浅谈windows 编程中SendMessage函数的妙用!!!

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;
}




浅谈windows 编程中SendMessage函数的妙用!!!_第1张图片


全屏效果的图片如下:


浅谈windows 编程中SendMessage函数的妙用!!!_第2张图片


你可能感兴趣的:(c++)