一,篇文章的主旨
这篇文章是对我一个工作經驗的总结.我要在窗口的客户区显示图片及若干个按钮,它们的布局是固定的.不管用户将窗口调节成无标题栏无边框还是有标题栏目有边框,都不能打乱图片与按钮的固定布局.我下面要讨论的问题就是如何根据窗口风格的变化来重新布局图片及按钮的位置.
二, 窗口風格的討論
首先我创建窗口的代碼如下:
_hWnd = CreateWindowEx(
WS_EX_TOPMOST|WS_EX_LAYERED,
c_szClassName,
c_sz,
WS_DLGFRAME,
win_pos_x, win_pos_y, win_width, win_height,
NULL,
NULL, _hInst, NULL);
执行的效果应该如下图所示(当然,應没有下圖中的X號)
在上圖中我标出了窗口的主要构成部分。
上图中的window标出了整个窗口的尺寸。window的尺寸可以这样获得:
RECT rect1;
GetWindowRect(_hWnd,&rect1);
首先討論window的高是如何构成。先看如下代碼:
int sys_min_height = GetSystemMetrics(SM_CYMIN);
int sys_caption_height = GetSystemMetrics(SM_CYSMCAPTION);
获得客户区尺寸,即圖中window_client所示的尺寸:
RECT rect;
GetClientRect(_hWnd,&rect2);
那麽window的高 = window_client的高 + sys_min_height;
而sys_min_height又是什么呢?
我们看上圖中window_caption的高应该是sys_caption_height, 上圖中的window_caption最外面 也應該有border的。
sys_min_height = sys_caption_height + 2 * window_border的宽度。
而圖中的window_border的宽度如何直接获得呢?
参考如下链接
http://blog.csdn.net/oldmtn/article/details/7257788
所说的那样:
WS_DLGFRAME Creates a window with a double border but no title.
看如下代码:
int sys_border1_width = GetSystemMetrics(SM_CYDLGFRAME);
int sys_border2_width = GetSystemMetrics(SM_CYBORDER);
那麽,window_border的宽度就等于2 * (sys_border1_width + sys_border2_width).
当然 ,我们也可以通过另外一种方式计算出圖 中的window_border的宽度:(window的宽度-window_client的宽度)/2。
在这种風格下,我要保証客户区的大小为200x200不变,就中考虑如何在CreateWindowEx中设置好窗口大小。下面来讲座而已问题。
三,有标题和边框时的布局
图片与按键的布局的放置在客户区的,就是圖中的window_client中。它们的坐标都是相对与window_client左上点的坐标来设定的。
window的宽應设置为:200+(sys_min_height - sys_caption_height)
window的高设置为 : 200+ sys_min_height
四,无标题和边框的布局
这个时候,可以理解为window与window_client重合。图片等的坐标都应该是相对与window左上角的坐标。
创建窗口window的时候,其尺寸应该如下设置:
window的宽應设置为:200
window的高设置为 : 200
五, 标题与边框的隐去
DWORD styles = GetWindowLong(_hWnd,GWL_STYLE);
if(!show_caption_border)
{
styles &= ~WS_BORDER;
styles &= ~WS_CAPTION;
}
if(SetWindowLong(_hWnd,GWL_STYLE,styles) == 0)// return 0 if failed.
{
//error handle
}
SetWindowPos(_hWnd,NULL,x,_y,0,0,SWP_NOSIZE);
最后一句很重要,不调用 的话会有问题。