WinMain函数
函数说明
int WINAPI WinMain
(HINSTANCE hThisInst, //应用程序当前实例句柄
HINSTANCE hPrevInst, //应用程序其他实例句柄
LPSTR lpszCmdLine, //指向程序命令行参数的指针
Int nCmdShow //应用程序开始执行时窗口显示方式的整数值标识 )
Windows是多任务管理的,也就是说在这个应用程序中,我们可以启动或者执行另外一个应用程序或者实例,那么你要运行另外一个应用程序或者实例,必须有一个句柄去指向你所要执行的其他应用程序或者实例。那既然你要执行其他应用程序,你就要有一个指向程序的命令的这个 参数的指针,以及应用程序开始执行时窗口所显示的标识。
注意,Windows既然是多任务管理的,也就是说。同一个应用程序的多个窗口可能会同时存在,那么每一个窗口我们都称之为一个实例的情况下,也就是说多个窗口每一个都要有一个句柄指向一个窗口,这样的话,我们才能识别到不同的窗口,也就是说用一个句柄唯一的指向一个窗口对象,所以我们操作不同实例的时候,都是把指向这个实例的句柄找到,通过句柄去操作这个对象。
初始化
通过给窗口类数据结构WNDCLASS赋值完成该数据结构中包含窗口类的各种属性,句柄可以理解为数据类型
调用GetStockObject函数获取系统提供的背景刷 HBRUSH GetStockObject(int nBrush);
创建一个窗口类的实例由函数CreateWindow()来实现
函数原型
HWND CreateWindow
(LPCTSTR lpszClassName, //窗口类名
LPCTSTR lpszTitle, //窗口标题名
DWORD dwStyle, //创建窗口样式
int x,y, //窗口左上角坐标
int nWidth,nHeight,//窗口宽度和高度
HWND hwndParent, //该窗口的父窗口句柄
HMENU hMenu, //窗口主菜单句柄
HINSTANCE hInstance, //创建窗口的应用程序当前句柄
LPVOID lpParam //指向一个传递给窗口的参数值的指针)
窗口类的显示由ShowWindow和UpdateWindow函数来实现
窗口显示形式标识 ShowWindow(hwnd , nCmdshow);
应用程序调用ShowWindow函数在屏幕上显示窗口
窗口显示但不激活,窗口不激活情况下是不能操作的,Windows时多任务多窗口的应用程序,当运行程序时,当前激活的窗口只有一个窗口,其余则是后台运行状态。
显示窗口后,应用程序调用UpdateWindows更新并绘制用户区并发出WM_PAINT消息
消息循环
Windows将产生的消息放到一个消息队列去,然后WinMain函数是将消息传递给窗口处理函数WndProc函数进行相应的处理
MSG Msg;
...
while(GetMessage (&Msg,NULL,0,0))
{TranslateMessage(&Msg);//将消息的虚拟键转换为字符信息
DispatchMessage(&Msg);//将消息传递到指定窗口函数
}
GetMessage
(lpMSG, //指向MSG结构的指针
hwnd, //从哪一个窗口获得消息
nMsgFilteMin, //用于消息过滤的最小信号值,也就是说,消息有个编号,编号有个区间,用来过滤这个区间是否是合理的消息。它要完成的就是从消息队列中读取一条消息get message,然后给它放到这个message结构中
nMsgFilterMax //用于消息过滤的最大信号值)
函数窗口的一般形式
LRESULT CALLBACK WndProc
(HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam)
{...
switch(message) //message为标识的信息
{case...
...
break;
...
case WM_DESTROY:
PostQuitMessage(0);
default:
return DefWindowProc
(hwnd,
message,
wParam,
lParam);//为未定义处理过程的消息提供缺省处理
}
return (0);
}
比如说WndProc WndProc的这个是消息处理函数,针对的哪一个窗口的消息,这里有个窗口的句柄,传过来的什么消息是message以及消息的字参数和长字参数, 那么这个switch就看这个地方传过来的消息,放到这个message,然后对这个message进行判断 。满足哪一个case那么就对这个case里面就响应相应的message操作。
可能是鼠标左键操作 可能是鼠标右键操作等等等等,这些都是属于消息 都是放到message里面。
那么这里面有一个特殊的消息就是DESTROY,遇到这个DESTROY消息就是退出消息循环,还有一个是Default消息缺省的DefWindowProc也是四个参数
跟这个WndProc的一样,为什么会有DefWindowProc?也就是说你这里如果定义了鼠标左键操作、鼠标右键操作、 单击鼠标、 双击鼠标以及键盘的ABCDE操作。比如说你响应的这五个键盘消息,这时候用户操作出错,他按了一个K键,好了, 那么这个K键肯定也是作为一个消息要传过来的,传过来你系统要怎么处理这个消息,大家知道switch-case构架里面都有一个Default 这个缺省操作。那么这时候缺省的操作的话,我们在学习C程序设计的时候,可能你会做的一个Default操作很简单就是break
就是不管它 不处理,但是在我们这个面向对象程序设计里面,它是这样的 它是用的DefWindowProc的
就是前面处理不了的操作 都在这里面操作,那这里面怎么操作、操作了什么 用户不要管它,你只要把这一行写上就行了。
它实际上做的事情就是过滤掉前面那个case里面没有列出来的消息
它都给它过滤掉了 也是不处理,在消息处理程序当中一般都有这个DESTROY这个消息,它 用来关闭窗口,这时候它在应用程序中实际上发出了一个QUIT消息 请求了退出,那么它的处理函数是PostQuitMessage。那么根据消息码来决定你是怎么个退出法,那么这个是WndProc构架,WndProc构架大家,程序C语言程序设计如果学得比较扎实的话,对于这个构架实际上是非常容易理解的,那这里面有两个数据类型 LRESULT和CALLBACK,LRESULT消息是一种消息处理结果的返回值的数据类型
它实际上就是一个长整的long,CALLBACK这个是表示这个函数是给系统调用的,有时候我们称为回调函数。