WS_BORDER以及WS_EX_CLIENTEDGE的研究

news/2024/11/23 23:33:56/

每次研究一点东西,都没有记录,下次需要的时候又浪费时间重新去研究。本人就是个没有总结习惯的人,这样等于没用积累,实在不行。

这2天研究了一下WS_BORDER和WX_EX_CLIENTEDGE的不同,以及在动态创建,和窗口绑定时候效果的不同。

下面开始:


1.先看MSDN有关WS_BORDER窗口风格,和WS_EX_CLIENTDEGE扩展窗口风格的定义。

WS_BORDER Creates a window that has a border.创建一个有边界的窗口。


WS_EX_CLIENTEDGE Specifies that a window has a 3D look — that is, a border with a sunken edge.指定窗口具有3D外观,也即是一个下沉的边缘。


2.在此之前先简单说下GetWindowRect和GetClientRect的区别

GetWindowRect获取窗口的整个区域,包括菜单,标题栏,边界。很明显加了WS_BORDER与WS_EX_CLIENTEDGE画出的边界不属于客户区。

GetClientRect获取的窗口的客户区,这里是在用于给用户作图用的。 

3.总结的现象


 http://

以上是创建CWnd时的统计的结果。很多时候我们需要通过ModifyStyleEx修改窗口风格,然后需要使用SetWindowPos来改变窗口风格。


4.以自绘CListBox来举例使用

直接附上我创建带有WS_BORDER和WS_EX_CLIENTEDGE风格CTListBox的例子


	DWORD dwStyle = WS_CHILD|WS_VISIBLE|WS_BORDER|WS_TABSTOP|WS_VSCROLL|LBS_NOTIFY|LBS_OWNERDRAWFIXED|LBS_HASSTRINGS|LBS_NOINTEGRALHEIGHT|LBS_EXTENDEDSEL;m_tlstbox.Create(dwStyle, CRect(10,10,110,110), this, ID_XLISTBOX);DWORD dwExStyle = WS_EX_LEFT|WS_EX_LTRREADING|WS_EX_RIGHTSCROLLBAR|WS_EX_NOPARENTNOTIFY|WS_EX_CLIENTEDGE;m_tlstbox.ModifyStyleEx(0, dwExStyle);

	CRect rcWnd;m_tlstbox.GetWindowRect(rcWnd);CRect rc;m_tlstbox.GetClientRect(rc);


我是应用ModifyStyleEx来给CTListBox增加扩展风格的。下面列出应用WS_BORDER和WS_EX_CLIENTEDGE的四种情况。


细心的朋友会发现,在此图第三个和第四个窗口的客户区和之前CWnd的窗口区域不一样。共通点,都是WS_EX_CLIENTEDGE没用。

我在

void CTListBox::DrawItem(LPDRAWITEMSTRUCT lpDIS)
{CRect rcWnd;GetWindowRect(rcWnd);CRect rcClient;GetClientRect(rcClient);
}
里面测试的结果也是如此。

原来我们通过ModifyStyleEx改变窗口扩展风格后,需要使用

m_tlstbox.SetWindowPos(&wndTop, 10,10,0,0, SWP_DRAWFRAME | SWP_NOSIZE);
来确保刚才添加的扩展风格被应用了。


虽然MSDN说ModifyStyleEx会调用SetWindowPos这个API来设定窗口位置,但是没用。

我们必须用如上的语句手动设置。

5.至于为什么不能使用ModifyStyle或者ModifyStyleEx正确的修改窗口风格?

MSDN的描述如下:

Certain window data is cached, so changes you make using SetWindowLong will not take effect until you call the SetWindowPos function. Specifically, if you change any of the frame styles, you must call SetWindowPos with the SWP_FRAMECHANGED flag for the cache to be updated properly.


6.但是经过研究发现使用ModifyStyleEx并带上SWP_FRAMECHANGED也能改变Frame Style,为什么呢?

	m_xlstbox.ModifyStyleEx(0, dwExStyle, SWP_NOSIZE|SWP_NOMOVE|SWP_FRAMECHANGED);
也可以正确的改变窗口的frame style,为什么呢?因为ModifyStyleEx和SetWindowPos都是调用::SetWindowPos这个API。虽然是MSND没有为ModifyStyleEx指定了该风格,但是SetWindowPos具有的nFlags我们都可以使用。

7.继续深究,为什么带有SWP_FRAMECHANGED能改变窗口的Frame Style呢?我找到原因了。

因为带有SWP_FRAMECHANGED标识,会向该窗口发送WM_NCCALCSIZE消息,我们可以手动拦截该消息,使WS_EX_CLIENTEDGE永远不被调用,但是最好不要这样。

至于WM_NCCALCSIZE如何实现的,那可是微软的秘密了。虽然不能看到他们的代码,但是我猜也是在这个消息的处理函数根据窗口的风格(例如,标题,菜单,滚动条,状态栏等等)来划分客户区的吧。

有关窗口的其他框架风格如WS_THICKFRAME,   WS_SIZEBOX。下次再总结。。吃饭去了。。。。



http://www.ppmy.cn/news/883748.html

相关文章

【solidity】函数修饰器(Function Modifiers)

修饰符可用于以声明方式更改函数的行为。例如&#xff0c;您可以使用修饰符在执行函数之前自动检查条件。 检查调用者权限 // SPDX-License-Identifier: GPL-3.0 pragma solidity >0.7.0 <0.9.0;contract Owned {address public owner;uint256 public account;construc…

ModifyStyle()调用不起作用

现象&#xff1a;在使用WTL做CListBox子类化时&#xff0c;使用 ModifyStyle(0, LBS_OWNERDRAWFIXED)不起作用; 原因&#xff1a;并不是所有的风格都可以动态利用ModifyStyle/ModifyStyleEx()函数增加和去除&#xff0c;有些风格比如 LBS_HASSTRINGS | LBS_OWNERDRAWFIXED| LB…

$(...).modal is not a function的解决办法

最近在练习ssm框架的时候遇到了一个小问题&#xff0c;无法识别bootstrap.min.js的modal方法&#xff0c;控制台报错$(...).modal is not a function。 于是测试测试了一下 发现可以正常弹框&#xff0c;然后又检查了id是不是写错了&#xff0c;也没写错。突然没了头绪。为什么…

user-modify

最近入职开始工作了&#xff0c;碰到一个很有意思的问题&#xff0c;后端传回来的文章内容<a>标签内的内容可以编辑。 很不理解&#xff0c;我从后端取到的数据这该怎么改呢。 问了同事&#xff08;导师&#xff09;&#xff0c;让我试试contenteditable属性&#xff0c;…

missing modality

THE MODALITY FOCUSING HYPOTHESIS: TOWARDS modal-general的知识是对于cross modality KD决定性的。 想要解决的问题是&#xff1a;crossmodal KD是否总是有效的&#xff1f; 文章通过实验证明即使多模态teacher能够取得更好的结果&#xff0c;但cross蒸馏过后的student mod…

This old-style function definition is not preceded by a prototype

文章目录 Introwarning 及解决 截屏知其然&#xff0c;却不知其所以然 Intro 在 Xcode 14 中随意写了几个C命令行程序&#xff0c;编译运行OK。 但是有以下两种报错&#xff1a; This old-style function definition is not preceded by a prototype This function declarati…

关于ModifyStyleEx无效的问题

在做MFC时&#xff0c;有时候我们需要显示选择一个项目&#xff0c;比如需要标记所选择的图片控件。我们可以用这个函数&#xff1a; BOOLModifyStyleEx ( DWORD dwRemove, DWORD dwAdd, UINT nFlags ) 或者 BOOLModifyStyle ( DWORD dwRemove, DWORD dwAdd, UINT nF…

ModifyStyle

CWnd::ModifyStyle 1.作用 : 调用这个函数修改窗口的风格 2.函数原型: BOOL ModifyStyle ( DWORD dwRemove, DWORD dwAdd, UINT nFlags0 ); 3.参数含义: dwRemove 指定修改时要删除的窗风格。 dwAdd 指定修改时将要增加的窗口风格。 nFlags 该参数将被传给SetWindowPos&#x…