Windows Programming/窗口创建

窗口创建与窗口分类编辑

使用Windows API函数CreateWindowEx,可以指定创建的窗口的类型:

  • Non Child Window:
    • Overlapped Window:顶层窗口,作为应用程序的主窗口。有标题条、边界与客户区,可以有菜单、最大最小化按钮、滚动条。
    • Pop-up Window:用于对话框、MessageBox,以及其他出现在应用程序主窗口之外的临时窗口。标题条可选。
  • Child Window:出现在父窗口的客户区中,超出的部分不可见。典型用于把父窗口的客户区分割成一些子区域。父窗口可以是Overlapped、Pop-up、其他Child窗口。子窗口的唯一必要特性是有客户区;不能有菜单;其他特性可选。定位子窗口时总是用父窗口客户区左上角坐标系。Destroyed、Hidden、Moved、Shown等窗口操作与父窗口一致。父窗口如果指定了WS_CLIPCHILDREN风格,则父窗口不能在子窗口上绘制。兄弟子窗口可以在彼此重叠的客户区上绘制,除非指定了WS_CLIPSIBLINGS风格。
  • Layered Window:
  • Message-Only Window:该窗口visible属性为false
  • Owner/Owned Window
    • Owner Window
    • Owned Window
GetParent函数,对于子窗口返回其父窗口;对于有WS_POPUP风格的非Child窗口,返回其owner;对于没有WS_POPUP风格的非Child窗口来说,GetParent恒定返回0。
GetWindow(hwnd, GW_OWNER)能够正常取得其owner
FindWindowEx可以指定父窗口、Z order上的前一个兄弟窗口,查找符合类名、窗口名的窗体。父窗口参数为NULL,则查找desktop的“子窗口”,即没有WS_CHILD风格的窗口。
GetTopWindow返回父窗口下的最顶层子窗口。
GetNextWindow返回Z order的前一个或下一个窗口。

Layered Window编辑

如果窗口使用语句

 ModifyStyleEx(0, WS_EX_LAYERED);

成为了Layered Window,就可以指定它的阿尔法值(半透明程度):

SetLayeredWindowAttributes(0, (255 * 50) / 100, LWA_ALPHA);

或者指定色键,系统将把具有该颜色的所有像素当作透明:

SetLayeredWindowAttributes(0x00bbggrr, 0, LWA_COLORKEY);

如果希望把所有鼠标事件传给桌面或者在当前窗口之下的其它线程的窗口,可以把当前窗口设置为:

 ModifyStyleEx(0, WS_EX_TRANSPARENT);

UpdateLayeredWindow函数:

  • 如果是WS_EX_APPWINDOW,此时在updatelayerwindow,并不会由系统拦截WM_PAINT消息,就像平时处理窗口一样,系统像平时使用invalidateRect()函数,可以局部重绘无效区域。
  • 如果是WS_EX_LAYERED,就必须手动在各处添加SendMessage(hwnd,wm_paint),这样才会进入WM_PAINT的处理

窗口的子类化编辑

窗口的subclass是指修改窗口过程的操作,而不是面向对象中的派生子类。

移动窗口编辑

正常情况下当使用者在窗口的标题栏按下鼠标左键时,系统发出WM_NCHITTESt来判断鼠标是否在HTCAPTION区域,然后向该窗口过程函数发送WM_NCLBUTTONDOWN消息。DefWindowProc函数指示窗口随同鼠标光标一起移动。松开鼠标按钮后,发出WM_NCLBUTTONUP消息。最后发出WM_MOVE消息。

在没有窗口的标题栏的情况下,移动窗口的几种办法:

  • SendMessage(hWnd,WM_NCLBUTTONDOWN,HTCAPTION,0);
  • SendMessage(hWnd,WM_SYSCOMMAND,SC_DRAGMOVE,0); // #define SC_DRAGMOVE 0xF012

操作系统有两种移动窗口的方式,一种是有虚线框(即影子窗口,ghost window),另一种没有虚线框,即实体窗口本身。操作系统全局范围内可通过如下函数来改变移动窗口的方式:

SystemParametersInfo(SPI_SETDRAGFULLWINDOWS,true,NULL,0);

下一章编辑