什么是窗口?

  窗口很重要,windows操作系统与用户的交互其实主要靠这个窗口。通常的我们认为,就是我们打开windows应用程序时,弹出来的窗口,如下:

  这种类型的窗口称为 应用程序窗口 或 主窗口。它通常具有带有标题栏,“最小化最大化”按钮以及其他标准UI元素的框架。该框架称为窗口的非客户区,之所以这样称呼,是因为操作系统管理窗口的该部分。框架内的区域是客户区域。这是程序管理的窗口的一部分。

但你可能想不到,控制窗口的屏幕截图 这也是一种窗口,没错。UI控件和应用程序窗口之间的主要区别在于,控件本身并不存在。而是,控件相对于应用程序窗口放置。当您拖动应用程序窗口时,控件将随其移动。同样,控件和应用程序窗口可以相互通信。

  当您考虑窗口时,不要简单地考虑应用程序窗口。取而代之的是,将窗口视为一种编程构造,它可以:

  • 占据屏幕的特定部分。
  • 在给定的时刻可能可见或不可见。
  • 知道如何绘制自己。
  • 响应来自用户或操作系统的事件。

Parent窗口和Owner窗口

  对于UI控件,控件窗口被称为应用程序窗口的子级。应用程序窗口是控制窗口的父级。父窗口提供用于定位子窗口的坐标系。拥有父窗口会影响窗口外观的各个方面;例如,子窗口将被剪切,以使子窗口的任何部分都不会出现在其父窗口的边界之外。

  另一个关系是应用程序窗口和模式对话框窗口之间的关系。当应用程序显示模式对话框时,应用程序窗口是owner窗口,而该对话框是owned窗口。拥有的窗口始终显示在其owner窗口的前面。当所有者最小化时,它是隐藏的,并且与所有者同时被销毁。

  简而言之就是:窗口和UI空间之间的关系就像 Parent/Child;窗口和模式对话框之间的关系就是Owner/Owned。

  如下:

带有对话框的应用程序的屏幕截图

  他们之间的关系:

该图显示了父母/孩子和所有者/拥有的关系

Window Handles

  Windows是对象(它们同时具有代码和数据),但是它们不是C ++类。相反,程序使用称为handle的值来引用窗口。手柄是不透明的类型。本质上,它只是操作系统用来标识对象的数字。可以将Windows描绘成具有已创建的所有窗口的大表。它使用此表通过其句柄查找窗口。(是否确实是内部工作方式并不重要。)窗口句柄的数据类型为HWND,通常称为“ aitch-wind”。窗口句柄由创建窗口的函数(CreateWindowCreateWindowEx)返回

  要在窗口上执行操作,通常会调用一些将HWND值作为参数的函数。例如,要在屏幕上重新放置窗口,请调用MoveWindow函数:

BOOL MoveWindow(HWND hWnd, int X, int Y, int nWidth, int nHeight, BOOL bRepaint);

  第一个参数是您要移动的窗口的句柄。其他参数指定窗口的新位置以及是否应重绘窗口。

  请记住,句柄不是指针。如果hwnd是包含句柄的变量,则尝试通过写入来取消引用该句柄*hwnd是错误的。

屏幕和窗口坐标

  坐标以与设备无关的像素为单位进行测量。

  根据任务的不同,可能会测量相对于屏幕,相对于窗口(包括框架)或相对于窗口的工作区的坐标。例如,您将使用屏幕坐标将窗口放置在屏幕上,而您将使用客户端坐标在窗口内绘制。在每种情况下,原点(0,0)始终是该区域的左上角。

显示屏幕,窗口和客户坐标的插图

Win32常见宏定义

typedef wchar_t WCHAR;
Typedef Definition
CHAR char
PSTR or LPSTR char*
PCSTR or LPCSTR const char*
PWSTR or LPWSTR wchar_t*
PCWSTR or LPCWSTR const wchar_t*

   SetWindowTextA采用ANSI字符串。SetWindowTextW采用Unicode字符串。

在内部,ANSI版本将字符串转换为Unicode。Windows标头还定义了一个宏,当UNICODE定义了预处理器符号时,该宏可以解析为Unicode版本,否则为ANSI版本。

#ifdef UNICODE
#define SetWindowText SetWindowTextW
#else
#define SetWindowText SetWindowTextA
#endif