会逃跑的按钮 1.0
本帖最后由 qq1242009750 于 2018-6-20 20:54 编辑今天写了一个好玩的小程序:让鼠标点击不到按钮。
主要的功能是,当鼠标计入到按钮的范围,按钮就会移动,从而达到点击不到按钮的效果。
我们知道鼠标进入了按钮的区域后,由按钮的消息过程来处理我们的消息。
1.在父窗口上创建一个按钮,要让按钮拥有我们的功能,首先我们要修改按钮的过程函数。(用到CreateWindow函数(创建窗口) SetWindowLong函数(用于更换按钮的消息处理过程))
2.捕获鼠标是否进入了此区域 (用到 WM_MOUSEMOVE WM_MOUSEHOVER WM_MOUSELEAVE 消息 和一个 TRACKMOUSEEVEVT结构体 和 TrakMouseEvent函数)
3.移动按钮 (用到 MoveWindow函数)
按钮移动规则:
先向右移动,让后向下移动
当不能右移动时,向左移动
当不能下移动时,向上移动
**移动范围在主窗口的客户区内
以此类推
**为了省去不需要的步骤在此省略了主窗口的注册和消息循环过程
①.我们在主窗口WM_CREATE消息里创建一个按钮,并修改按钮的消息处理过程
WNDPROC OldProc; //保存按钮之前的消息处理过程
RECT ClientRect; //保存住串口客户区的大小
//主窗口消息处理过程
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
OldProc = (WNDPROC)SetWindowLong(CreateWindow(TEXT("BUTTON"), TEXT("123"), WS_CHILD | BS_PUSHBUTTON | WS_VISIBLE, 100, 100, 50, 50, hWnd, (HMENU)IDC_BUTTON1, ((LPCREATESTRUCT)lParam)->hInstance, 0), GWL_WNDPROC, (LONG)WndProc2);
break;
case WM_SIZE:
GetClientRect(hWnd, &ClientRect);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
//按钮控件消息处理过程
LRESULT CALLBACK WndProc2(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static BOOL _bMouseTrack = TRUE; //捕抓标志 FALSE:取消捕抓 TRUE:恢复捕抓
switch (message)
{
default:
return CallWindowProc(OldProc, hWnd, message, wParam, lParam);
}
return 0;
}
②捕获鼠标是否进入了此区域
LRESULT CALLBACK WndProc2(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static BOOL _bMouseTrack = TRUE; //捕抓标志 FALSE:取消捕抓 TRUE:恢复捕抓
switch (message)
{
case WM_MOUSEMOVE:
if (_bMouseTrack)
{
TRACKMOUSEEVENT tme; //鼠标捕抓结构体
tme.cbSize = sizeof(TRACKMOUSEEVENT); //结构体的大小
tme.dwHoverTime = 1; //悬停的时间 备注:以毫秒为单位,
tme.hwndTrack = hWnd; //起作用的窗口句柄
tme.dwFlags = TME_HOVER | TME_LEAVE; //设置消息
TrackMouseEvent(&tme); //捕抓函数
}
break;
case WM_MOUSEHOVER: //鼠标在按钮悬停1ms时产生
_bMouseTrack = FALSE; //取消TrackMouseEvent函数再次捕抓
break;
case WM_MOUSELEAVE: //鼠标移出按钮时产生
_bMouseTrack = TRUE; //恢复rackMouseEvent函数再次捕抓
break;
default:
return CallWindowProc(OldProc, hWnd, message, wParam, lParam);
}
return 0;
}
③移动按钮
LRESULT CALLBACK WndProc2(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static BOOL _bMouseTrack = TRUE/*捕抓标志 FALSE:取消捕抓 TRUE:恢复捕抓*/, Hflag = TRUE/*水平方向左右移动标志*/, Vflag = TRUE/*垂直方向上下移动标志*/;
POINT pt;
static RECT rect;
static HPEN hpen;
HDC hdc;
switch (message)
{
case WM_MOUSEMOVE:
if (_bMouseTrack)
{
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(TRACKMOUSEEVENT);
tme.dwHoverTime = 1000;
tme.hwndTrack = hWnd;
tme.dwFlags = TME_HOVER | TME_LEAVE;
TrackMouseEvent(&tme);
}
break;
case WM_MOUSEHOVER:
_bMouseTrack = FALSE;
hdc = GetDC(hWnd);
SetBkColor(hdc, RGB(255, 255, 0));
SetWindowText(hWnd, TEXT(""));
GetWindowRect(hWnd, &rect);
ScreenToClient(GetParent(hWnd), (POINT*)&rect);
ScreenToClient(GetParent(hWnd), ((POINT*)&rect) + 1);
pt.x = rect.left;
pt.y = rect.top;
if (Hflag)
{
if (ClientRect.right - pt.x >= 100) //判断此方向是否有足够的位置给按钮移动,没有则改变移动方向
{
MoveWindow(hWnd, rect.left + 50, rect.top, rect.right - rect.left, rect.bottom - rect.top, TRUE);
rect.left += 50; //保持移动后的坐标
rect.right += 50; //保持移动后的坐标
}
else
{
Hflag = !Hflag;
}
}
else
{
if (pt.x - ClientRect.left >= 100)
{
MoveWindow(hWnd, rect.left - 50, rect.top, rect.right - rect.left, rect.bottom - rect.top, TRUE);
rect.left -= 50;
rect.right -= 50;
}
else
{
Hflag = !Hflag;
}
}
if (Vflag)
{
if (ClientRect.bottom - pt.y >= 100)
{
MoveWindow(hWnd, rect.left, rect.top + 50, rect.right - rect.left, rect.bottom - rect.top, TRUE);
rect.top += 50;
rect.bottom += 50;
}
else
{
Vflag = !Vflag;
}
}
else
{
if (pt.y - ClientRect.top >= 100)
{
MoveWindow(hWnd, rect.left, rect.top - 50, rect.right - rect.left, rect.bottom - rect.top, TRUE);
rect.top -= 50;
rect.bottom -= 50;
}
else
{
Vflag = !Vflag;
}
}
SendMessage(GetDlgItem(GetParent(hWnd), 11), LB_ADDSTRING, 0, (LPARAM)TEXT("HOVER"));
ReleaseDC(hWnd, hdc);
break;
case WM_MOUSELEAVE:
GetCursorPos(&pt);
_bMouseTrack = TRUE;
hdc = GetDC(hWnd);
SetWindowText(hWnd, TEXT("123"));
SendMessage(GetDlgItem(GetParent(hWnd), 11), LB_ADDSTRING, 0, (LPARAM)TEXT("LEAVE"));
ReleaseDC(hWnd, hdc);
break;
default:
return CallWindowProc(OldProc, hWnd, message, wParam, lParam);
}
return 0;
}
最后的主窗口和按钮的消息处理过程是这样的:
主窗口:
WNDPROC OldProc; //保存按钮之前的消息处理过程
RECT ClientRect; //保存住串口客户区的大小
//主窗口消息处理过程
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
OldProc = (WNDPROC)SetWindowLong(CreateWindow(TEXT("BUTTON"), TEXT("123"), WS_CHILD | BS_PUSHBUTTON | WS_VISIBLE, 100, 100, 50, 50, hWnd, (HMENU)IDC_BUTTON1, ((LPCREATESTRUCT)lParam)->hInstance, 0), GWL_WNDPROC, (LONG)WndProc2);
break;
case WM_SIZE:
GetClientRect(hWnd, &ClientRect);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
按钮消息处理过程:
LRESULT CALLBACK WndProc2(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static BOOL _bMouseTrack = TRUE/*捕抓标志 FALSE:取消捕抓 TRUE:恢复捕抓*/, Hflag = TRUE/*水平方向左右移动标志*/, Vflag = TRUE/*垂直方向上下移动标志*/;
POINT pt;
static RECT rect;
static HPEN hpen;
HDC hdc;
switch (message)
{
case WM_MOUSEMOVE:
if (_bMouseTrack)
{
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(TRACKMOUSEEVENT);
tme.dwHoverTime = 1000;
tme.hwndTrack = hWnd;
tme.dwFlags = TME_HOVER | TME_LEAVE;
TrackMouseEvent(&tme);
}
break;
case WM_MOUSEHOVER:
_bMouseTrack = FALSE;
hdc = GetDC(hWnd);
SetBkColor(hdc, RGB(255, 255, 0));
SetWindowText(hWnd, TEXT(""));
GetWindowRect(hWnd, &rect);
ScreenToClient(GetParent(hWnd), (POINT*)&rect);
ScreenToClient(GetParent(hWnd), ((POINT*)&rect) + 1);
pt.x = rect.left;
pt.y = rect.top;
if (Hflag)
{
if (ClientRect.right - pt.x >= 100) //判断此方向是否有足够的位置给按钮移动,没有则改变移动方向
{
MoveWindow(hWnd, rect.left + 50, rect.top, rect.right - rect.left, rect.bottom - rect.top, TRUE);
rect.left += 50; //保持移动后的坐标
rect.right += 50; //保持移动后的坐标
}
else
{
Hflag = !Hflag;
}
}
else
{
if (pt.x - ClientRect.left >= 100)
{
MoveWindow(hWnd, rect.left - 50, rect.top, rect.right - rect.left, rect.bottom - rect.top, TRUE);
rect.left -= 50;
rect.right -= 50;
}
else
{
Hflag = !Hflag;
}
}
if (Vflag)
{
if (ClientRect.bottom - pt.y >= 100)
{
MoveWindow(hWnd, rect.left, rect.top + 50, rect.right - rect.left, rect.bottom - rect.top, TRUE);
rect.top += 50;
rect.bottom += 50;
}
else
{
Vflag = !Vflag;
}
}
else
{
if (pt.y - ClientRect.top >= 100)
{
MoveWindow(hWnd, rect.left, rect.top - 50, rect.right - rect.left, rect.bottom - rect.top, TRUE);
rect.top -= 50;
rect.bottom -= 50;
}
else
{
Vflag = !Vflag;
}
}
SendMessage(GetDlgItem(GetParent(hWnd), 11), LB_ADDSTRING, 0, (LPARAM)TEXT("HOVER"));
ReleaseDC(hWnd, hdc);
break;
case WM_MOUSELEAVE:
GetCursorPos(&pt);
_bMouseTrack = TRUE;
hdc = GetDC(hWnd);
SetWindowText(hWnd, TEXT("123"));
SendMessage(GetDlgItem(GetParent(hWnd), 11), LB_ADDSTRING, 0, (LPARAM)TEXT("LEAVE"));
ReleaseDC(hWnd, hdc);
break;
default:
return CallWindowProc(OldProc, hWnd, message, wParam, lParam);
}
return 0;
}
好啦!以上就是小弟我的不才之作,有更好的Ider,请大家通知我! {:5_109:}
升级啦!
会逃跑的按钮(升级版)
http://bbs.fishc.com/thread-117255-1-1.html
页:
[1]