win32窗口

一、入口函数

File -> Win32 Application -> A simple Win32 application.

二、打印

在win32中没有控制台,所以需要输出需要手动添加一个头文件

	Tools.h
	
	void __cdecl OutputDebugStringF(const char *format, ...); 
	
	#ifdef _DEBUG  
	#define DbgPrintf   OutputDebugStringF  
	#else  
	#define DbgPrintf  
	#endif 
	
	
	Tools.cpp
	
	void __cdecl OutputDebugStringF(const char *format, ...)  
	{  
	    va_list vlArgs;  
	    char    *strBuffer = (char*)GlobalAlloc(GPTR, 4096);  
	
	    va_start(vlArgs, format);  
	    _vsnprintf(strBuffer, 4096 - 1, format, vlArgs);  
	    va_end(vlArgs);  
	    strcat(strBuffer, "\n");  
	    OutputDebugStringA(strBuffer);  
	    GlobalFree(strBuffer);  
	    return;  
	}  

三、GetLastError

获取错误代码,如下

#include "stdafx.h"
#include "Tools.h"
int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
 	// TODO: Place code here.

	MessageBox((HWND)1,0,0,0);

	DWORD erroCode = GetLastError();
	DbgPrintf("%d\n",erroCode);
	return 0;
}

MessageBox第一个参数有误,用GetLastError会返回最后出现的错误的编号,然后利用这个编号去查找错误信息

四、事件

Windows中的事件是一个“动作”,这个动作可能是用户操作应用程序产生的,也可能是Windows自己产生的.

而消息,就是用来描述这些“动作”的,比如:

这个动作是什么时候产生的?

哪个应用程序产生的?

在什么位置产生的?

等等。。。

Windows为了能够准确的描述这些信息,提供了一个结构体:MSG,该结构体里面记录的事件的详细信息.

typedef struct tagMSG {				
  HWND   hwnd; 				
  UINT   message; 				
  WPARAM wParam; 				
  LPARAM lParam; 				
  DWORD  time; 				
  POINT  pt; 				
} MSG, *PMSG; 				

1、hwnd

窗口句柄

2、message

消息类型,是键盘还是鼠标,是鼠标左键还是右键

3、wParam 和 lParam

32位消息的特定附加信息,具体表示什么处决于message

4、time

消息创建时的时间

5、pt

消息创建时的鼠标位置

五、消息流程

1、系统/用户触发的某个动作(按下键盘或者点下鼠标)

2、系统将这些信息存储到MSG结构体中

3、系统将该消息存储到相关应用程序的消息队列中

4、从队列中获取消息

5、翻译消息(比如你按了下键盘上的a,message只记录了你按了下键盘,具体按了哪个键就需要翻译,翻译完之后封装成一个结构体)

6、分派消息(将消息翻译完之后,再把封装好的消息发给操作系统)

7、操作系统调用我们写的程序处理消息

六、创建窗口

1、设计窗口类

	//窗口的类名									
	TCHAR className[] = "My First Window"; 									
										
	// 创建窗口类的对象 									
	WNDCLASS wndclass = {0};						//一定要先将所有值赋值			
	wndclass.hbrBackground = (HBRUSH)COLOR_MENU;		                //窗口的背景色			
	wndclass.lpfnWndProc = WindowProc;					//窗口过程函数			
	wndclass.lpszClassName = className;					//窗口类的名字			
	wndclass.hInstance = hInstance;						//定义窗口类的应用程序的实例句柄	

2、注册窗口类


	//注册窗口类					
	RegisterClass(&wndclass);  	

3、创建窗口

	// 创建窗口  									
	HWND hwnd = CreateWindow(  									
		className,							//类名				
		TEXT("我的第一个窗口"),				                //窗口标题				
		WS_OVERLAPPEDWINDOW,				                //窗口外观样式 				
		10,							        //相对于父窗口的X坐标				
		10,								//相对于父窗口的Y坐标				
		600,								//窗口的宽度  				
		300,								//窗口的高度  				
		NULL,								//父窗口句柄,为NULL  				
		NULL,								//菜单句柄,为NULL  				
		hInstance,							//当前应用程序的句柄  				
		NULL);								//附加数据一般为NULL

4、判断是否创建成功

	if(hwnd == NULL)						//是否创建成功  				
		return 0;  							

5、显示窗口

	// 显示窗口  			
	ShowWindow(hwnd, SW_SHOW);  			

6、消息循环

	MSG msg;  				
	while(GetMessage(&msg, NULL, 0, 0))  				
	{  				
		TranslateMessage(&msg);  			
		DispatchMessage(&msg);  			
	}  				

7、回调函数

  • 窗口回调函数处理过的消息,必须传回0

  • 窗口回调不处理的消息,由DefWindowProc来处理

LRESULT CALLBACK WindowProc(  									
							IN  HWND hwnd,  		
							IN  UINT uMsg,  		
							IN  WPARAM wParam,  		
							IN  LPARAM lParam  		
							)  		
{  									
	switch(uMsg)								
	{								
		
	case WM_DESTROY:								
		{												
			PostQuitMessage(0);						
									
			return 0;						
		}							
		//键盘消息							

	}								
	return DefWindowProc(hwnd,uMsg,wParam,lParam);								
}  	

8、完整代码

// test.cpp : Defines the entry point for the application.
//

#include "stdafx.h"

									
LRESULT CALLBACK WindowProc(  									
							IN  HWND hwnd,  		
							IN  UINT uMsg,  		
							IN  WPARAM wParam,  		
							IN  LPARAM lParam  		
							);

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
	//
	//窗口的类名									
	TCHAR className[] = "My First Window"; 									
										
	// 创建窗口类的对象 									
	WNDCLASS wndclass = {0};				//一定要先将所有值赋值			
	wndclass.hbrBackground = (HBRUSH)COLOR_MENU;		//窗口的背景色			
	wndclass.lpfnWndProc = WindowProc;			//窗口过程函数			
	wndclass.lpszClassName = className;			//窗口类的名字			
	wndclass.hInstance = hInstance;				//定义窗口类的应用程序的实例句柄			
										


	//注册窗口类					
	RegisterClass(&wndclass);  		
			

										
	// 创建窗口  									
	HWND hwnd = CreateWindow(  									
		className,					//类名				
		TEXT("我的第一个窗口"),				//窗口标题				
		WS_OVERLAPPEDWINDOW,				//窗口外观样式 				
		10,						//相对于父窗口的X坐标				
		10,						//相对于父窗口的Y坐标				
		600,						//窗口的宽度  				
		300,						//窗口的高度  				
		NULL,						//父窗口句柄,为NULL  				
		NULL,						//菜单句柄,为NULL  				
		hInstance,				        //当前应用程序的句柄  				
		NULL);						//附加数据一般为NULL				
										
	if(hwnd == NULL)					//是否创建成功  				
		return 0;  								
										

	// 显示窗口  			
	ShowWindow(hwnd, SW_SHOW);  			
				
						
	MSG msg;  				
	while(GetMessage(&msg, NULL, 0, 0))  				
	{  				
		TranslateMessage(&msg);  			
		DispatchMessage(&msg);  			
	}  				
										
	return 0;
}

									
LRESULT CALLBACK WindowProc(  									
							IN  HWND hwnd,  		
							IN  UINT uMsg,  		
							IN  WPARAM wParam,  		
							IN  LPARAM lParam  		
							)  		
{  									
	switch(uMsg)								
	{								
		
	case WM_DESTROY:								
		{												
			PostQuitMessage(0);						
									
			return 0;						
		}							
						
	}								
	return DefWindowProc(hwnd,uMsg,wParam,lParam);								
}  									

七、窗口消息类型

	//窗口创建					
	case WM_CREATE: 							
		{						
			DbgPrintf("WM_CREATE %d\n",uMsg);									
								
			return 0;					
		}				

1、根据消息类型WM_CREATE,查找IN WPARAM wParam, IN LPARAM lParam 这两个参数的意义

2、

	//窗口移动
	case WM_MOVE:							
		{						
			DbgPrintf("WM_MOVE %d %d\n",wParam,lParam);					
			POINTS points = MAKEPOINTS(lParam);					
			DbgPrintf("X Y %d %d\n",points.x,points.y);					
								
			return 0;					
		}	

八、win32入口

1、入口有4个参数

  • IN HWND hwnd //句柄
  • IN UINT uMsg //永远为空
  • IN WPARAM wParam //接受命令行参数
  • IN LPARAM lParam //以什么方式显示最大化还是最小化等
posted @ 2021-12-07 23:42  lnterpreter  阅读(140)  评论(0编辑  收藏  举报