Win32 API (2013/1/17)
2013-01-17 14:41 Clingingboy 阅读(907) 评论(0) 编辑 收藏 举报
一.WM_MOUSEMOVE消息
- MK_CONTROL
- The CTRL key is down.
- MK_LBUTTON
- The left mouse button is down.
- MK_MBUTTON
- The middle mouse button is down.
- MK_RBUTTON
- The right mouse button is down.
- MK_SHIFT
- The SHIFT key is down.
- MK_XBUTTON1
- Windows 2000/XP: The first X button is down.
- MK_XBUTTON2
- Windows 2000/XP: The second X button is down.
The high-order word specifies the y-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area.
二.Point的转换
1
可以用宏GET_X_LPARAM和GET_Y_LPARAM取低位和高位
#define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
#define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
取坐标方法
int xPos = GET_X_LPARAM(lParam); // horizontal position
int yPos = GET_Y_LPARAM(lParam); // vertical position
CPoint的封装
ATLTYPES_INLINE CPoint::CPoint(_In_ LPARAM dwPoint) throw()
{
x = (short)GET_X_LPARAM(dwPoint);
y = (short)GET_Y_LPARAM(dwPoint);
}
所以可以用CPoint的封装来表示坐标
case WM_MOUSEMOVE:
{
CPoint pt(lParam);
OnMouseMove((UINT)wParam, pt);
}
break;
三.关于非客户端区域
Windows默认有非客户端区域,但有些客户端为了美观则去掉了默认非客户端区域的界面,绘制自己的界面.如何判断是否为非客户端区域完全由程序在WM_NCHITTEST消息中判断.
如QQ客户端,以后部分需要拖拽
默认非客户端区域的标题部分则提供了这样的功能,若下部分可以拖拽,为了利用这个功能,则需要在WM_NCHITTEST根据区域来进行判断,windows会对于返回的非客户区域进行处理
代码示例:
switch(message)
{
case WM_NCHITTEST:
{
bHandled=TRUE;
return HTCAPTION;
}
break;
}
同理,其他的非客户区域也如此,如窗体边缘的拉缩,也可以根据区域来判断
代码示例:
if(WM_NCHITTEST == uMsg)
{
CPoint point(lParam);
DWORD nStyle = GetWindowLong(GetSafeHwnd(), GWL_STYLE);
CRect rect;
::GetWindowRect(GetSafeHwnd(),&rect);
if((nStyle & WS_MAXIMIZE)) {
}
else
{
int nMargin=2;
if((point.x <= rect.left + 2 && point.y <= rect.top + 20) ||
(point.x <= rect.left + 20 && point.y <= rect.top + 2) ||
(point.x - rect.left + point.y - rect.top <= 10))
return HTTOPLEFT;
else if((point.x >= rect.right - 20 && point.y <= rect.top + 2) ||
(point.x >= rect.right - 2 && point.y <= rect.top + 20) ||
(rect.right - point.x + point.y - rect.top <= 10))
return HTTOPRIGHT;
else if((point.x <= rect.left + 2 && point.y >= rect.bottom - 20) ||
(point.x <= rect.left + 20 && point.y >= rect.bottom - 2) ||
(point.x - rect.left + rect.bottom - point.y <= 10))
return HTBOTTOMLEFT;
else if(point.x + point.y >= rect.right + rect.bottom - 15)
return HTBOTTOMRIGHT;
else if(point.x <= rect.left + nMargin)
return HTLEFT;
else if(point.x >= rect.right - nMargin)
return HTRIGHT;
else if(point.y <= rect.top + nMargin)
return HTTOP;
else if(point.y >= rect.bottom - nMargin)
return HTBOTTOM;
}
}
四.WM_GETMINMAXINFO消息
这个消息在每次WM_SIZE之前都会触发,告诉系统窗体的最大最小区域
参考:http://blog.csdn.net/flowshell/article/details/4795581
示例:
LRESULT CMoloGUIWindow::OnGetMinMaxInfo(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
MONITORINFO oMonitor = {};
oMonitor.cbSize = sizeof(oMonitor);
::GetMonitorInfo(::MonitorFromWindow(m_hWnd, MONITOR_DEFAULTTOPRIMARY), &oMonitor);
CRect rcWork;
if(oMonitor.dwFlags & MONITORINFOF_PRIMARY)
{
SystemParametersInfo(SPI_GETWORKAREA, NULL, &rcWork, NULL);
}
else
{
rcWork = oMonitor.rcMonitor;
}
LPMINMAXINFO lpMMI = (LPMINMAXINFO) lParam;
lpMMI->ptMaxPosition.x = rcWork.left;
lpMMI->ptMaxPosition.y = rcWork.top;
lpMMI->ptMaxSize.x = rcWork.right - rcWork.left;
lpMMI->ptMaxSize.y = rcWork.bottom - rcWork.top;
lpMMI->ptMinTrackSize.x = m_minSize.cx;//min width
lpMMI->ptMinTrackSize.y = m_minSize.cy;//min width
return 0;
}
五.WM_NCCALCSIZE消息
计算客户区域
示例:以下位置变成了(0,0)坐标
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
RECT rect;
GetClientRect(hWnd, &rect) ;
rect.left=0;
rect.top=0;
DrawText (hdc, TEXT ("Hello, Windows 98!"), -1, &rect,
DT_SINGLELINE) ;
EndPaint(hWnd, &ps);
break;
更改默认客户区域
case WM_NCCALCSIZE:
{
BOOL bCalSize=(BOOL)wParam;
NCCALCSIZE_PARAMS* pCalcParm=(NCCALCSIZE_PARAMS*)lParam;
int myCaptionHeight = 130;
int myLeftBorderWeight =10;
int myRightBorderWeight =10;
int myBottomBorderWeight =10;
if (TRUE)
{
RECT& rc = (RECT&)pCalcParm->rgrc[0];//get the client rectangle
rc.top += myCaptionHeight - GetSystemMetrics(SM_CYCAPTION) - GetSystemMetrics(SM_CYDLGFRAME);
rc.left +=myLeftBorderWeight- GetSystemMetrics(SM_CYDLGFRAME);
rc.bottom -= myBottomBorderWeight - GetSystemMetrics(SM_CYDLGFRAME);
rc.right -= myRightBorderWeight - GetSystemMetrics(SM_CYDLGFRAME);
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
这样会导致更改的原客户区域刷新机制失效,另外进行处理
参考:http://blog.csdn.net/lgstudyvc/article/details/7367806
http://blog.csdn.net/zdfcumt/article/details/5304221