您的位置:首页 > 其它

计算窗口边框厚度、标题栏高度最正确的方法

2015-09-24 18:52 531 查看
关于如何计算标题栏高度和边框厚度,流传的最多的方法是GetSystemMetrics,或者干脆用GetWindowRect减去GetClientRect得到。以上方法弊端就不多讨论了,一个通用性差,要根据不同窗口样式写很多代码,另一个效率差;

以下给出最正确的方法,一如既往,贴代码:

class CCalcAroundSize : public CWnd
{
public:
enum BorderFlags{
GBT_LEFTBORDER = offsetof( RECT, left ),
GBT_TOPBORDER = offsetof( RECT, top ),
GBT_RIGHTBORDER = offsetof( RECT, right ),
GBT_BOTTOMBORDER = offsetof( RECT, bottom )
};
INT GetBorderThickness( BorderFlags bf, __in_opt BOOL bRecalc = FALSE )
{
if( bRecalc ){
::SetWindowPos( GetSafeHwnd(),
NULL,
0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_FRAMECHANGED );
}
return *(INT*)(LPBYTE)((LPRECT)m_rcAroundSize) + bf;
}

protected:
virtual LRESULT WindowProc( UINT message, WPARAM wParam, LPARAM lParam )
{
LRESULT lResult = __super::WindowProc( message, wParam, lParam );
if( message == WM_NCCALCSIZE && wParam )
{
LPNCCALCSIZE_PARAMS lpncsp = reinterpret_cast<NCCALCSIZE_PARAMS*>(lParam);
ASSERT( AfxIsValidAddress( lpncsp, sizeof( NCCALCSIZE_PARAMS ) ) );

// 左边框厚度
m_rcAroundSize.left = lpncsp->rgrc[0].left -
lpncsp->lppos->x;

// 标题栏高度。
m_rcAroundSize.top = lpncsp->rgrc[0].top -
lpncsp->lppos->y;

// 右边框厚度
m_rcAroundSize.right = (lpncsp->lppos->x + lpncsp->lppos->cx) -
lpncsp->rgrc[0].right;

// 底边框厚度
m_rcAroundSize.bottom = (lpncsp->lppos->y + lpncsp->lppos->cy) -
lpncsp->rgrc[0].bottom;

}
}
private:
CRect m_rcAroundSize;
};


另外关于WM_NCCALCSIZE消息,请在__super::WindowProc处理完后再处理。否则DefWindowProc(或者用户;如果CCalcAroundSize的父类不是CWnd而是CUserDef的话,用户很可能)在该消息中修改该消息参数,这种情况下,会得到错误结果。

注意:

标题栏高度在这里指 —— [标题栏(可鼠标点击拖动那部分)]+ [边框] + [菜单] + [工具栏]的总高度;(方括号表示可选);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: