一般的窗口,带有标题栏的,我们把鼠标放到上面去就可以拖拽,但POPUP的窗口是没有办法的,这就需要用鼠标的一系列的消息来搞定!
这一系列的鼠标消息是 按下+移动+抬起的组合,步骤如下:
0. 创建窗口为 WS_POPUP类型,显示出一个灰的矩形,没有标题栏等;
1. 处理左键按下WM_LBUTTONDOWN消息,获取到鼠标在窗口上的坐标位置(全局变量),鼠标会移动到窗口外,因此需要开户捕捉capture;
2. 处理鼠标移动WM_MOUSEMOVE消息,得到当前鼠标所在屏幕的坐标,将x坐标减去在本窗口的x偏移量(Y同理),移动窗口;
3. 处理鼠标抬起WM_LBUTTONUP消息,释放捕捉
4. 处理右键菜单WM_CONTEXTMENU消息,加入一个“退出”菜单项,弹出菜单,点击退出
代码如下:
0
hWnd = CreateWindowEx(0, /* extended window style */
"WindowClassName", /* registered class */
"Windows Application", /* window title */
WS_POPUP, /* default window style */
200, /* x position */
200, /* y position */
300, /* width of window */
200, /* heigth of window */
HWND_DESKTOP, /* The window is a child-window to desktop */
NULL, /* no menu */
hInst, /* Program Instance handler */
NULL); /* No Window Creation data */
1
bool bDragging = false; //是否拖动标志
POINT ptBegin; //起点坐标
case WM_LBUTTONDOWN:
{
bDragging = true;
ptBegin.x = LOWORD(lParam); //获取x轴坐标
ptBegin.y = HIWORD(lParam); //获取y轴坐标
SetCapture(hwnd); //捕捉
}
break;
2
case WM_MOUSEMOVE:
{
if (bDragging)
{
POINT pt;
GetCursorPos(&pt);
int px = pt.x - ptBegin.x;
int py = pt.y - ptBegin.y;
SetWindowPos(hwnd, NULL, px, py,0,0,SWP_NOSIZE);;
}
}
break;
3
case WM_LBUTTONUP:
{
bDragging = false;
ReleaseCapture();
}
break;
4
case WM_CONTEXTMENU:
{
HMENU hPop = CreatePopupMenu(); //弹出菜单句柄
AppendMenu(hPop, MF_STRING, 11010, "退出");
POINT pt;
pt.x = LOWORD(lParam);
pt.y = HIWORD(lParam);
TrackPopupMenu(hPop,TPM_LEFTALIGN|TPM_TOPALIGN, pt.x,pt.y,0,hwnd, NULL);
}
case WM_COMMAND:
{
switch(LOWORD(wParam))
{
case 11010: //右键退出菜单
PostQuitMessage(0);
break;
}
}
至此,第3部分的消息处理练习先告一段落了,我们在这部分主要练习了键盘,鼠标和定时器消息以及它们之间的组合加强。到此为止,我们已经有一定的能力去制作简单的Windows程序,实现许多常用的功能~