windows编程中SendMessage函数是非常重要的,而且这个对于理解windows的消息机制也很重要。本文用代码的方式实现了一些功能,借以说明此函数之妙用。说明不当之处,希望批评指正,谢谢!
废话不多说了,代码说明了一切!!!
/*本程序主要为了演示SendMessage的用法,
*实现功能:
* --> 1: 完全去掉窗口标题栏和边框。
* --> 2: 在窗口客户区按住鼠标左键可以拖动窗口。
* --> 3: 每隔2秒变换一次窗口背景颜色。
* --> 4: 屏蔽Alt + F4组合键的关闭窗口功能。
* --> 5: 在窗口客户区双击鼠标左键,让窗口最大化。
* --> 6: 按钮实现的最大化窗口,最小化窗口,关闭窗口。
*
*/
// 本程序在vs2012调试通过,保存文件时用cpp文件,用c++的方式编译。
#include
#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;
}
全屏效果的图片如下: