Windows Box Model解析
很久以前看到过一篇解释HTML中DOM的Box Model的文章(好像是在MSDN,有图示,很清楚)。最近在写Windows程序,遇到了一个要resize一个window,并且要相应移动它里面的controls的需求。趁这个机会研究了一下Windows的Box Model,发现竟然和DOM的Box Model是如此的相似。
首先介绍一下与其相关的一些API:
BOOL GetWindowInfo(
HWND hwnd,
PWINDOWINFO pwi
); // pwi为传出参数,是一个指向WINDOWINFO结构体的指针
BOOL GetWindowRect(
HWND hwnd,
LPRECT lpRect
); // lpRect为传出参数,是一个指向RECT结构体的指针
BOOL GetClientRect(
HWND hwnd,
LPRECT lpRect
);// lpRect为传出参数,是一个指向RECT结构体的指针
BOOL SetWindowPos(
HWND hWnd,
HWND hWndInsertAfter,
int X,
int Y,
int cx,
int cy,
UINT uFlags
); // 此函数功能强大,可以Move和Resize一个Window
typedef struct {
DWORD cbSize;
RECT rcWindow;
RECT rcClient;
DWORD dwStyle;
DWORD dwExStyle;
DWORD dwWindowStatus;
UINT cxWindowBorders;
UINT cyWindowBorders;
ATOM atomWindowType;
WORD wCreatorVersion;
} WINDOWINFO, *PWINDOWINFO, *LPWINDOWINFO;
typedef struct _RECT {
LONG left;
LONG top;
LONG right;
LONG bottom;
} RECT, *PRECT;
这里需要解释一下什么叫做Window Rectangle和Client Rectangle,Window Rectangle顾名思义,就是指当前的Window的所占矩形区域(以屏幕左上角为(0, 0)点)。Client Rectangle就比较麻烦了,它指的是这个Window的真正用户区域,也就是除去border,scrollbars,titlebar等等之后的矩形区域。所以一般来说,Client Rectangle要比Window Rectangle小。
还有一个概念就是Offset坐标,这个指的是当前Window的Window Rectangle和他的父窗口的Client Rectangle的偏移(也就是说以父窗口的Client Rectangle的左上角为原点)。
API中有一些值得我们注意的地方,也是有一点不爽的地方:
- GetClientRect API返回的并不是以屏幕左上角为原点的坐标,而是以当前window的Client区域的左上角为原点的。所以返回的RECT机构中,right就是window的宽,bottom就是window的高。这个是这几个API中惟一一个不是以屏幕左上角为原点的API,需要多加注意。
- GetWindowInfo中返回的WINDOWINFO结构体中的rectClient与GetClientRect返回的RECT不是一回事。WINDOWINFO中的rectClient是以屏幕左上角为原点的Client Rectangle坐标。
- SetWindowPos中的x, y参数是表示当前窗口的Window Rectangle的新的左上角的坐标。但是这个坐标是Offset坐标,也就是说,这个坐标不是以屏幕左上角为原点的,而是以父窗口的Client Rectangle的左上角为原点的。
- 似乎没有API可以直接返回一个window的Offset坐标。
发表评论
| Trackback








