[WTL/ATL]_[初级]_[关于WS_CLIPCHILDREN和WS_CLIPSIBLINGS样式的说明]

本文深入探讨了Win32窗口开发中WS_CLIPSIBLINGS与WS_CLIPCHILDREN样式的应用,解释了它们如何影响窗口及其子控件的刷新机制,提供了代码示例帮助理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

场景

1.在Win32窗口开发或基于Win32WTL库开发时,我们经常创建新窗口或新控件都会使用WS_CLIPSIBLINGS | WS_CLIPCHILDREN两个属性, 那么这两个属性有什么用呢?好像不加也没问题.

2.有时候我们刷新或拉伸父窗口时,它的子控件移动后会显示透明,看起来像是没绘制一样.什么原因?

说明

WS_CLIPCHILDREN: 这个样式如果设置了,当前窗口刷新指定区域时,该区域的子窗口都不会刷新。没设置这个属性,那么子窗口就会刷新.
WS_CLIPSIBLINGS: 如果有WS_CLIPSIBLINGS属性,只有接收WM_PAINT消息的子窗口全部刷新,而其他子窗口和它重叠的区域不刷新,只刷新非重叠区域. 去掉 WS_CLIPSIBLINGS 时,子窗口的重叠区域也会刷新。

也就是说,WS_CLIPSIBLINGS能优化刷新重复区域,只刷新一次,每次创建都可以加上. 而WS_CLIPCHILDREN根据情况加,如果想自己控制子窗口刷新不受父窗口影响,那么可以在父窗口创建时加上WS_CLIPCHILDREN;如果不想自己控制子窗口的刷新,需要父窗口刷新时,子窗口也刷新,那么可以去掉WS_CLIPCHILDREN样式.

代码

MyButton.h


#ifndef MY_BUTTON
#define MY_BUTTON

class MyButton : public CWindowImpl<MyButton,CButton>
{
public:
	DECLARE_WND_CLASS(NULL)

	BEGIN_MSG_MAP_EX(MyButton)
		MESSAGE_HANDLER(WM_PAINT, OnPaint)
		DEFAULT_REFLECTION_HANDLER()
	END_MSG_MAP()

	LRESULT OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
};

#endif

MyButton.cpp

#include "stdafx.h"
#include "MyButton.h"
#include <string>

LRESULT MyButton::OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
	auto _id = GetWindowLong(GWL_ID);
	auto str_id = std::to_wstring((long long)_id);
	str_id.append(L":MyButton::OnPaint\n");
	OutputDebugString(str_id.c_str());

	
	

	bHandled = FALSE;
	return 0;
}

View.h

// View.h : interface of the CView class
//
/////////////////////////////////////////////////////////////////////////////

#pragma once

#include "atlmisc.h"
#include "MyButton.h"

enum
{
	kButtonId1 = WM_USER +1,
	kButtonId2
};

class CView : public CWindowImpl<CView>
{
public:
	DECLARE_WND_CLASS(NULL)

	BOOL PreTranslateMessage(MSG* pMsg);

	BEGIN_MSG_MAP_EX(CView)
		MSG_WM_CREATE(OnCreate)
		MESSAGE_HANDLER(WM_PAINT, OnPaint)
		MSG_WM_TIMER(OnTimer)
		REFLECT_NOTIFICATIONS()
	END_MSG_MAP()

// Handler prototypes (uncomment arguments if needed):
//	LRESULT MessageHandler(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
//	LRESULT CommandHandler(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
//	LRESULT NotifyHandler(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/)

	LRESULT OnPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
	int OnCreate(LPCREATESTRUCT lpCreateStruct);
	void OnTimer(UINT_PTR nIDEvent);
private:
	MyButton button1_;
	CRect rect1_;

	MyButton button2_;
	CRect rect2_;

};

View.cpp

// View.cpp : implementation of the CView class
//
/////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "resource.h"

#include "View.h"


BOOL CView::PreTranslateMessage(MSG* pMsg)
{
	pMsg;
	return FALSE;
}

LRESULT CView::OnPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
	CPaintDC dc(m_hWnd);

	//TODO: Add your drawing code here

	return 0;
}

void CView::OnTimer(UINT_PTR nIDEvent)
{
	OutputDebugString(L"CView::OnTimer\n");
	InvalidateRect(rect1_);
}

int CView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	button1_.Create(m_hWnd,0,L"Tobey",WS_VISIBLE|WS_CHILD,0,kButtonId1);
	CSize size;
	button1_.GetIdealSize(&size);
	rect1_.left = 100;
	rect1_.top = 200;
	rect1_.right = rect1_.left+size.cx;
	rect1_.bottom = rect1_.top+size.cy;

	button1_.SetWindowPos(NULL,rect1_,
		(SWP_NOZORDER | SWP_NOREPOSITION | SWP_NOACTIVATE));


	button2_.Create(m_hWnd,0,L"At Work",WS_VISIBLE|WS_CHILD,0,kButtonId2);
	button2_.GetIdealSize(&size);
	
	rect2_.left = 100;
	rect2_.top = 220;
	rect2_.right = rect2_.left+size.cx;
	rect2_.bottom = rect2_.top+size.cy;
	button2_.SetWindowPos(NULL,rect2_,
		(SWP_NOZORDER | SWP_NOREPOSITION | SWP_NOACTIVATE));

	SetTimer(1,2000);

	return 0;
}

图示1:
在这里插入图片描述

项目下载地址:

参考

window-styles

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白行微

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值