Windows Box Model解析

2007年7月17日 | Author: zhangdi | 标签: , ,

很久以前看到过一篇解释HTML中DOM的Box Model的文章(好像是在MSDN,有图示,很清楚)。最近在写Windows程序,遇到了一个要resize一个window,并且要相应移动它里面的controls的需求。趁这个机会研究了一下Windows的Box Model,发现竟然和DOM的Box Model是如此的相似。

win-box.jpg

首先介绍一下与其相关的一些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中有一些值得我们注意的地方,也是有一点不爽的地方:

  1. GetClientRect API返回的并不是以屏幕左上角为原点的坐标,而是以当前window的Client区域的左上角为原点的。所以返回的RECT机构中,right就是window的宽,bottom就是window的高。这个是这几个API中惟一一个不是以屏幕左上角为原点的API,需要多加注意。
  2. GetWindowInfo中返回的WINDOWINFO结构体中的rectClient与GetClientRect返回的RECT不是一回事。WINDOWINFO中的rectClient是以屏幕左上角为原点的Client Rectangle坐标。
  3. SetWindowPos中的x, y参数是表示当前窗口的Window Rectangle的新的左上角的坐标。但是这个坐标是Offset坐标,也就是说,这个坐标不是以屏幕左上角为原点的,而是以父窗口的Client Rectangle的左上角为原点的。
  4. 似乎没有API可以直接返回一个window的Offset坐标。
目前还没有任何评论.