Window Style





1、WS_POPUP
A pop-up window is an overlapped window with optional title bar and border. 
popup window可以有父窗口。
显示在main window之外。可显示在屏幕任何位置。


2、WS_OVERLAPPED
An overlapped window is a top-level window that has a caption (title bar), border and client area. 
overlapped window没有父窗口。通常作为程序的main window。
WS_OVERLAPPED窗口总是有title bar和border,即使你显示删除WS_CAPTION和WS_BORDER风格,而WS_POPUP却没有该特点。


3、WS_CHILD、WS_CHILDWINDOW
child window是设置了ws_child属性的窗口。
它有父窗口。
只能显示在父窗口的客户区内部。
父窗口移动,子窗口会随之移动。(在客户区的相对位置不变。)
父窗口销毁,子窗口随之销毁。


子窗口创建时,使用CreateWindow的x和y参数是相对于其父窗口的客户区起点。movewindow()\setwindowpos也一样。

通常,控件(button\list\ect)都是child window。
所有不带ws_child风格的窗口都是top-level window。
owned window有parent(实际是owner),但没有ws_child。


2、WS_EX_LAYERED
layered window不能为子窗口(win8 开始可以为子窗口。)。必须为WS_POPUP或WS_OVERLAPPED。 
必须调用SetLayeredWindowAttributes或UpdateLayeredWindow之后才能显示出来。


使用createwindowex创建ws_ex_layered窗口,(也可以创建时不指定ws_ex_layered,创建后使用SetWindowLong修改属性。)
然后setlayeredwindowattributes修改层窗口的透明属性。
setlayeredwindowattributes之后,layered window可以有子窗口,并且子窗口拥有和父窗口相同的layered属性。窗口子控件的绘制使用默认方式,也就是不需要人为控制。


colorkey和alpha方式同时只能有一个。colorkey是把指定的颜色都当作透明;alpha是做blend。


使用colorkey方式时,窗口的透明区域不接收鼠标消息,鼠标消息会被发送到透明窗口下面的窗口上。
使用alpha方式时,窗口alpha值为0的区域(透明区域)也不接收鼠标消息,鼠标消息会被pass throuh到它下面的窗口。
layered window拥有WS_EX_TRANSPARENT属性时,透明窗口(包括不透明区域)完全不接收鼠标消息,鼠标消息被传递给它下面的窗口。

updatelayeredwindow()用来做透明窗口的window painting,类似bitblt。是手工绘制透明窗口的api。自动绘制只用setlayeredwindowattributes即可。





4、WS_EX_APPWINDOW
强迫一个top-level窗口在可见时,出现在TaskBar上。
但这并不意味着一个窗口出现在TaskBar上就一定需要该风格,其实,如果是主线程的第一个窗口(m_pMainWnd),即使没有该风格,也会出现在TaskBar上。







5、Z-order
系统使用一个list描述窗口的Z-order。
新创建的窗口,系统把它放在同类型窗口z-order的最上面。可以使用BringWindowToTop()把窗口提到同类型窗口z-order的最上面。
激活的窗口,系统把它放在同类型窗口z-order的最上面。一个窗口被置z-order顶端,其子窗口也被置顶。








一、TOP_LEVEL window
没有ws_child风格的窗口。
没有父窗口,可有owner窗口。即可以被owned,但不可以被child。
可以显示在桌面的任何位置,不像子窗口那样受父窗口限制。
要么是overlapped window,要么是popup window。


CreateWindow(Ex)的hWndParent,可以成为新窗口的父窗口,也可以成为新窗口的owner窗口。如果没有ws_child(即指定了ws_popup或ws_overlapped),hWndParent会成为新窗口的owner。

对其top_level窗口的创建、移动等涉及的坐标都是屏幕坐标。比如createwindow、movewindow、setwindowpos的x,y参数是screen coordinates。
(GetWindowRect()不论对top-level window还是ws_child window,获取的都是屏幕坐标。)


子窗口位置相关的api使用的坐标是相对于其父窗口的。top-level窗口位置相关的api使用的坐标是相对于屏幕的。




二、owned window
An owned window is a top-level window that has an owner.

作为top-level窗口,可以显示在屏幕的任何区域。
总是显示在它的owner window的前面(z-order的上面)。但不随owner的移动而移动。
随owner的隐藏或最小化而隐藏。
随owner的销毁而销毁。
随owner的disabled而disabled的。
通常,是popup or overlapped window.


不能给其设置ws_child,否则导致其为child而不再是owned top-level window。
可使用createwindow(ex)指定其hWndParent, 可以给top-level window设置owner。也可以使用SetWindowLongPtr(m_hWnd, GWL_HWNDPARENT, (LONG_PTR)hWndParent);
如果hWndParent为child window,则系统把所属权分配给child window的top-level parent window。


When a topmost window is made non-topmost, its owners and its owned windows are also made non-topmost windows.
A non-topmost window can own a topmost window, but the reverse cannot occur. 
Any window (for example, a dialog box) owned by a topmost window is itself made a topmost window, to ensure that all owned windows stay above their owner.




三、在顶层窗口之间的关系
顶层窗口拥有或归属其他顶层窗口。
属于其他窗口的窗口称为归属窗口;拥有其他窗口的窗口称为宿主窗口。
在z-order中,归属窗口一定在它的宿主窗口前面。
使用createwindow(ex)或setwindowlong,设置top-level窗口的父窗口,这个“父窗口”实际为owner窗口。







问题:
一个进程控制另一个进程的窗口,可使用top-level window的owner关系。但owned window总是不能被设置在owner的子窗口下?????








下面几个方法的差异:
 
GetParent方法:如果是子窗口(具有WS_CHILD风格),那么总能得到一个有效的临时窗口对象(Immediate Window);如果是top-level窗口,又分为两种情况:如果该窗口为非拥有(unowned),那么返回NULL,否则,返回拥有者窗口对象。因此,GetParent并非总是返回父窗口。
 
GetOwner方法:获得拥有者窗口,默认为父窗口。父子窗口中的子窗口只能出现在父窗口的客户区域,而具有拥有者窗口的窗口可以出现在桌面的任何位置。这里的Owner窗口,不同于API方法GetWindow获得的Owner窗口,它是MFC特定的概念。
 
GetAncestor方法:获得祖先窗口。有三个选择,GA_PARENT, GA_ROOT, GA_ROOTOWNER。















  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用以下代码将这段代码设置为 RichTextBox 的内容: ``` string code = "#include <windows.h>\n\nLRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);\n\nint WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)\n{\n // Register the window class\n const char CLASS_NAME[] = \"My Window Class\";\n\n WNDCLASS wc = { };\n\n wc.lpfnWndProc = WndProc;\n wc.hInstance = hInstance;\n wc.lpszClassName = CLASS_NAME;\n\n RegisterClass(&wc);\n\n // Create the window\n HWND hwnd = CreateWindowEx(\n 0, // Optional window styles\n CLASS_NAME, // Window class\n \"Form\", // Window text\n WS_OVERLAPPEDWINDOW, // Window style\n\n // Size and position\n CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,\n\n NULL, // Parent window\n NULL, // Menu\n hInstance, // Instance handle\n NULL // Additional application data\n );\n\n if (hwnd == NULL)\n {\n return 0;\n }\n\n // Show the window\n ShowWindow(hwnd, nCmdShow);\n\n // Run the message loop\n MSG msg = { };\n while (GetMessage(&msg, NULL, 0, 0))\n {\n TranslateMessage(&msg);\n DispatchMessage(&msg);\n }\n\n return 0;\n}\n\nLRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)\n{\n switch (msg)\n {\n case WM_DESTROY:\n PostQuitMessage(0);\n break;\n\n default:\n return DefWindowProc(hwnd, msg, wParam, lParam);\n }\n\n return 0;\n}"; richTextBox1.Text = code; ``` 在这个代码字符串中,`\n` 表示换行符。你可以根据需要修改代码的内容。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值