快生活 - 生活常识大全

第章节让我们来深入了解一下


  WM_NCCALCSIZE的妙用
  当窗口的大小发生变化的时候,Windows会使用WM_NCCALCSIZE这个消息来判断窗口客户区在整个窗口中的所处的位置。关于这个WM_NCCALCSIZE消息有两种形式。其中比较简单的一种是接收一个窗口矩形,然后它会返回一个客户区矩形。如果你希望窗口在大小发生变化时保持一个预期的客户区矩形(同时考虑菜单栏扩展为多行的情况),则这种方式会比较有用。
  关于函数AdjustWindowRectEx
  函数AdjustWindowRectEx可以依据所需客户矩形大小,计算包含这个客户区的窗口的最小矩形的。计算出的矩形随后可以传送给CreateWindowEx函数,用于创建一个客户区所需大小的窗口。但是这个函数不会考虑菜单栏扩展为多行的情况,因为它不知道你将会使用哪个菜单(在AdjustWindowRectEx函数中,没有一个HMENU或者HWND参数来指定菜单或者窗口)。
  代码来了
  代码解析
  这个函数接收的参数有:一个窗口的句柄,另外一个是期望的窗口客户区的矩形尺寸。首先会使用GetMenu尝试获取窗口的菜单,然后使用AdjustWindowRectEx来计算一个包含客户区的最小窗口尺寸,就如之前所提到的,这个API不会考虑菜单被扩展为多行显示的情况。接下来,我们判断窗口的菜单句柄是否为空,如果不为空,说明这个窗口包含一个菜单栏。
  接下来,我们使用一种特殊的手法来判断菜单栏是否扩展为多行显示。具体为:我们通过向窗口发送WM_NCCALCSIZE消息,传入了一个矩形,这个矩形的高度设置为一个很大的值0x7FFF,其宽度设置为之前AdjustWindowRect调用的返回值。
  在代码中,我们向窗口发送了WM_NCCALCSIZE消息,并且WPARAM设置成了FALSE,表明我们不需要指定准确的客户区矩形坐标信息,还表明:在消息处理之前,第四个参数会包含一个建议的窗口尺寸(注意,这里的仅设置了高度为一个很大的值0x7FFF),同时消息处理例程返回后,这个参数会包含窗口客户区的屏幕坐标。
  另外,我们会看到让人摸不着头脑的一行:当WM_NCCALCSIZE处理返回之后,我们更新了窗口矩形的bottom值。
  最后,我们使用了SetWindowPos来更新窗口的位置,注意这里使用到了标志:SWP_NOMOVE | SWP_NOZORDER。
  练习题
  1) 为什么要使用0x7FFF这个值来作为窗口矩形的高度。
  2) 为什么需要"rcWindow.bottom += rcTemp.top"?
网站目录投稿:静彤