浅谈windows 编程中SendMessage函数的妙用!!!
windows编程中SendMessage函数是非常重要的,而且这个对于理解windows的消息机制也很重要。本文用代码的方式实现了一些功能,借以说明此函数之妙用。说明不当之处,希望批评指正,谢谢!
废话不多说了,代码说明了一切!!!
/*本程序主要为了演示SendMessage的用法, *实现功能: * --> 1: 完全去掉窗口标题栏和边框。 * --> 2: 在窗口客户区按住鼠标左键可以拖动窗口。 * --> 3: 每隔2秒变换一次窗口背景颜色。 * --> 4: 屏蔽Alt + F4组合键的关闭窗口功能。 * --> 5: 在窗口客户区双击鼠标左键,让窗口最大化。 * --> 6: 按钮实现的最大化窗口,最小化窗口,关闭窗口。 * */ // 本程序在vs2012调试通过,保存文件时用cpp文件,用c++的方式编译。 #include<Windows.h> #define ID_TIMER 1 #define WM_CHANGECOLOR (WM_USER + 1) // 自定义消息 #define ID_COLOR 0 #define ID_MINIMIZE 1 #define ID_MAXIMIZE 2 #define ID_RESTORE 3 #define ID_FULLSCREEN 4 #define ID_CLOSE 5 LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM); int WINAPI WinMain(HINSTANCE hInstace,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) { WNDCLASS wndclass; wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.hCursor = LoadCursor(NULL,IDC_ARROW); wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION); wndclass.hInstance = hInstace; wndclass.lpfnWndProc = WndProc; wndclass.lpszMenuName = NULL; wndclass.lpszClassName = TEXT("sunkang"); RegisterClass(&wndclass); HWND hwnd = CreateWindow(TEXT("sunkang"),TEXT(""),WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstace,NULL); ShowWindow(hwnd,SW_SHOWNORMAL); UpdateWindow(hwnd); MSG msg; while(GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return 0; } LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) { static int cxClient,cyClient; static int cxScreen,cyScreen; static int btn_width,btn_height; static HBRUSH hBrush[5]; static HWND hButton[6]; static int indicator = 0; // 对应为红色 switch(message) { case WM_CREATE: { //得到应用程序实例句柄 HINSTANCE hInstance = (HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE); COLORREF color[5] = {RGB(255,0,0),RGB(0,255,0),RGB(0,0,255),RGB(0,0,0),RGB(100,100,100)}; TCHAR* title[6] = {TEXT("变换颜色"),TEXT("最小化"),TEXT("最大化"), TEXT("复位"),TEXT("全屏"),TEXT("关闭窗口")}; for(int i = 0; i < 5; ++i) hBrush[i] = CreateSolidBrush(color[i]); // 创建画刷 for(int i = 0; i < 6; ++i) hButton[i] = CreateWindow(TEXT("button"),title[i],WS_CHILDWINDOW | WS_VISIBLE | BS_DEFPUSHBUTTON, 0,0,0,0,hwnd,HMENU(i),hInstance,NULL); SetTimer(hwnd,ID_TIMER,2000,0); // 时间间隔为2秒 cxScreen = GetSystemMetrics(SM_CXSCREEN); //静态变量 cyScreen = GetSystemMetrics(SM_CYSCREEN); //静态变量 SendMessage(hwnd,WM_CHANGECOLOR,0,0); // 改变一下背景颜色 break; } case WM_SIZE: { cxClient = LOWORD(lParam); //静态变量 cyClient = HIWORD(lParam); btn_width = cxClient / 6; //静态变量 btn_height = cyClient / 5; for(int i = 0; i < 6; ++i) //依次设定button的位置 MoveWindow(hButton[i],i * btn_width,0,btn_width,btn_height,TRUE); //具体看WM_CHANGECOLOR消息的实现 break; } case WM_LBUTTONDOWN: { SendMessage(hwnd,WM_NCLBUTTONDOWN,HTCAPTION,lParam); break; } case WM_LBUTTONDBLCLK: { // 最大化窗口 SendMessage(hwnd,WM_SYSCOMMAND,SC_MAXIMIZE,lParam); break; } case WM_TIMER: { //按照设定,时间间隔为2秒 // 模拟鼠标的键击,点击"变换颜色"按钮 SendMessage(GetDlgItem(hwnd,ID_COLOR),WM_LBUTTONDOWN,wParam, MAKELONG(btn_width / 2,btn_height / 2)); // 左键按下 SendMessage(GetDlgItem(hwnd,ID_COLOR),WM_LBUTTONUP,wParam, MAKELONG(btn_width / 2,btn_height / 2)); // 左键释放 // 键击位置为button中心 // 可以看到每隔2秒窗口背景颜色会变换一次 break; } case WM_CHANGECOLOR: { indicator = indicator == 4 ? 0 : indicator + 1; SetClassLong(hwnd,GCL_HBRBACKGROUND,LONG(hBrush[indicator])); InvalidateRect(hwnd,NULL,TRUE); UpdateWindow(hwnd); break; } case WM_COMMAND: { switch(LOWORD(wParam)) { case ID_COLOR: SendMessage(hwnd,WM_CHANGECOLOR,wParam,lParam); break; case ID_MINIMIZE: SendMessage(hwnd,WM_SYSCOMMAND,SC_MINIMIZE,lParam); break; case ID_MAXIMIZE: SendMessage(hwnd,WM_SYSCOMMAND,SC_MAXIMIZE,lParam); break; case ID_RESTORE: //下面这条语句要加上,不然会有点问题,这与windows内部保存的状态有关。 SendMessage(hwnd,WM_SYSCOMMAND,SC_RESTORE,lParam); MoveWindow(hwnd,cxScreen / 8,cyScreen / 8,cxScreen * 3 / 4, cyScreen * 3 / 4,TRUE); break; case ID_FULLSCREEN: //下面这条语句要加上,不然会有点问题,这与windows内部保存的状态有关。 SendMessage(hwnd,WM_SYSCOMMAND,SC_RESTORE,lParam); MoveWindow(hwnd,0,0,cxScreen,cyScreen,TRUE); break; case ID_CLOSE: SendMessage(hwnd,WM_CLOSE,wParam,lParam); break; default: break; } SetFocus(hwnd); // 将焦点设为父窗口 break; } case WM_CLOSE: { if(IDOK == MessageBox(hwnd,TEXT("确定退出吗?"),TEXT("关闭窗口"),MB_OKCANCEL | MB_ICONQUESTION)) SendMessage(hwnd,WM_DESTROY,wParam,lParam); //当然也可以直接调用DestroyWindow(hwnd); break; } case WM_DESTROY: { KillTimer(hwnd,ID_TIMER); for(int i = 0; i < 5; ++i) //释放资源 DeleteObject(hBrush[i]); PostQuitMessage(0); break; } case WM_NCCALCSIZE: { //完全去掉标题栏和边框 break; } case WM_SYSKEYDOWN: { if(GetKeyState(VK_F4) < 0) // 屏蔽Alt + F4 的关闭窗口功能 break; else return DefWindowProc(hwnd,message,wParam,lParam); } default: return DefWindowProc(hwnd,message,wParam,lParam); } return 0; }
全屏效果的图片如下:
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。