WinMain与WndProc以及窗口诞生过程总结
一、int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int nCmdShow)
- 四个参数:
- hInstance:程序当前实例的句柄(handle to current instance),以后随时可以用GetModuleHandle(0)来获得
- hPrevInstance:前一个实例的句柄(handle to previous instance),在Win32中,每一个进程都有一个独立的4G地址空间,从0到2G属于进程私有,对其他进程来说是不可见的。所以,在Win32中,hPrevInstance总是为NULL。
- szCmdLine:指向以/0结尾的命令行,不包括EXE本身的文件名(pointer to command line),以后随时可以用GetCommandLine()来获取完整的命令行。
- iCmdShow:指明应该以什么方式显示主窗口(show state of window)。
- 宏定义:
- WINAPI:#define WINAPI __stdcall 表示函数调用遵循__stdcall规则
- HINSTANCE:
DECLARE_HANDLE(HINSTANCE);
typedef HINSTANCE HMODULE;#define DECLARE_HANDLE(name) struct name##__{int unused;}; typedef struct name##__ *name
- LPSTR:typedef _Null_terminated_ CHAR *NPSTR, *LPSTR, *PSTR; 就是一个以/0结尾的字符串
#ifndef VOID
#define VOID void
typedef char CHAR;
二、LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
- 参数:
- hwnd:窗口句柄
- message:消息ID
- wParam和lParam:消息参数
- 宏定义:
- LRESULT、WPARAM、LPARAM:
typedef UINT_PTR WPARAM;
typedef LONG_PTR LPARAM;
typedef LONG_PTR LRESULT;typedef _W64 unsigned int UINT_PTR, *PUINT_PTR;
typedef _W64 long LONG_PTR, *PLONG_PTR;
- CALLBACK:#define CALLBACK __stdcall
- HWND:DECLARE_HANDLE (HWND); 与HINSTANCE的定义类似
- UINT:typedef unsigned int UINT;
- LRESULT、WPARAM、LPARAM:
三、窗口诞生过程总结
- 定义窗口类结构(WNDCLASS)
#ifdef UNICODE
typedef WNDCLASSW WNDCLASS;
typedef PWNDCLASSW PWNDCLASS;
typedef NPWNDCLASSW NPWNDCLASS;
typedef LPWNDCLASSW LPWNDCLASS;
#else
typedef WNDCLASSA WNDCLASS;
typedef PWNDCLASSA PWNDCLASS;
typedef NPWNDCLASSA NPWNDCLASS;
typedef LPWNDCLASSA LPWNDCLASS;
#endif // UNICODE- 结构成员:
typedef struct tagWNDCLASSW {
UINT style; //窗口类型
WNDPROC lpfnWndProc; //窗口过程(必须是回调函数)
int cbClsExtra; //预留的额外空间,一般为0
int cbWndExtra; //预留的额外空间,一般为0
HINSTANCE hInstance; //应用程序的实例句柄
HICON hIcon; //为所有基于该窗口类的窗口设定一个图标
HCURSOR hCursor; //为所有基于该窗口类的窗口设定一个鼠标指针
HBRUSH hbrBackground; //指定窗口背景色
LPCWSTR lpszMenuName; //指定窗口菜单
LPCWSTR lpszClassName; //指定窗口类名
} WNDCLASSW, *PWNDCLASSW, NEAR *NPWNDCLASSW, FAR *LPWNDCLASSW;
- 注册窗口类
- RegisterClass:注册在随后调用CreateWindow函数和CreateWindowEx函数中使用的窗口类。
- 参数为lpWndClass,指向一个WNDCLASS结构的指针
- 返回值:ATOM的宏定义
typedef WORD ATOM;typedef unsigned short WORD; - 关于RegisterClassEx:参数lpwcx指向一个WNDCLASSEX结构的指针如果函数成功,返回这个窗口类型的标识号;如果函数失败,返回值为0。若想获得更多错误信息,请调用GetLastError函数。
- 创建窗口
HWND WINAPI CreateWindow(
_In_opt_ LPCTSTR lpClassName, // 窗口类名称
_In_opt_ LPCTSTR lpWindowName, // 窗口标题
_In_ DWORD dwStyle, // 窗口风格,或称窗口格式
_In_ int x, // 初始 x 坐标
_In_ int y, // 初始 y 坐标
_In_ int nWidth, // 初始 x 方向尺寸
_In_ int nHeight, // 初始 y 方向尺寸
_In_opt_ HWND hWndParent, // 父窗口句柄
_In_opt_ HMENU hMenu, // 窗口菜单句柄
_In_opt_ HINSTANCE hInstance, // 程序实例句柄
_In_opt_ LPVOID lpParam // 创建参数
);- _In_说明该参数是输入的,_opt_说明该参数是可选参数
- 函数成功返回窗口句柄,否则返回NULL
- 显示窗口
BOOL WINAPI ShowWindow(
_In_ HWND hWnd,
_In_ int nCmdShow
);- 第一次调用时应使用WinMain的参数nCmdShow作为参数
- 如果窗口之前可见,则返回非0否则返回0
- 更新窗口
BOOL UpdateWindow(
_In_ HWND hWnd
);- 绕过消息队列直接向窗口过程发送WM_PAINT消息
- 函数调用成功返回非0
- 消息循环
BOOL WINAPI GetMessage(
_Out_ LPMSG lpMsg, //指向MSG结构
_In_opt_ HWND hWnd, //需要检索消息窗口的句柄,为NULL时检索所有的当前线程的窗口消息和线程消息,为-1时只检索当前线程消息
_In_ UINT wMsgFilterMin, //指定被检索的最小消息值得整数
_In_ UINT wMsgFilterMax //指定被检索的最大消息值得整数
);- 作用:从当前线程的消息队列里取出一个消息并放入MSG结构中,不能获得其他线程的消息
- 若消息队列为空,函数会一直等待到有消息到来才有返回值
- 返回值:
- 函数出现错误则返回-1,
- 获得WM_QUIT消息返回0
- 否则返回非0
BOOL WINAPI TranslateMessage(
_In_ const MSG *lpMsg
);- 该函数将虚拟键消息转换为字符消息。字符消息被寄送到调用线程的消息队列里,当下一次线程调用函数GetMessage或PeekMessage时被读出。
LRESULT WINAPI DispatchMessage(
_In_ const MSG *lpmsg
);- 分派一个消息给窗口过程
- 返回值为窗口过程返回的值,通常被忽略
WinMain与WndProc以及窗口诞生过程总结的更多相关文章
- 创建Windows窗体 : WinMain() 与 WndProc()
#include <windows.h> #include <mmsystem.h> LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, ...
- 使用Win32/ATL建立窗口的过程
有时候想写个几十kb的小程序,MFC实在是太大了,Win32有时又太麻烦,怎么办呢?用ATL写会更方便和轻量级一些 ATL和MFC不同的是,ATL并没有强制性封装WinMain函数,仅封装了WndPr ...
- Win32窗口创建过程
编写窗口程序的步骤: 1 定义WinMain函数 2 定义窗口处理函数–自己定义处理消息 3 注册窗口类(往OS写入数据) 4 创建窗口 (在内存中创建窗口) 5 显示窗 ...
- uCGUI窗口初始化过程
一.相关结构体和变量 重要的uCGUI系统全局变量 NextDrawWin 下一个需要重绘的窗口句柄 WM__NumWindows 系统当前的总共 ...
- MFC应用程序创建窗口的过程 good
MFC应用程序中处理消息的顺序 1.AfxWndProc() 该函数负责接收消息,找到消息所属的CWnd对象,然后调用AfxCallWndProc 2.AfxCallWndProc() 该 ...
- C#在父窗口中调用子窗口的过程(无法访问已释放的对象)异常,不存在从对象类型System.Windows.Forms.DateTimePicker到已知的托管提供程序本机类型的映射。
一:C#在父窗口中调用子窗口的过程(无法访问已释放的对象)异常 其实,这个问题与C#的垃圾回收有关.垃圾回收器管 理所有的托管对象,所有需要托管数据的.NET语言(包括 C#)都受运行库的 垃圾回收器 ...
- (转)C#在父窗口中调用子窗口的过程(无法访问已释放的对象)
C#在父窗口中调用子窗口的过程: 1. 创建子窗口对象 2. 显示子窗口对象 笔者的程序中,主窗体MainFrm通过菜单调用子窗口ChildFrm.在窗体中定义了子窗口对象,然后在菜单项点击事件中 ...
- wxWidgets源码分析(6) - 窗口关闭过程
目录 窗口关闭过程 调用流程 关闭文档 删除视图 删除文档对象 关闭Frame App清理 多文档窗口的关闭 多文档父窗口关闭 多文档子窗口关闭 窗口的正式删除 窗口关闭过程总结 如何手工删除view ...
- VC++窗口创建过程,图形绘制,时钟程序
创建窗口步骤: (1)注册窗口类(RegisterClassEx) (2)创建窗口(CreateWindowEx) (3)在桌面显示窗口(ShowWindow) (4)更新窗口客户区(UpdateWi ...
随机推荐
- freemarker基本知识总结
1.取出内容 ${} 例如,${document.fileName} 2. <ul> <#list cms.documents("channel=XXXX") a ...
- DateTime用法二
任何项目,难免会碰到DateTime的显示问题,.net框架虽提供丰富多样的显示方法,但我很少使用,因老忘记细节,每次都要纠结到底月份在前还是年份在前:日期分隔符到底是“/”,还是“\”,还是“-”等 ...
- cf701A Cards
There are n cards (n is even) in the deck. Each card has a positive integer written on it. n / 2 peo ...
- Hat’s Words hdu-1247
就是查找这个单词能不能有两个单词组成,简单的字典树题目 ////////////////////////////////////////////////////////////// #include& ...
- Asp.Net读取服务器EXE文件的方法!(超简单实例)
Asp.Net读取服务器EXE文件的方法!(超简单实例) Process process = new Process(); process.StartInfo.FileName = "d:\ ...
- Maven assembly插件输出文件乱码问题
使用Maven的<artifactId>maven-assembly-plugin</artifactId>插件导致输出的XML配置文件源文件的中文注释变成乱码,排查了多个地方 ...
- 计算两点距离 ios
//计算两点距离 -(float)distanceBetweenTwoPoint:(CGPoint)point1 point2:(CGPoint)point2 { ) + powf(point1.y ...
- 神经网络和BP算法推导
注意:绘画太难了,因为他们画,本文中的所有插图来自基本算法饺子机类.请勿转载 1.习模型: 事实上,基本上全部的基本机器学习模型都能够概括为下面的特征:依据某个函数,将输入计算并输出. 图形化表示为下 ...
- 高性能 Socket 组件 HP-Socket v3.2.1-RC5 公布
HP-Socket 是一套通用的高性能 TCP/UDP Socket 组件,包括服务端组件.client组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP 通信系统,提供 C/C+ ...
- struts2,hibernate,spring整合笔记(1)
今天终于配置好了ssh框架的整合,记录下过程供参考 环境:window8.1,jdk1.7 ,带有javaee的eclipse,也就是说要能发布web项目,TOMCAT服务器,tomcat配置涉及到环 ...