关于WM_MOUSEHOVER和WM_MOUSELEAVE消息的用法以及按钮的变色问题!

来源:互联网 发布:少女淘宝店铺推荐 编辑:程序博客网 时间:2024/05/18 06:51

本文用代码的方式详细说明了Windows编程中WM_MOUSEHOVER和WM_MOUSELEAVE消息的用法,以及按钮的变色问题,实现的功能也很多,主要是示例了这两个消息的用法和具体实现按钮的变色。

代码的注释还算详细,就不多做说明了!看代码!

另外做一下功能的说明:

1: 在客户区点鼠标右键,弹出菜单可以关闭窗口!

2: 客户区中的那个巨大的按钮,鼠标移入和移出时可以变色和改变文字,单击鼠标左键可以更改客户区窗口的背景颜色!

3:在最上面的按钮上按住鼠标左键可以移动窗口!(按钮)

建一个空的win32工程,复制下面的代码就可以运行了,vs2012调试通过!!!

编译使用cpp文件,c++方式编译。



//#undef UNICODE  // 加上这行代码,可以编译非UNICODE版本//如果达不到按钮变色的效果,加上下面这行代码//#define _WIN32_WINNT  0x0400 //如有问题,请批评指正。//本程序在vs2012调试通过#include<Windows.h>#define ID_MINIMIZE   0#define ID_MAXIMIZE   1#define ID_CLOSE      2#define ID_CAPTION    3#define ID_CLICK      4int indicator_color = 0; COLORREF m_color[6] = {RGB(255,0,0),RGB(0,255,0),RGB(0,0,255),                       RGB(0,0,0),RGB(100,100,100),RGB(0,125,0)};HBRUSH   m_hBrush[6];  //画刷句柄HWND     btn_hwnd[5];  //按钮句柄HINSTANCE m_hInstance;  //应用程序实例句柄BOOL click_entry   = FALSE;  //FALSE 表示鼠标没有移入button上BOOL min_entry     = FALSE;BOOL max_entry     = FALSE;BOOL close_entry   = FALSE;// 主窗口过程LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);  //ID号为ID_CAPTION的button窗口过程LRESULT CALLBACK btn_CaptionProc(HWND,UINT,WPARAM,LPARAM);  //ID号为ID_MINIMIZE的button窗口过程LRESULT CALLBACK btn_MinProc(HWND,UINT,WPARAM,LPARAM); //ID号为ID_MAXIMIZE的button窗口过程LRESULT CALLBACK btn_MaxProc(HWND,UINT,WPARAM,LPARAM); //ID号为ID_CLOSE的button窗口过程LRESULT CALLBACK btn_CloseProc(HWND,UINT,WPARAM,LPARAM); //ID号为ID_CLICK的button窗口过程LRESULT CALLBACK btn_ClickProc(HWND,UINT,WPARAM,LPARAM); //以下变量为更改button的窗口过程之用WNDPROC old_btn_CaptionProc;WNDPROC old_btn_MinProc;WNDPROC old_btn_MaxProc;WNDPROC old_btn_CloseProc;WNDPROC old_btn_ClickProc;//一个内部使用的函数,主要用于在ID为ID_CAPTION的按钮上输出文字void MySetWindowText(const TCHAR *str){HDC hdc = GetDC(btn_hwnd[ID_CAPTION]);SetBkColor(hdc,m_color[5]);SetTextColor(hdc,RGB(255,255,255));  //白色RECT rect;GetClientRect(btn_hwnd[ID_CAPTION],&rect);InvalidateRect(btn_hwnd[ID_CAPTION],NULL,TRUE);UpdateWindow(btn_hwnd[ID_CAPTION]);TextOut(hdc,0,rect.bottom / 3 * 2,str,lstrlen(str));ReleaseDC(btn_hwnd[ID_CAPTION],hdc);}int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd){//初始化画刷for(int i = 0; i < 6; ++i)m_hBrush[i] = CreateSolidBrush(m_color[i]);m_hInstance = hInstance;WNDCLASS wndclass;wndclass.cbClsExtra = 0;wndclass.cbWndExtra = 0;wndclass.hbrBackground = m_hBrush[3]; // 黑色wndclass.hCursor = LoadCursor(NULL,IDC_CROSS);wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION);wndclass.hInstance = hInstance;wndclass.lpfnWndProc = WndProc;wndclass.lpszClassName = TEXT("sunkang");wndclass.lpszMenuName = NULL;wndclass.style = CS_HREDRAW | CS_HREDRAW;RegisterClass(&wndclass);HWND hwnd = CreateWindow(TEXT("sunkang"),TEXT(""),WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NULL);ShowWindow(hwnd,nShowCmd);UpdateWindow(hwnd);MSG msg;while(GetMessage(&msg,NULL,0,0)){TranslateMessage(&msg);DispatchMessage(&msg);}//释放资源for(int i = 0; i < 6; ++i)DeleteObject(m_hBrush[i]);}LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam){//static HINSTANCE hInstance;static int cxClient,cyClient;static int click_btn_width,click_btn_height;switch(message){case WM_CREATE:{//m_hInstance = (LPCREATESTRUCT(lParam))->hInstance;btn_hwnd[ID_CAPTION] = CreateWindow(TEXT("button"),TEXT(""),WS_CHILD | WS_VISIBLE | BS_OWNERDRAW,0,0,0,0,hwnd,HMENU(ID_CAPTION),m_hInstance,NULL);btn_hwnd[ID_CLICK] = CreateWindow(TEXT("button"),TEXT(""),WS_CHILD | WS_VISIBLE | BS_OWNERDRAW,0,0,0,0,hwnd,HMENU(ID_CLICK),m_hInstance,NULL);old_btn_CaptionProc = (WNDPROC)SetWindowLong(btn_hwnd[ID_CAPTION],                   GWL_WNDPROC,(LONG)btn_CaptionProc);old_btn_ClickProc = (WNDPROC)SetWindowLong(btn_hwnd[ID_CLICK],                   GWL_WNDPROC,LONG(btn_ClickProc));//以下三个按钮的父窗口为btn_hwnd[ID_CAPTION]btn_hwnd[ID_MINIMIZE] = CreateWindow(TEXT("button"),TEXT(""),WS_CHILD | WS_VISIBLE | BS_OWNERDRAW,0,0,0,0,btn_hwnd[ID_CAPTION],HMENU(ID_MINIMIZE),m_hInstance,NULL);btn_hwnd[ID_MAXIMIZE] = CreateWindow(TEXT("button"),TEXT(""),WS_CHILD | WS_VISIBLE | BS_OWNERDRAW,0,0,0,0,btn_hwnd[ID_CAPTION],HMENU(ID_MAXIMIZE),m_hInstance,NULL);btn_hwnd[ID_CLOSE] = CreateWindow(TEXT("button"),TEXT(""),WS_CHILD | WS_VISIBLE | BS_OWNERDRAW,0,0,0,0,btn_hwnd[ID_CAPTION],HMENU(ID_CLOSE),m_hInstance,NULL);//分别更改button的窗口过程old_btn_MinProc = (WNDPROC)SetWindowLong(btn_hwnd[ID_MINIMIZE],               GWL_WNDPROC,(LONG)(btn_MinProc));old_btn_MaxProc = (WNDPROC)SetWindowLong(btn_hwnd[ID_MAXIMIZE],               GWL_WNDPROC,(LONG)(btn_MaxProc));old_btn_CloseProc = (WNDPROC)SetWindowLong(btn_hwnd[ID_CLOSE],               GWL_WNDPROC,(LONG)(btn_CloseProc));break;}case WM_SIZE:{cxClient = LOWORD(lParam);cyClient = HIWORD(lParam);// 模拟标题栏的buttonMoveWindow(btn_hwnd[ID_CAPTION],0,0,cxClient,cyClient / 5,TRUE);click_btn_width = cxClient / 2;click_btn_height = cyClient / 5 * 2;//客户区中的buttonMoveWindow(btn_hwnd[ID_CLICK],cxClient / 4,cyClient / 5 * 2,click_btn_width,click_btn_height,TRUE);break;}case WM_CTLCOLORBTN:{if(HWND(lParam) == btn_hwnd[ID_CAPTION])return (LRESULT)m_hBrush[5];else{HDC hdc = HDC(wParam);LOGFONT lf;lf.lfCharSet = ANSI_CHARSET;lstrcpy(lf.lfFaceName,TEXT("宋体"));//lf.lfWidth = click_btn_width / 5;lf.lfHeight = click_btn_height;lf.lfItalic = FALSE;lf.lfClipPrecision = 0;lf.lfEscapement = 0;lf.lfOrientation = 0;lf.lfOutPrecision = 0;lf.lfPitchAndFamily = 0;lf.lfQuality = 0;lf.lfStrikeOut = FALSE;lf.lfUnderline = FALSE;lf.lfWeight = 400;if(click_entry == FALSE){TCHAR name[] = TEXT("HELLO");lf.lfWidth = click_btn_width / lstrlen(name);HFONT hFont = CreateFontIndirect(&lf);HFONT old_font = (HFONT)SelectObject(hdc,hFont);SetBkColor(hdc,m_color[0]);SetTextColor(hdc,m_color[2]);TextOut(hdc,0,0,name,lstrlen(name));SelectObject(hdc,old_font);return (LRESULT)m_hBrush[0];}else{TCHAR name[] = TEXT("WORLD");lf.lfWidth = click_btn_width / lstrlen(name);HFONT hFont = CreateFontIndirect(&lf);HFONT old_font = (HFONT)SelectObject(hdc,hFont);SetBkColor(hdc,m_color[5]);SetTextColor(hdc,m_color[1]);TextOut(hdc,0,0,name,lstrlen(name));SelectObject(hdc,old_font);return (LRESULT)m_hBrush[5];}}break;}case WM_RBUTTONDOWN:{HMENU hMenu = CreatePopupMenu();AppendMenu(hMenu,MF_STRING,ID_CLOSE,TEXT("退出!"));POINT pt = {LOWORD(lParam),HIWORD(lParam)};ClientToScreen(hwnd,&pt);TrackPopupMenu(hMenu,TPM_LEFTALIGN | TPM_TOPALIGN,pt.x,pt.y,0,hwnd,NULL);DeleteObject(hMenu);break;}case WM_MOUSEMOVE:{TCHAR buf[] = TEXT("右键有惊喜!!!");MySetWindowText(buf);break;}case WM_COMMAND:{switch(LOWORD(wParam)){            case ID_CLOSE: { SendMessage(hwnd,WM_CLOSE,0,0); break; }case ID_CLICK:{indicator_color = ++indicator_color % 5;SetClassLong(hwnd,GCL_HBRBACKGROUND,(LONG)(m_hBrush[indicator_color]));InvalidateRect(hwnd,NULL,TRUE);UpdateWindow(hwnd);break;}default:break;}break;}case WM_NCCALCSIZE:{ //完全去掉标题栏和边框break;}case WM_SYSKEYDOWN:{  //屏蔽Alt + F4关闭窗口的功能if(wParam == VK_F4);elsereturn DefWindowProc(hwnd,message,wParam,lParam);break;}case WM_CLOSE:{if(IDOK == MessageBox(hwnd,TEXT("确定退出吗?"),TEXT("关闭窗口!"),MB_OKCANCEL | MB_ICONQUESTION))DestroyWindow(hwnd);break;}case WM_DESTROY:{PostQuitMessage(0);break;}default:return DefWindowProc(hwnd,message,wParam,lParam);}return 0;}LRESULT CALLBACK btn_CaptionProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam){//static HINSTANCE hInstace = switch(message){case WM_SIZE:{int cxClient = LOWORD(lParam);int cyClient = HIWORD(lParam);int btn_width = cxClient / 15;int btn_height = cyClient / 4;MoveWindow(btn_hwnd[ID_MINIMIZE],cxClient - btn_width * 3, 0,         btn_width,btn_height,TRUE);MoveWindow(btn_hwnd[ID_MAXIMIZE],cxClient - btn_width * 2, 0,         btn_width,btn_height,TRUE);MoveWindow(btn_hwnd[ID_CLOSE],cxClient - btn_width, 0,         btn_width,btn_height,TRUE);break;}case WM_CTLCOLORBTN:{HDC hdc = HDC(wParam);switch(GetDlgCtrlID(HWND(lParam))){case ID_MINIMIZE:{if(min_entry == FALSE){SetBkColor(hdc,m_color[5]);SetTextColor(hdc,m_color[0]);RECT rect;GetClientRect(HWND(lParam),&rect);DrawText(hdc,TEXT("最小化"),lstrlen(TEXT("最小化")),&rect,DT_BOTTOM | DT_CENTER);return LRESULT(m_hBrush[5]);}else{SetBkColor(hdc,m_color[0]);SetTextColor(hdc,m_color[1]);RECT rect;GetClientRect(HWND(lParam),&rect);DrawText(hdc,TEXT("最小化"),lstrlen(TEXT("最小化")),&rect,DT_BOTTOM | DT_CENTER);return LRESULT(m_hBrush[0]);}break;}case ID_MAXIMIZE:{if(max_entry == FALSE){SetBkColor(hdc,m_color[5]);SetTextColor(hdc,m_color[1]);RECT rect;GetClientRect(HWND(lParam),&rect);DrawText(hdc,TEXT("最大化"),lstrlen(TEXT("最大化")),&rect,DT_BOTTOM | DT_CENTER);return LRESULT(m_hBrush[5]);}else{SetBkColor(hdc,m_color[1]);SetTextColor(hdc,m_color[0]);RECT rect;GetClientRect(HWND(lParam),&rect);DrawText(hdc,TEXT("最大化"),lstrlen(TEXT("最大化")),&rect,DT_BOTTOM | DT_CENTER);return LRESULT(m_hBrush[1]);}break;}case ID_CLOSE:{if(close_entry == FALSE){SetBkColor(hdc,m_color[5]);SetTextColor(hdc,m_color[3]);RECT rect;GetClientRect(HWND(lParam),&rect);DrawText(hdc,TEXT("关闭"),lstrlen(TEXT("关闭")),&rect,DT_BOTTOM | DT_CENTER);return LRESULT(m_hBrush[5]);}else{SetBkColor(hdc,m_color[0]);SetTextColor(hdc,m_color[2]);RECT rect;GetClientRect(HWND(lParam),&rect);DrawText(hdc,TEXT("关闭"),lstrlen(TEXT("关闭")),&rect,DT_BOTTOM | DT_CENTER);return LRESULT(m_hBrush[0]);}break;}default:break;}break;}case WM_COMMAND:{switch(LOWORD(wParam)){case ID_MINIMIZE:{SendMessage(GetParent(hwnd),WM_SYSCOMMAND,SC_MINIMIZE,lParam);break;}case ID_MAXIMIZE:{SendMessage(GetParent(hwnd),WM_SYSCOMMAND,SC_MAXIMIZE,lParam);break;}case ID_CLOSE:{SendMessage(GetParent(hwnd),WM_CLOSE,0,0);break;}default:break;}break;}case WM_LBUTTONDOWN:{ //模拟标题栏的鼠标左键双击SendMessage(GetParent(hwnd),WM_NCLBUTTONDOWN,HTCAPTION,lParam);break;}case WM_LBUTTONDBLCLK:{SendMessage(GetParent(hwnd),WM_NCLBUTTONDBLCLK,HTCAPTION,lParam);break;}case WM_MOUSEMOVE:{TCHAR buf[] = TEXT("温馨提示:双击鼠标左键可以最大化窗口,\按住鼠标左键可以拖动窗口!");MySetWindowText(buf);break;}default:return CallWindowProc(old_btn_CaptionProc,hwnd,message,wParam,lParam);// 也可以用下面的方式,一样的。// return old_btn_CaptionProc(hwnd,message,wParam,lParam);}return 0;}LRESULT CALLBACK btn_ClickProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam){switch(message){case WM_MOUSEMOVE:{if(click_entry == FALSE){TRACKMOUSEEVENT tme;tme.cbSize = sizeof(TRACKMOUSEEVENT);tme.dwFlags = TME_HOVER | TME_LEAVE;tme.dwHoverTime = 1; //1ms 立即显示tme.hwndTrack = hwnd;//激活WM_MOUSEHOVER消息TrackMouseEvent(&tme);}break;}case WM_MOUSEHOVER:{click_entry = TRUE;InvalidateRect(hwnd,NULL,TRUE);UpdateWindow(hwnd);TCHAR buf[] = TEXT("点击鼠标左键可以更改窗口颜色!");MySetWindowText(buf);break;}case WM_MOUSELEAVE:{click_entry = FALSE;InvalidateRect(hwnd,NULL,TRUE);UpdateWindow(hwnd);break;}default:return CallWindowProc(old_btn_ClickProc,hwnd,message,wParam,lParam);//return old_btn_ClickProc(hwnd,message,wParam,lParam);}return 0;}LRESULT CALLBACK btn_MinProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam){switch(message){case WM_MOUSEMOVE:{if(min_entry == FALSE){TRACKMOUSEEVENT tme;tme.cbSize = sizeof(TRACKMOUSEEVENT);tme.dwFlags = TME_HOVER | TME_LEAVE;tme.dwHoverTime = 1; //1ms 立即显示tme.hwndTrack = hwnd;//激活WM_MOUSEHOVER消息TrackMouseEvent(&tme);}break;}case WM_MOUSEHOVER:{min_entry = TRUE;InvalidateRect(hwnd,NULL,TRUE);UpdateWindow(hwnd);TCHAR buf[] = TEXT("最小化窗口!!!");MySetWindowText(buf);break;}case WM_MOUSELEAVE:{min_entry = FALSE;InvalidateRect(hwnd,NULL,TRUE);UpdateWindow(hwnd);break;}default:return CallWindowProc(old_btn_MinProc,hwnd,message,wParam,lParam);//return old_btn_ClickProc(hwnd,message,wParam,lParam);}return 0;}LRESULT CALLBACK btn_MaxProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam){switch(message){case WM_MOUSEMOVE:{if(max_entry == FALSE){TRACKMOUSEEVENT tme;tme.cbSize = sizeof(TRACKMOUSEEVENT);tme.dwFlags = TME_HOVER | TME_LEAVE;tme.dwHoverTime = 1; //1ms 立即显示tme.hwndTrack = hwnd;//激活WM_MOUSEHOVER消息TrackMouseEvent(&tme);}break;}case WM_MOUSEHOVER:{max_entry = TRUE;InvalidateRect(hwnd,NULL,TRUE);UpdateWindow(hwnd);TCHAR buf[] = TEXT("最大化窗口+++");MySetWindowText(buf);break;}case WM_MOUSELEAVE:{max_entry = FALSE;InvalidateRect(hwnd,NULL,TRUE);UpdateWindow(hwnd);break;}default:return CallWindowProc(old_btn_MaxProc,hwnd,message,wParam,lParam);//return old_btn_ClickProc(hwnd,message,wParam,lParam);}return 0;}LRESULT CALLBACK btn_CloseProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam){switch(message){case WM_MOUSEMOVE:{if(close_entry == FALSE){TRACKMOUSEEVENT tme;tme.cbSize = sizeof(TRACKMOUSEEVENT);tme.dwFlags = TME_HOVER | TME_LEAVE;tme.dwHoverTime = 1; //1ms 立即显示tme.hwndTrack = hwnd;//激活WM_MOUSEHOVER消息TrackMouseEvent(&tme);}break;}case WM_MOUSEHOVER:{close_entry = TRUE;InvalidateRect(hwnd,NULL,TRUE);UpdateWindow(hwnd);TCHAR buf[] = TEXT("关闭窗口XXXXXXX");MySetWindowText(buf);break;}case WM_MOUSELEAVE:{close_entry = FALSE;InvalidateRect(hwnd,NULL,TRUE);UpdateWindow(hwnd);break;}default:return CallWindowProc(old_btn_CloseProc,hwnd,message,wParam,lParam);//return old_btn_ClickProc(hwnd,message,wParam,lParam);}return 0;}


下面试程序运行的效果图!











0 0
原创粉丝点击