现在的位置: 首页 > 综合 > 正文

duilib中设置不激活窗口后移动无法立即跟随的bug

2018年10月15日 ⁄ 综合 ⁄ 共 3459字 ⁄ 字号 评论关闭
LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{	
	switch (uMsg)
	{
	case WM_LBUTTONDOWN:
		{
			OnMouseLButtonDown(wParam, lParam);			
			break;
		}
	case WM_LBUTTONUP:
		{
			OnMouseLButtonUp(wParam, lParam);			
			break;
		}
	case WM_MOUSEMOVE:
		{
			OnMouseLDownMove(wParam, lParam);			
			break;
		}
	case WM_NCMOUSEMOVE:
		{
			OnMouseNcLDownMove(wParam, lParam);			
			break;
		}
	case WM_NCLBUTTONUP:
		{
			OnMouseNcLButtonUp(wParam, lParam);			
			break;
		}
	case WM_NCLBUTTONDOWN:
		{
			OnMouseNcLButtonDown(wParam, lParam);	
			break;
		}

	}
	return __super::HandleMessage(uMsg, wParam, lParam);
}

void OnMouseNcLButtonDown(WPARAM wParam, LPARAM lParam)
{
	POINT point;
	point.x = (short)LOWORD( lParam);
	point.y = (short)HIWORD( lParam);
	ClientToScreen(m_hWnd, &point);
	m_ptPrev = point;
}
void OnMouseNcLButtonUp(WPARAM wParam, LPARAM lParam)
{
	POINT ptIn;
	ptIn.x = (short)LOWORD( lParam);
	ptIn.y = (short)HIWORD( lParam);
	POINT pt = ptIn;
	ClientToScreen(m_hWnd, &pt);
	RECT rectWnd, rcWorkArea;
	SIZE sz;
	GetWindowRect(m_hWnd, &rectWnd);
	OffsetRect(&rectWnd, m_ptPrev.x - m_ptMouseDown.x, m_ptPrev.y - m_ptMouseDown.y);
	OffsetRect(&rectWnd, pt.x - m_ptPrev.x, pt.y - m_ptPrev.y);
	::SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWorkArea, FALSE);
	sz.cx = rectWnd.right - rectWnd.left;
	sz.cy = rectWnd.bottom - rectWnd.top;
	if (rectWnd.left  + sz.cx > rcWorkArea.right)
	{
		rectWnd.left = rcWorkArea.right - sz.cx;
	}
	else if(rectWnd.left < 0)
	{
		rectWnd.left = 0;
	}
	if(rectWnd.top < 0)
	{
		rectWnd.top = 0;
	}
	else if(rectWnd.top + sz.cy > rcWorkArea.bottom )
	{
		rectWnd.top = rcWorkArea.bottom - sz.cy;
	}
	m_ptPrev.x = m_ptPrev.y = m_ptMouseDown.x = m_ptMouseDown.y = -1;
	GetWindowRect(m_hWnd, &rectWnd);
}
void OnMouseLButtonDown(WPARAM wParam, LPARAM lParam)
{
	m_bMouseState = LNCDOWN;
	// 按下标题栏时拖放
	::SendMessage(m_hWnd, WM_NCLBUTTONDOWN, wParam, lParam);
}
void OnMouseLButtonUp(WPARAM wParam, LPARAM lParam)
{
	POINT ptIn, pt;
	pt.x = ptIn.x = (short)LOWORD(lParam);
	pt.y = ptIn.y = (short)HIWORD(lParam);
	HRGN hRgn =	CreateRectRgn(0, 0, 0, 0);
	GetWindowRgn(m_hWnd, hRgn);
	ClientToScreen(m_hWnd, &pt);
	if (!PtInRegion(hRgn, ptIn.x, ptIn.y) && (m_bMouseState == NOEVENT)) //释放鼠标捕捉
	{
		::SendMessage(m_hWnd, WM_MOUSELEAVE, 0, 0);
	}
	DeleteObject(hRgn);
	if ((m_bMouseState == LNCDOWN) || (m_bMouseState == NOEVENT))
	{
		::SendMessage(m_hWnd, WM_NCMOUSEMOVE, wParam, lParam);
	}
}
void OnMouseLDownMove(WPARAM wParam, LPARAM lParam)
{
	POINT ptIn, pt;
	pt.x = ptIn.x = (short)LOWORD(lParam);
	pt.y = ptIn.y = (short)HIWORD(lParam);
	HRGN hRgn =	CreateRectRgn(0, 0, 0, 0);
	GetWindowRgn(m_hWnd, hRgn);
	ClientToScreen(m_hWnd, &pt);
	if (!PtInRegion(hRgn, ptIn.x, ptIn.y) && (m_bMouseState == NOEVENT)) //释放鼠标捕捉
	{
		::SendMessage(m_hWnd, WM_MOUSELEAVE, 0, 0);
	}
	DeleteObject(hRgn);
	if ((m_bMouseState == LNCDOWN) || (m_bMouseState == NOEVENT))
	{
		::SendMessage(m_hWnd, WM_NCMOUSEMOVE, wParam, lParam);
	}


}
void OnMouseNcLDownMove(WPARAM wParam, LPARAM lParam)
{
	UINT nFlags = (UINT)wParam;
	POINT point;
	point.x = (short)LOWORD( lParam);
	point.y = (short)HIWORD( lParam);
	if (nFlags & MK_LBUTTON)
	{
		RECT rectWnd;
		POINT pt = point;
		GetWindowRect(m_hWnd, &rectWnd);
		ClientToScreen(m_hWnd, &pt);
		OffsetRect(&rectWnd, pt.x - m_ptPrev.x , pt.y - m_ptPrev.y);
		m_ptPrev = pt;
		int nWidth = rectWnd.right - rectWnd.left;
		int nHeight = rectWnd.bottom - rectWnd.top;
		RECT rcWorkArea;
		::SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWorkArea, FALSE);
		if(rectWnd.left < rcWorkArea.left)
		{
			rectWnd.left = rcWorkArea.left;
		}
		else if (rectWnd.left  + nWidth > rcWorkArea.right)
		{
			rectWnd.left = rcWorkArea.right - nWidth;
		}
		if (rectWnd.top < rcWorkArea.top)
		{
			rectWnd.top = rcWorkArea.top;
		}
		else if (rectWnd.top + nHeight > rcWorkArea.bottom)
		{
			rectWnd.top = rcWorkArea.bottom - nHeight;
		}
		::MoveWindow(m_hWnd, rectWnd.left, rectWnd.top, nWidth, nHeight, TRUE);
	}

}

private:enum MOUSESTATE{NOEVENT, LNCDOWN, LCLIENTDOWN, LSIZEDOWN};MOUSESTATE m_bMouseState; //记录鼠标状态POINT m_ptMouseDown; //记录鼠标按下时的位置POINT m_ptPrev; //记录鼠标前一次的位置


【上篇】
【下篇】

抱歉!评论已关闭.