自绘按钮,鼠标移到按钮上的问题 (Win32)

木黑神 2015-08-12 10:20:18
问题是:鼠标移到按钮上,让按钮高亮、突显 出来的。(我下面用: 变色 来说)

按钮状态里面有:ODS_HOTLIGHT(可这家会不给面子,一直没效果)

按网上的说法和 MFC 代码,多是取得按钮在客户区的矩形,然后在 鼠标移动的消息中 判断 点在矩形中。
前几天我用这方法试了,效果不错(图形按钮,一块矩形区域,不是CreateWindow 创建的)。

今天又看孙鑫视频(08 对话框(2)你能抓到我吗的那个例子),他在函数中响应什么。。。???
然后鼠标要移到按钮上就隐藏。

我就在想,判断鼠标在矩形中的方法,不是最好的方法。系统应该有 API 直接支持的。
今天又建了个按钮(CreateWindow 创建的),发现 判断鼠标在矩形中的方法不管用了。
搞了半天才知道,问题出在哪:

当矩形位置和大小 等于 按钮 位置和大小的 时候,这时不管鼠标怎么在按钮上移动,按钮都不会(变色)。
(感觉网上的MFC 代码是可以的)

我把矩形的大小 从:(RECT rt = {10,10,100,100}; //按钮坐标),变成:(RECT rt = {10,10,120,120}; //按钮坐标 右和下都加了20)

这时在当鼠标移到按钮下面或右边时,按钮就会(变色)。

!!!实在搞不了了,求大神帮助和指点

窗口过程代码:

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HWND hbtn;
LPDRAWITEMSTRUCT btn;
static int i = 0;
static POINT x;

RECT rt = {10,10,120,120}; //按钮坐标 右和下都加了20
// RECT rt = {10,10,100,100}; //按钮坐标

switch(uMsg)
{
case WM_CREATE:
hbtn = CreateWindow(_T("button"),_T("OK"),WS_CHILD|WS_VISIBLE|BS_OWNERDRAW,10,10,100,100,hwnd,(HMENU)id_btn,hInst, NULL);
break;
case WM_MOUSEMOVE:
x.x = LOWORD(lParam);
x.y = HIWORD(lParam);

if(PtInRect(&rt, x))
{
i = 1;
InvalidateRect(hwnd,NULL,TRUE);
}
else
{
i = 0;
InvalidateRect(hwnd,NULL,TRUE);
}
break;
case WM_DRAWITEM:
btn = (LPDRAWITEMSTRUCT)lParam;

if(i == 1)
{
FillRect(btn->hDC, &btn->rcItem, (HBRUSH)CreateSolidBrush(RGB(0,255,255)));
FrameRect(btn->hDC, &btn->rcItem, (HBRUSH)GetStockObject(BLACK_BRUSH));
}
else
{
FillRect(btn->hDC, &btn->rcItem, (HBRUSH)CreateSolidBrush(RGB(255,0,0)));
FrameRect(btn->hDC, &btn->rcItem, (HBRUSH)GetStockObject(BLACK_BRUSH));
}

break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
...全文
368 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
木黑神 2015-08-13
  • 打赏
  • 举报
回复
引用 3 楼 schlafenhamster 的回复:
....
谢谢
schlafenhamster 2015-08-13
  • 打赏
  • 举报
回复
WNDPROC BToldProc; // BToldProc = (WNDPROC)SetWindowLong(m_hButtom1, GWL_WNDPROC, (LONG)BTProc); // LRESULT CALLBACK BTProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {// UINT id=GetWindowLong(hWnd,GWL_ID); if(id==IDC_BUTTON) { PAINTSTRUCT ps; HDC hdc; switch(Msg) {// case WM_LBUTTONDOWN: fBlocking=TRUE; // erase old DrawBoxOutline(hWnd,ptBeg,ptEnd); ptBeg.x=ptEnd.x=LOWORD(lParam); ptBeg.y=ptEnd.y=HIWORD(lParam); DrawBoxOutline(hWnd,ptBeg,ptEnd); return 0; case WM_MOUSEMOVE: if (fBlocking) { DrawBoxOutline(hWnd,ptBeg,ptEnd); ptEnd.x=LOWORD(lParam); ptEnd.y=HIWORD(lParam); DrawBoxOutline(hWnd,ptBeg,ptEnd); } return 0; case WM_LBUTTONUP: if (fBlocking) { fBlocking=FALSE; DrawBoxOutline(hWnd,ptBeg,ptEnd); InvalidateRect(hWnd,NULL,TRUE); } return 0; case WM_PAINT: hdc=BeginPaint(hWnd,&ps); //Rectangle(hdc,ptBeg.x,ptBeg.y,ptEnd.x,ptEnd.y); EndPaint(hWnd,&ps); DrawBoxOutline(hWnd,ptBeg,ptEnd); //InvalidateRect(hWnd,NULL,FALSE); //return CallWindowProc(BToldProc, hWnd, Msg, wParam, lParam); return 0; } }//if(id==ID_BUTTON) else //if(id==IDC_BUTTON1) { char prompt[80]; sprintf(prompt,"%d\n",GetDlgCtrlID(hWnd)); // OutputDebugString(prompt); DWORD hit; switch(Msg) { case WM_SIZE: OutputDebugString("WM_SIZE\n"); break; case WM_NCHITTEST://HTCLIENT=1 HTBORDER=18 hit=CallWindowProc(BToldProc, hWnd, Msg, wParam, lParam); if(hit >= 1) { sprintf(prompt,"BUTTON1: WM_NCHITTEST %d\n",hit); OutputDebugString(prompt); } return hit; break; case WM_MOUSEMOVE: { TRACKMOUSEEVENT tme; tme.cbSize = sizeof(tme); tme.dwFlags = TME_HOVER|TME_LEAVE; tme.dwHoverTime = 1; tme.hwndTrack = hWnd; BOOL boRet = _TrackMouseEvent(&tme); }break; case WM_MOUSELEAVE: OutputDebugString("Leave\n"); break; case WM_MOUSEHOVER: OutputDebugString("Over\n"); break; ....
yaozhiyong110 2015-08-13
  • 打赏
  • 举报
回复
你这没必要自己重新写 网上搜别人封装好的Button类就可以了 什么效果都有...
schlafenhamster 2015-08-13
  • 打赏
  • 举报
回复
应该 子类化 按钮, 因为 鼠标在 按钮内 时 WM_MOUSEMOVE 消息 是 按钮 处理 的 。 主程序中 只有放大 20 的 地方 WM_MOUSEMOVE 才到 主程序
赵4老师 2015-08-13
  • 打赏
  • 举报
回复
/* * Owner draw state */ #define ODS_SELECTED 0x0001 #define ODS_GRAYED 0x0002 #define ODS_DISABLED 0x0004 #define ODS_CHECKED 0x0008 #define ODS_FOCUS 0x0010 #if(WINVER >= 0x0400) #define ODS_DEFAULT 0x0020 #define ODS_COMBOBOXEDIT 0x1000 #endif /* WINVER >= 0x0400 */ #if(WINVER >= 0x0500) #define ODS_HOTLIGHT 0x0040 #define ODS_INACTIVE 0x0080 #endif /* WINVER >= 0x0500 */

15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧