WIN32学习——Windows消息机制(二)

一、消息的相关函数:

1 GetMessage - 从系统中获取消息,将消息从系统中移除,它是一个阻塞函数。当系统无消息时,GetMessage会等候下一条消息。

2 PeekMessage - 以查看的方式从系统获取消息,可以不将消息从系统中移除,是一个非阻塞函数,当系统无消息时,返回false,继续执行后续代码。

3 SendMessage - 发送消息,会直接把消息发送给窗口处理函数,而不经过消息队列和消息循环,会等候消息处理结果。

4 PostMessage - 投递消息,把消息投递到消息队列中,由消息循环完成消息的处理,消息发出后立刻返回,不等候消息执行结果。

二、消息队列类型:

1 系统消息队列 - 由系统维护的消息队列,存放系统产生的消息,例如键盘、鼠标等。

2 程序消息队列 - 属于每一个应用程序(线程)的消息队列,由应用程序(线程)维护。

三、从消息队列中获取消息的次序:

1 在程序(线程)消息队列中查找消息,如果队列有消息,检查消息是否满足指定条件,不满足条件就不会取出消息,否则从程序消息队列中取出消息返回。

2 如果程序(线程)消息队列中没有消息,向系统消息队列中获取属于本程序的消息,如果系统队列的当前消息属于本程序,系统会将消息转发到程序消息队列中,并取得返回。

3 如果系统消息队列也没有消息,检查当前窗口需要重新绘制的区域,如果发现有需要绘制的区域,产生WM_PAINT消息,取得消息返回处理。

4 如果没有重新绘制区域,检查定时器如果有到时的定时器,产生WM_TIMER,返回处理执行。

5 如果没有到时间的定时器,整理程序的资源、内存等。GetMessage()函数会继续等候下一条消息,而PeekMessage()函数会返回FALSE,交出程序的使用权。

四、绘图消息WM_PAINT:

1 程序收到WM_PAINT消息,不使用这个消息的两个附加参数WPARAM和LPARAM。

2 绘图的步骤:

a、开始绘图处理

HDC BeginPaint(

HWND hwnd, // 绘图窗口

LPPAINTSTRUCT lpPaint // 绘图参数的BUFF

);返回绘图设备句柄HDC

b、绘图

c、结束绘图处理

BOOL EndPaint(

HWND hWnd, // 绘图窗口

CONST PAINTSTRUCT *lpPaint // 绘图参数的指针BeginPaint返回

);

五、键盘消息:

WM_KEYDOWN - 按键被按下时产生

WM_KEYUP - 按键被放开时产生

WM_CHAR - 字符消息(不是按键直接产生,是由TranslateMessage函数翻译按键消息产生)

按键消息(键盘按键被按下或弹起时,所带的附加参数说明):

WPARAM - 按键的Virtual Key

LPARAM - 按键的参数,例如按下次数

WM_CHAR消息(按下某键通过TranslateMessage函数翻译之后生成的WM_CHAR消息的附加参数说明):

WPARAM - 输入的字符

LPARAM - 按键的相关参数

附加以上总结的代码案例:

/*
功能:
1 点击关闭按钮,弹框提示
2 在WIN32程序中调用控制台的使用(AllocConsole)
3 自定义消息的使用
4 绘图消息WM_PAINT的使用
5 键盘消息的使用WM_KEYDOWN、WM_KEYUP、WM_CHAR
6 通过使用键盘上下左右按键移动自绘制的图形
*/

#include <Windows.h>
#include <stdio.h>
#include <tchar.h>

HINSTANCE g_hInstance;
HANDLE hOutHandle;
int n_xPos = 100,n_yPos =100;
//自定义消息
#define WM_MYMESSAGE WM_USER + 1

void OnPaint(HWND hWnd)
{
	PAINTSTRUCT ps;
	HDC hDC = BeginPaint(hWnd,&ps);
	//TextOut(hDC,100,100,__TEXT("miao miao"),lstrlen(__TEXT("miao miao")));
	TextOut(hDC,n_xPos,n_yPos,__TEXT("miao miao"),lstrlen(__TEXT("miao miao")));
	EndPaint(hWnd,&ps);
}

void OnKeyDown(HWND hWnd,WPARAM wParam)
{
	if (VK_UP == wParam)
	{
		n_yPos-= 4;
		InvalidateRect(hWnd,NULL,TRUE);
	}
	if (VK_DOWN == wParam)
	{
		n_yPos+= 4;
		InvalidateRect(hWnd,NULL,TRUE);
	}
	if (VK_LEFT == wParam)
	{
		n_xPos-= 4;
		InvalidateRect(hWnd,NULL,TRUE);
	}
	if (VK_RIGHT == wParam)
	{
		n_xPos+= 4;
		InvalidateRect(hWnd,NULL,TRUE);
	}
}

void OnKeyUp()
{
	//为验证WM_KEYUP和WM_CHAR消息,打开一个控制台,当收到消息时在控制台中显示相应内容
	TCHAR szText[256] = {0};
	lstrcpy(szText,__TEXT("WM_KEYUP\n"));
	WriteConsole(hOutHandle,szText,lstrlen(szText),NULL,NULL);
}

void OnKeyChar(WPARAM wParam)
{
	TCHAR szText[256] = {0};
	_stprintf_s(szText,256,__TEXT("char:%08X\n"),wParam);
	WriteConsole(hOutHandle,szText,lstrlen(szText),NULL,NULL);
}

LRESULT CALLBACK MyProc(HWND hWnd,UINT nMsg,WPARAM wParam,LPARAM lParam)
{
	switch(nMsg)
	{
		//键盘消息验证
	case WM_KEYDOWN:
		OnKeyDown(hWnd,wParam);
		break;
	case WM_KEYUP:
		OnKeyUp();
		break;
	case WM_CHAR:
		OnKeyChar(wParam);
		break;
		//绘图消息验证
	case WM_PAINT:
		OnPaint(hWnd);
		break;
		//通过WM_CREATE发送自定义消息来验证自定义消息
	case WM_MYMESSAGE:
		MessageBox(hWnd,__TEXT("WM_MYMESSAGE  is called"),__TEXT("提示"),MB_OK);
		break;
	case WM_CREATE:
		SendMessage(hWnd,WM_MYMESSAGE,NULL,NULL);
		break;
	case WM_SYSCOMMAND:
		if (wParam == SC_CLOSE)
		{
			if(IDYES == MessageBox(hWnd,__TEXT("确定要关闭窗口"),__TEXT("提示"),MB_YESNO))
				PostQuitMessage(0);
			else
				return 0;
		}
		break;
	}
	return DefWindowProc(hWnd,nMsg,wParam,lParam);
}

ATOM Register(LPCWSTR className)
{
	WNDCLASSEX wc = {0};
	wc.cbClsExtra = 0;
	wc.cbSize = sizeof(WNDCLASSEX);
	wc.cbWndExtra = 0;
	wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
	wc.hCursor = NULL;
	wc.hIcon = NULL;
	wc.hIconSm = NULL;
	wc.hInstance = g_hInstance;
	wc.lpfnWndProc = MyProc;
	wc.lpszClassName = className;
	wc.lpszMenuName = NULL;
	wc.style = CS_VREDRAW | CS_HREDRAW;
	return RegisterClassEx(&wc);
}

HWND Create(LPCWSTR className,LPCWSTR windowName)
{
	return CreateWindowEx(0,className,windowName,WS_OVERLAPPEDWINDOW,100,100,600,600,NULL,NULL,g_hInstance,NULL);
}

void Show(HWND hWnd)
{
	ShowWindow(hWnd,SW_SHOW);
	UpdateWindow(hWnd);
}

void Message()
{
	MSG ms = {0};
	while (GetMessage(&ms,NULL,0,0))
	{
		TranslateMessage(&ms);
		DispatchMessage(&ms);
	}
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
	//打开控制台
	AllocConsole();
	hOutHandle = GetStdHandle(STD_OUTPUT_HANDLE);
	g_hInstance = hInstance;
	Register(__TEXT("Main"));
	HWND hWnd = Create(__TEXT("Main"),__TEXT("This is test"));
	Show(hWnd);
	Message();
	return 0;
}


猜你喜欢

转载自blog.csdn.net/bimabushihaodongxi/article/details/70808538
今日推荐