Win8仿Win10无边框效果的实现

时间:2023-01-09 20:59:55

只是左右没有边框而已,阴影效果是没有的。如图所示。我想,在Win10如果这样做,估计会把客户区切掉一截。

Win8仿Win10无边框效果的实现

当Windows客户区的大小和位置需要重新计算时会发出WM_NCCALCSIZE消息,因此拦截该消息可以控制Windows窗体客户区的尺寸和位置。

当消息参数wParam为TRUE时,lParam参数为NCCALCSIZE_PARAMS类型的指针,该类型包含了可用于计算客户区大小和位置的信息。

NCCALCSIZE_PARAMS 结构体

typedef struct tagNCCALCSIZE_PARAMS {

RECT rgrc[3];

PWINDOWPOS lppos;

} NCCALCSIZE_PARAMS, *LPNCCALCSIZE_PARAMS;

  • 第一个RECT存储了窗体被移动或尺寸被修改后的窗体的坐标信息,这是窗口马上要应用的信息;
  • 第二个RECT存储移动前或尺寸被改变前窗体的坐标信息;
  • 第三个RECT存储了移动前或尺寸修改前客户区的坐标信息。

如果窗体是子窗体,那么坐标信息都使相对父窗体的,否则坐标是相对于屏幕的。当消息处理完毕后,第一个RECT被用来存储移动后或大小改变后的客户区的坐标信息,即计算后的结果。窗体边框厚度和标题高度是可以获取的。略。

Win8仿Win10无边框效果的实现

如果一个窗体没有标题栏,那么它的边框效果是这样的

修改客户区域

已经说明,客户区域的坐标信息是根据窗体的新坐标信息、窗体边框厚度和标题栏的高度进行计算得来的。因此我们可以拦截WM_NCCALCSIZE消息,人为的修改窗体的坐标信息,从而影响客户区坐标信息的计算结果。

void CXXXDlg::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
lpncsp->rgrc[0].left -= 7;
lpncsp->rgrc[0].right += 8;
lpncsp->rgrc[0].bottom += 7;
CDialog::OnNcCalcSize(bCalcValidRects, lpncsp);
}

给出的代码中没有设置top,因为窗体顶部的边框在标题栏上方,这里简单的修改top是达不到预期效果的,需要重绘标题栏才行。略。

引用:修改窗体客户区区域