`

非客户区的CAPTION

 
阅读更多

非客户区的CAPTION:才能移动窗体 

如果客户区要模拟非客户区 需要欺骗窗体,告诉窗体当前的点击是在非客户区,只有非客户才能做窗体调整,和移动窗体

 

       SendMessage(WM_NCLBUTTONDBCLICK, HTCAPTION,0  ) 双击

        SendMessage(WM_NCLBUTTONDOWN, HTCAPTION,0  ) 移动

 

 

 

CWnd::OnNcHitTest

  afx_msg UINT OnNcHitTest( CPoint point );

  返回值:下面列出的鼠标击中测试枚举值之一。

  · HTBORDER 在不具有可变大小边框的窗口的边框上。

  · HTBOTTOM 在窗口的水平边框的底部。

  · HTBOTTOMLEFT 在窗口边框的左下角。

  · HTBOTTOMRIGHT 在窗口边框的右下角。

  · HTCAPTION 在标题条中。

  · HTCLIENT 在客户区中。

  · HTERROR 在屏幕背景或窗口之间的分隔线上(与HTNOWHERE相同,除了Windows的DefWndProc函数产生一个系统响声以指明错误)。

  · HTGROWBOX 在尺寸框中。

  · HTHSCROLL 在水平滚动条上。

  · HTLEFT 在窗口的左边框上。

  · HTMAXBUTTON 在最大化按钮上。

  · HTMENU 在菜单区域。

  · HTMINBUTTON 在最小化按钮上。

  · HTNOWHERE 在屏幕背景或窗口之间的分隔线上。

  · HTREDUCE 在最小化按钮上。

  · HTRIGHT 在窗口的右边框上。

  · HTSIZE 在尺寸框中。(与HTGROWBOX相同)

  · HTSYSMENU 在控制菜单或子窗口的关闭按钮上。

  · HTTOP 在窗口水平边框的上方。

  · HTTOPLEFT 在窗口边框的左上角。

  · HTTOPRIGHT 在窗口边框的右上角。

  · HTTRANSPARENT 在一个被其它窗口覆盖的窗口中。

  · HTVSCROLL 在垂直滚动条中。

  · HTZOOM 在最大化按钮上。

  参数: point 包含了光标的x轴和y轴坐标。这些坐标总是用屏幕坐标给出的。

  说明:

  每当鼠标移动时,框架就为包含光标(或者是用SetCapture成员函数捕获了鼠标输入的CWnd对象)的CWnd对象调用这个成员函数。

  注意 框架调用这个成员函数以允许你的应用程序处理一个Windows消息。传递给你的成员函数的参数反映了接收到消息时框架接收到的参数。如果你调用了这个函数的基类实现,则该实现将使用最初传递给消息的参数(而不是你提供给这个函数的参数)。

  举例:

  比如果应用程序自己绘制的界面没有标题栏,那我们怎么来拖动程序呢?那么就可以添加下面消息:

  UINT CMainWindow::OnNcHitTest (CPoint point)

  {

  UINT nHitTest = CFrameWnd::OnNcHitTest (point);

  if (nHitTest == HTCLIENT) //如果是客户区

  nHitTest = HTCAPTION; //则把它当成标题栏

  return nHitTest;

  }

  经过上面处理后,如果用户拖动程序的客户区的话,系统会以为你拖动的是栏题栏,从而实现程序拖动

  请参阅:CWnd::GetCapture, WM_NCHITTEST

 

 

duilib里面的函数:

 

LRESULT WindowImplBase::OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
	POINT pt; pt.x = GET_X_LPARAM(lParam); pt.y = GET_Y_LPARAM(lParam);
	::ScreenToClient(*this, &pt);

	RECT rcClient;
	::GetClientRect(*this, &rcClient);
	
	if( !::IsZoomed(*this) )
	{
		RECT rcSizeBox = m_PaintManager.GetSizeBox();
		if( pt.y < rcClient.top + rcSizeBox.top )
		{
			if( pt.x < rcClient.left + rcSizeBox.left ) return HTTOPLEFT;
			if( pt.x > rcClient.right - rcSizeBox.right ) return HTTOPRIGHT;
			return HTTOP;
		}
		else if( pt.y > rcClient.bottom - rcSizeBox.bottom )
		{
			if( pt.x < rcClient.left + rcSizeBox.left ) return HTBOTTOMLEFT;
			if( pt.x > rcClient.right - rcSizeBox.right ) return HTBOTTOMRIGHT;
			return HTBOTTOM;
		}

		if( pt.x < rcClient.left + rcSizeBox.left ) return HTLEFT;
		if( pt.x > rcClient.right - rcSizeBox.right ) return HTRIGHT;
	}

	RECT rcCaption = m_PaintManager.GetCaptionRect();
	if( pt.x >= rcClient.left + rcCaption.left && pt.x < rcClient.right - rcCaption.right \
		&& pt.y >= rcCaption.top && pt.y < rcCaption.bottom ) {
			CControlUI* pControl = static_cast<CControlUI*>(m_PaintManager.FindControl(pt));
			if( pControl && _tcsicmp(pControl->GetClass(), _T("ButtonUI")) != 0 && 
				_tcsicmp(pControl->GetClass(), _T("OptionUI")) != 0 &&
				_tcsicmp(pControl->GetClass(), _T("TextUI")) != 0 )
				return HTCAPTION;
	}

	return HTCLIENT;
}

 

 

 客户区模拟非客户区 要重载的关于非客户的代码

LRESULT OnNcActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);

LRESULT OnNcCalcSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);

LRESULT OnNcPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); 

LRESULT OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);

 

CWnd中createex方法中

调用precreatex方法 其中里面是在   CREATESTRUCT ex         并且注册

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics