首页 初玩手游 游戏攻略 cs1.5窗口模式 Windows程序绘制窗口的过程

cs1.5窗口模式 Windows程序绘制窗口的过程

更新时间:2024-05-30 2:09:06 分类:游戏攻略 浏览:1

大家好,如果您还对cs1.5窗口模式不太了解,没有关系,今天就由本站为大家分享cs1.5窗口模式的知识,包括Windows程序绘制窗口的过程的问题都会给大家分析到,还望可以解决大家的问题,下面我们就开始吧!

/*------------------------------------

第9个例子RegisterClass.c:注册窗口类

----------------------------------------*/

/**************回调函数**********

LRESULT:返回值,被宏定义为long型

CALLBACK:函数参数进栈顺序(从右到左,反汇编求证)---_stdcall调用约定

4个参数:为MSG结构体的前4个成员变量

**********************************/

LRESULTCALLBACKWndProc(HWND,UINT,WPARAM,LPARAM);//消息回调函数

/***********程序入口**********/

intWINAPIWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,

{//窗口类名---一个以\\\\0结尾字符串数组,用来保存程序名称,

//即注册到操作系统的名称,一般为进程名称!

staticTCHARszAppName[]=TEXT("HelloWin");

//*************1、设计窗口类************

WNDCLASSwndclass;//定义窗口变量

wndclass.style=CS_HREDRAW|CS_VREDRAW;//窗口类型:水平、垂直重绘,即改变窗口大小时自动发送WM_PAINT消息,而不必手动发送。被改变时该类所有窗口重绘

wndclass.lpfnWndProc=WndProc;//窗口处理函数---回调函数的地址

wndclass.cbClsExtra=0;//窗口扩展:预留空间的附加值,此程序没用到

wndclass.cbWndExtra=0;//窗口实例扩展:预留空间的附加值,此程序没用到

wndclass.hInstance=hInstance;//应用程序实例句柄

wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);//装载窗口标题栏图标

wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);//装载窗口鼠标

wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);//背景白色

wndclass.lpszMenuName=NULL;//装载窗口菜单,此处程序没有

wndclass.lpszClassName=szAppName;//窗口类名---程序的名字

//****************2、注册窗口类**************

if(RegisterClass(&wndclass))//成功注册一个窗口类

MessageBox(NULL,TEXT("爱达人---成功注册一个窗口类!"),

szAppName,MB_ICONEXCLAMATION);

//************回调函数——消息处理过程***********

//窗口回调函数,此函数只有声明和定义,没有调用!这说明此函数确实是由操作系统调用的!

LRESULTCALLBACKWndProc(HWNDhwnd,UINTmessage,WPARAMwParam,LPARAMlParam)

窗口总是基于窗口类创建的。窗口类确定了处理窗口消息的窗口过程。

在创建应用窗口之前,必须调用函数RegisterClass来注册窗口类。

LRESULTCALLBACKWndProc(HWND,UINT,WPARAM,LPARAM);//消息回调函数

本例中未作任何消息处理,后面的例题中将会详细介绍

*******************************************************************

LPCTSTRlpszMenuName;//LPCWSTR(Unicode版本)

LPCTSTRlpszClassName;//LPCWSTR(Unicode版本)

*********************************

RegisterClass函数:注册一个窗口类,供以后在对CreateWindow或CreateWindowEx函数的调用中使用。

【注意】如果使用reateWindowEx函数创建创建,相应的需要使用RegisterClassEx注册窗口。但是,如果不需要设置类小图标,则仍然可以使用CreateWindow函数和RegisterClass函数。

constWNDCLASSA*lpWndClass//指向WNDCLASS结构的指针。在将结构传递给函数之前,必须用适当的类属性填充该结构。

ATOM类型为Windows中定义的新数据类型,其即unsignedshort类型,在<WinDef.h>中的定义如下:

如果函数成功,返回值是唯一标识已注册的类的一个原子;如果函数失败,返回值为0。若想获得更多错误信息,请调用GetLastError函数。

运行结果:注册成功后,返回值非0,弹出一个对话框。

毫无疑问,仅仅只是注册窗口类是无法完成窗口队的创建。

【注意】程序中的窗口过程WndProc并未做任何事情,直接返回操作系统。让我们继续进行下一步。

/*-----------------------------------

第10个例子CreateWindow.c:创建、显示和更新窗口---此例尚不能显示窗口

-----------------------------------------*/

/**************回调函数***********/

LRESULTCALLBACKWndProc(HWND,UINT,WPARAM,LPARAM);//消息回调函数

/***********程序入口************/

intWINAPIWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,

staticTCHARszAppName[]=TEXT("HelloWin");//窗口类名

//************1、设计窗口类*************

WNDCLASSwndclass;//定义窗口类结构变量

wndclass.style=CS_HREDRAW|CS_VREDRAW;//窗口风格

wndclass.lpfnWndProc=WndProc;//窗口过程---回调函数的地址

wndclass.cbClsExtra=0;//窗口扩展:预留空间的附加值,此程序没用到

wndclass.cbWndExtra=0;//窗口实例扩展:预留空间的附加值,此程序没用到

wndclass.hInstance=hInstance;//应用程序实例句柄

wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);//装载窗口标题栏图标

wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);//装载窗口鼠标

wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);//初始化窗体背景(白色画刷)

wndclass.lpszMenuName=NULL;//装载窗口菜单(此处程序没有菜单)

wndclass.lpszClassName=szAppName;//窗口类名---程序名

/***************2、注册窗口类*********/

if(!RegisterClass(&wndclass))//返回值为0,未成功注册

MessageBox(NULL,TEXT("注册失败!"),

szAppName,MB_ICONEXCLAMATION);

/*************3、创建窗口******************/

hwnd=CreateWindow(szAppName,//已注册的窗口类名

TEXT("我的第一个窗口程序!"),//窗体标题

WS_OVERLAPPEDWINDOW,//窗体风格(重叠窗口、标题栏和边框

CW_USEDEFAULT,//窗体左上角x坐标

CW_USEDEFAULT,//窗体左上角y坐标

NULL//指向一个值的指针,该值传递给窗口WM_CREATE消息

/*创建窗口完成(只存在于内存中),系统会发送第一条消息WM_CREATE,注意此时,程序并未执行到消息循环处,操作系统绕过应用程序的消息队列,直接将WM_CREATE消息发送给窗口过程。该消息在所有的消息之前,目的是为了在程序程序执行之前可以有机会进行一些初始化工作或装载动态链接库等操作。

A)CreateWindow的第一个参数就是窗口类名,通过这个名字可以找到刚才注册的窗口类,然后再根据它来创建窗口。

B)显示器上的坐标与数学中的不同,显示器的左上角是坐标原点,从原点向右是x轴,向下是y轴,都是正坐标,没有负数。

C)参数hInstance是通过主函数WinMain传入的。

【注意】通过CreateWindows()函数创建窗口后,仅仅是为窗口分配了内存空间,获得了句柄,但窗口并没有显示出来,所以还需要调用ShowWindow()函数来显示窗口。

/*******************4、显示窗口和更新窗口**************/

ShowWindow(hwnd,nCmdShow);//发送WM_SIZE和WM_SHOWWINDOW消息送入消息队列

/*1、单纯一个ShowWindow,照样会正确绘制出窗口内容,只不过是在消息队列取空之后才绘制的,有时我们希望窗口被立即重画,而不是去等待那个不确定的消息队列,此时就需要用到UpdateWindow。UpdateWindow的作用只有一个:假若当前存在被标记为重绘的区域(即无效区域,如果其不存在的话它什么也不做),那么立刻让Windows使用SendMessage的方式来对你的窗口发送WM_PAINT。

2、ShowWindow本身并不发送重绘消息,它的作用仅仅是把窗口显示出来。

所以还需要调用UpdateWindow()函数,生成VM_PAINT消息,将客户区中的各种控件绘制出来。不过,当窗口显示的时候,Windows会自动探测窗口的内容是否需要重绘、以及需要重绘的区域。

3、ShowWindow调用中会发送WM_SIZE和WM_SHOWWINDOW消息给窗口过程。

4、第一次调用和以后的调用是有区别的。第一次调用时,它的输入参数nCmdShow是需要输入WinMain函数里传入来的nCmdShow参数,而不能是其它参数。在此以后就不再需要nCmdShow参数了。

UpdateWindow(hwnd);//发送WM_PAINT消息给窗口过程

/*执行UpdateWindow时会立即发送一条WM_PAINT消息,同样由操作系统直接发出。UpdateWindow执行时,先判断无效区域是否为空,不为空,则发送WM_PAINT消息,为空为不发送。可见,将上面的ShowWindow注释掉,则不发送。因为未显示出来,当然没有无效区域,即无效区域为空。

/*UpdateWindow和In?v?a?l?i?d?a?t?e?的区别:

1、UpdateWindow()的作用是使窗口立即重绘(因为操作系统绕过应用程序的消息队列,直接给窗口过程发WM_PAINT消息,从而导致窗口立即重绘。

而Invalidate等函数(功能为使整个客户区无效)调用后窗口不会立即重绘,这是由于WM_PAINT消息的优先级很低,它需要等消息队列中的其它消息发送完后才能被处理。

2、UpdateWindow执行时,先判断无效区域是否为空,不为空才发送消息,Invalidate的无效区为整个客户区(注意与InvalidRect函数(功能为使指定的区域无效)的区别)

//**********回调函数——消息处理过程***********

//窗口过程回调函数,这里只有声明和定义,直接返回!这说明此函数确实是由操作系统调用的!

LRESULTCALLBACKWndProc(HWNDhwnd,UINTmessage,WPARAMwParam,LPARAMlParam)

CreateWindow函数:创建一个重叠窗口,弹出窗口或子窗口。它指定窗口类,窗口标题,窗口样式,以及(可选)窗口的初始位置和大小。

该函数还指定窗口的父级或所有者(如果有)以及窗口的菜单。

要使用CreateWindow支持的样式以及扩展窗口样式,请使用CreateWindowEx函数。

dwStyle,//指定创建窗口的风格。

lpParam//指向一个值的指针,该值传递给窗口WM_CREATE消息。

*******************************

ShowWindow函数:该函数设置指定窗口的显示状态。

返回值:如果窗口之前可见,则返回值为非零。如果窗口之前被隐藏,则返回值为零。

********************************

UpdateWindow函数:如果窗口的更新区域不为空,则UpdateWindow函数通过向该窗口过程发送WM_PAINT消息来更新指定窗口的客户区。

该函数绕过应用程序消息队列,直接将WM_PAINT消息发送到指定窗口的窗口过程。如果更新区域为空,则不发送消息。

1.细心的读者可能会注意到,我们在初始化窗口类时已经给出了窗口风格,为何在调用CreateWindow函数创建窗口时还要再次给出窗口风格呢?

这是因为,一个窗口类可以创建多个窗口,每个窗口都可以有属于自己的独特风格,这样设计更灵活。

2.还有一个重复项,初始化窗口类时给定了窗口菜单,CreateWindow函数同样也有一个参数是菜单句柄。道理是相同的,如果该窗口类只创建了一个窗口,绑定菜单可以在初始化窗口类时进行,也可以在调用CreateWindow时进行。假设一个窗口类需要创建多个窗口时,则每个窗口都可以绑定不同的菜单。

3.虽然此例程已经创建窗口、显示窗口和更新窗口,但新创建的窗口仅存在于内存中,并未真正显示出来。执行CreateWindow函数后,会产生程序的第一个消息WM_CREATE。只有当Windows系统将WM_CREATE消息直接发送给窗口过程WndProc并处理之后,才会真正在屏幕显示窗口。

4.【注意】注释中解释了显示窗口的四个不同函数的区别:ShowWindow、UpdateWindow、Invalidate、InvalidRect。其中执行ShowWindow函数会产生两个消息WM_SIZE和WM_SHOWWINDOW并送入窗口消息队列。执行UpdateWindow函数会产生WM_PAINT消息无需送入窗口消息队列,而是直接交给窗口过程,立即更新窗口。

【注】此时,由于窗口过程尚未处理任何消息,屏幕仍无法显示窗口。

/*------------------------------------

第11个例子GetMessage.c:消息循环

TranslateMessage函数:将虚拟键消息转换为字符消息

DispatchMessage函数:分发一个消息给窗口程序

---------------------------------------*/

/***********回调函数*********************/

LRESULTCALLBACKWndProc(HWND,UINT,WPARAM,LPARAM);//消息回调函数

/***********程序入口***************/

intWINAPIWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,

staticTCHARszAppName[]=TEXT("HelloWin");//窗口类名

/***********1、设计窗口类*******************/

WNDCLASSwndclass;//定义窗口类变量

wndclass.style=CS_HREDRAW|CS_VREDRAW;//窗口风格

wndclass.lpfnWndProc=WndProc;//窗口处理函数---回调函数的地址

wndclass.cbClsExtra=0;//窗口扩展:预留空间的附加值,此程序没用到

wndclass.cbWndExtra=0;//窗口实例扩展:预留空间的附加值,此程序没用到

wndclass.hInstance=hInstance;//应用程序实例句柄

wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);//装载窗口标题栏图标

wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);//装载窗口鼠标

wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);//背景色

wndclass.lpszMenuName=NULL;//装载窗口菜单,此处程序没有

wndclass.lpszClassName=szAppName;//窗口类名---程序名

/**********2、注册窗口类**************/

if(!RegisterClass(&wndclass))//未成功注册

MessageBox(NULL,TEXT("注册失败!"),szAppName,MB_ICONEXCLAMATION);

/**************3、创建窗口类************/

hwnd=CreateWindow(szAppName,//已注册窗口类名

TEXT("我的第一个窗口程序!"),//窗体标题

WS_OVERLAPPEDWINDOW,//窗体风格

CW_USEDEFAULT,//窗体左上角x坐标

CW_USEDEFAULT,//窗体左上角y坐标

/**************4、显示窗口和更新窗口*************/

ShowWindow(hwnd,nCmdShow);//发送WM_SIZE和WM_SHOWWINDOW消息送入消息队列

UpdateWindow(hwnd);//发送WM_PAINT消息给窗口过程

/**************5、消息循环***************/

/*1、调用GetMessage函数时,传入msg的地址,从窗口消息队列中获取消息,其中的消息结构的内容由操作系统自动填充。

2、这是windows程序的核心,消息循环处理过程,只有在收到WM_QUIT时才退出消息循环,结束程序。

while(GetMessage(&msg,NULL,0,0))

TranslateMessage(&msg);//将虚拟键消息转换为字符消息

DispatchMessage(&msg);//发送消息函数,先把msg发送给操作系统,

//然后由操作系统再调用Wndproc函数!

//Dispatch函数的内部实现大体流程

//callWndProc(...)//调用窗体回调函

returnmsg.wParam;//msg.wParam来自一条表示退出的消息,返回这个值给系统

/**********回调函数——消息处理过程***********/

//窗口回调函数,只有声明和定义,直接返回!这说明此函数确实是由操作系统调用的!

LRESULTCALLBACKWndProc(HWNDhwnd,UINTmessage,WPARAMwParam,LPARAMlParam)

HWNDhwnd;//消息所指向的窗口的句柄

UINTmessage;//每条消息在头文件WINUSER.H中都定义了一个以WM为前缀的消息标识符,如按下鼠标左键WM_lbuttondown。

WPARAMwParam;//一个32为的“消息参数”,该参数的含义和取值取决于具体的消息

LPARAMlParam;//一个32位的消息参数,该参数的含义和取值同样取决于具体的消息

DWORDtime;//消息进入消息队列的时间

POINTpt;//消息进入消息队列中时鼠标指针的位置坐标

}MSG,*PMSG,NEAR*NPMSG,FAR*LPMSG;

*****************************************

GetMessage函数:从调用线程的消息队列里取得一个消息并将其放于指定的结构。

_Out_LPMSGlpMsg,//指向MSG结构的指针,该结构从线程的消息队列接收消息信息

_In_opt_HWNDhWnd,//想获取哪个窗口的消息,为NULL时是获取所有窗口的消息

_In_UINTwMsgFilterMin,//获取消息的ID编号最小值,如果小于这个值就不获取

_In_UINTwMsgFilterMax);//获取消息的ID编号最大值,如果大于这个值就不获取

如果wMsgFilterMin和wMsgFilterMax都为零,则GetMessage返回所有可用消息(即,不执行范围过滤)。

__in:输入参数;__out:输出参数;__in_opt:可选的输入参数,返回后不会改变其值。

**************************************

TranslateMessage函数:将虚拟键消息转换为字符消息。字符消息将发布到调用线程的消息队列中,以在线程下次调用GetMessage或PeekMessage函数时读取。

constMSG*lpMsg//指向MSG结构的指针,该结构包含通过使用GetMessage或

//PeekMessage函数从调用线程的消息队列中检索到的消息信息。

*************************************

DispatchMessage函数:将消息调度到窗口过程。它通常用于调度由GetMessage函数检索的消息。

constMSG*lpMsg//指向包含消息的结构的指针。

消息循环是Windows程序的核心,主程序中使用一个while循环结构不间断的从窗口消息队列中获取消息,GetMessage函数获取到WM_QUIT标记后返回0,退出消息循环。如果获取的是其它消息,则交给TranslateMessage函数和DispatchMessage函数处理。如果从窗口消息队列中获取的是键盘按键消息WM_KEYDOWN,则通过TranslateMessage函数将键盘消息的虚拟键码翻译字符并转换成WM_CHAR消息后分发给操作系统,再次送入消息队列。如果获取的是非WM_KEYDOWN消息,则直接交给DispatchMessage函数分发给Windows操作系统,Windows操作系统再回调窗口过程处理消息。

【注】此时,由于窗口过程尚未处理任何消息,屏幕仍无法显示窗口。

/*---------------------------------------

第12个例子WndProc.c:处理消息机制---窗口过程

注意:关闭窗口后,程序仍然没有退出。

---------------------------------------*/

/*************回调函数************/

LRESULTCALLBACKWndProc(HWND,UINT,WPARAM,LPARAM);//消息回调函数

/*************程序入口*****************/

intWINAPIWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,

staticTCHARszAppName[]=TEXT("HelloWin");//窗口类名

/*****************1、设计窗口类*********/

WNDCLASSwndclass;//定义窗口类变量

wndclass.style=CS_HREDRAW|CS_VREDRAW;//窗口风格

wndclass.lpfnWndProc=WndProc;//窗口处理函数---回调函数的地址

wndclass.cbClsExtra=0;//窗口扩展:预留空间的附加值,此程序没用到

wndclass.cbWndExtra=0;//窗口实例扩展:预留空间的附加值,此程序没用到

wndclass.hInstance=hInstance;//应用程序实例句柄

wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);//装载窗口标题栏图标

wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);//装载窗口鼠标

wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);//背景色

wndclass.lpszMenuName=NULL;//装载窗口菜单,此处程序没有

wndclass.lpszClassName=szAppName;//窗口类名---程序的名字

/**************2、注册窗口类********/

if(!RegisterClass(&wndclass))//未成功注册

MessageBox(NULL,TEXT("注册失败!"),szAppName,MB_ICONEXCLAMATION);

/*************3、创建窗口***************/

hwnd=CreateWindow(szAppName,//已注册的窗口类名

TEXT("我的第一个窗口程序!"),//窗体标题

WS_OVERLAPPEDWINDOW,//窗体风格

CW_USEDEFAULT,//窗体左上角x坐标

CW_USEDEFAULT,//窗体左上角y坐标

/*创建窗口完成(只存在于内存),系统会发送第一条消息WM_CREATE,注意此时,程序并未执行到消息循环处,操作系统绕过应用程序的消息队列,直接向应用程序发出。该消息在所有的消息之前,目的是为了在程序程序执行之前可以有机会进行一些初始化工作或装载动态链接库等操作。

A)CreateWindow的第一个参数就是窗口类名,通过这个名字可以找到刚才注册的窗口类,然后再根据它来创建窗口。

B)显示器上的坐标与数学中的不同,显示器的左上角是坐标原点,从原点向右是x轴,向下是y轴,都是正坐标,没有负数。

C)参数hInstance是通过主函数WinMain传入的。

【注意】通过CreateWindows()函数创建窗口后,仅仅是为窗口分配了内存空间,获得了句柄,但窗口并没有显示出来,所以还需要调用ShowWindow()函数来显示窗口。

/****************4、显示窗口和更新窗口************/

ShowWindow(hwnd,nCmdShow);//发送WM_SIZE和WM_SHOWWINDOW消息送入消息队列

UpdateWindow(hwnd);//发送WM_PAINT消息给窗口过程

/****************5、消息循环***************/

while(GetMessage(&msg,NULL,0,0))

TranslateMessage(&msg);//将虚拟键消息转换为字符消息

DispatchMessage(&msg);//分发消息函数

returnmsg.wParam;//msg.wParam来自一条表示退出的消息,返回这个值给系统,从而退出

/************************回调函数——消息处理过程****************************/

LRESULTCALLBACKWndProc(HWNDhwnd,UINTmessage,WPARAMwParam,LPARAMlParam)

{//创建窗口消息,此消息是一个应用程序发送的第一个消息,也是唯一的一次!

//调用默认窗口过程以为应用程序未处理的任何窗口消息提供默认处理

returnDefWindowProc(hwnd,message,wParam,lParam);

//returnDefWindowProc(hwnd,message,wParam,lParam);//默认窗口过程

/***************注意******************

1:所有的消息都由操作系统负责管理,所有的消息先进入总的系统消息队列,再由系统消息队列分发给各个窗口消息队列!

2:窗口回调函数Wndproc是由操作系统调用的,所有的队列消息进入消息循环,由消息循环把消息分发给操作系统,再由操作系统调用窗口过程Wndproc函数,而Wndproc窗口过程根据message的不同而调用相应的处理过程!如果是非队列消息则由操作系统直接交给窗口过程。窗口过程即回调函数,在switch语句中使用message参数,其中各个消息由单独的case语句处理。

请注意,每种情况都会为每个消息返回一个特定的值。对于未处理的消息,窗口过程将调用操作系统默认的窗口过程DefWindowProc函数处理。

3:上面这个程序可以改造一下,再添加几个消息处理过程,比如鼠标左键按下WM_LBUTTONDOWN,鼠标左键抬起WM_LBUTTONUP定时器消息WM_TIMER,绘图消息WM_PAINT消息等等。我们将注意测试每个消息!

4:其实,WINDOWS程序也可以自己去创建函数!自己去自定义消息处理过程!比如,自己定义了一个函数,想在鼠标左键点击后去调用这个函数,那就可以在WM_LBUTTONDOWN这个消息处理过程中加上自己定义的函数调用就可以了!

5:上面这个程序是个非常简单的程序,但是他足以说明WINDOWS程序的消息机制!几乎所有的程序都包括上面这段代码。不管多么复杂的WINDOWS程序都必须包括上面这段代码,因为他是再简单不过的了,只是创建了一个窗口!

但是,再复杂的程序无非也就是在Wndproc函数中的switch多加几个case嘛!无非就是加上什么鼠标,键盘,定时器等等,但原里都是一样的!他的消息处理过程都是一样的!主要是把他的消息机制弄懂,其它的都非常easy!

*******************************/

WM_CREATE消息:当应用程序通过调用CreateWindowEx或CreateWindow函数请求创建窗口时发送。(在函数返回之前发送消息。)

在创建窗口之后,但在该窗口变为可见之前,新窗口的窗口过程会收到此消息。窗口通过其WindowProc函数接收此消息。

指向CREATESTRUCT结构的指针,该结构包含有关正在创建的窗口的信息。

如果应用程序处理此消息,则应返回零以继续创建窗口。如果应用程序返回–1,则窗口将被销毁,并且CreateWindowEx或CreateWindow函数将返回NULL句柄。

*******************************************

DefWindowProc函数:调用Windows操作系统默认的窗口过程来为应用程序没有处理的任何窗口消息提供转换的处理。该函数确保每一个消息得到处理。

绝大多少消息都是由DefWindowProc函数按照默认的方式处理。

HWNDhWnd,//接收到消息的窗口过程的句柄。

WPARAMwParam,//附加消息信息。此参数的内容取决于Msg参数的值。

LPARAMlParam//附加消息信息。此参数的内容取决于Msg参数的值。

返回值类型:LRESULT。返回值是消息处理的结果,并取决于消息。

1.窗口过程是一个回调函数,Windows操作系统将消息参数传递给WndProc窗口过程处理消息。窗口过程内是一个switch结构,根据message消息ID使用case语句处理。本例caseWM_CREATE:语句块中什么都没有处理,直接return0返回操作系统,我们创建的窗口就在屏幕上显示出来了。

2.WM_CREATE消息是Windows程序产生的第一个消息,也是唯一一次产生的消息。通常我们在处理WM_CREATE消息时做一些窗口的初始化工作,例如添加子窗口。

3.细心的读者会发现,当我们点击窗口右上角系统菜单关闭窗口后,程序仍然没有退出,这是怎么回事呢?是否还记得,我们讲解消息循环时,只有当GetMessage函数获取WM_QUIT标记时才会结束消息循环,退出程序。因此,虽然我们关闭了窗口,但是消息循环仍然在运行,等待获取新的窗口消息。

4.动手实验:为了加深映像,理解Windows程序的消息驱动机制,请读者在caseWM_CREATE:处下一个断点,然后单步跟踪程序的运行,观察程序执行的流程。我们会惊讶的发现,Windows程序并不是按照代码的先后顺序执行的,这与我们之前学习的面向过程的C语言或汇编语言程序完全不同。当我们处理WM_CREATE消息return0返回后,返回到了窗口过程的结尾,然后跳转到CreateWindow函数,接着执行ShowWindow函数后,屏幕出现窗口。这也证明了Windows程序是跟着消息传递的顺序执行的。我们看到的Windows程序仅仅是浮出水面的冰山一角。在后面的学习中,希望读者能够多做一些这样的实验,体会消息驱动机制。

5.【注意】switch结构的语法,DefWindowProc函数可以放在default语句后,也可以直接放到return语句后。如果将DefWindowProc函数放置在return语句后,则case语句中可以直接使用return0;返回。

关于cs1.5窗口模式和Windows程序绘制窗口的过程的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。

版权声明: 本站内容部分来源网络,版权归作者所有,如有侵权,请联系我们删除!
相关文章
金山移动办公软件「V1.5」下载 金山移动办公软件下载 商务办公
导语:随着移动办公的兴起,越来越多的人开始关注如何高效地处理工作事务。金山移动办公软件“V1.5”的推出为我们提供了解决方案。它不仅可以帮助我们更方便地处理日常工作, 它还具有强大的功能和特性,使我们能够更高效地完成任务。让我向你介绍这个软件。 一、金山移动办公软件的介绍 金山移动办公软件是由国内知名软件公司金山软件开发的移动办公应用程序。它集成了文字、表格和演示等各种功能模块。 它可以满足用户在…
cw228 2024-05-30 02:19:07
流浪星球「V1.5」下载  流浪星球下载 生活服务
导语:大家好,今天我要为大家介绍一款备受关注的游戏软件——流浪星球「V1.5」下载 流浪星球下载。这款游戏备受玩家们的喜爱,今天我将带您一起来了解它的特色和亮点。一、流浪星球的介绍流浪星球是一款由国内知名游戏开发商研发的科幻题材冒险游戏。在这个虚拟的宇宙世界中,玩家可以探索各种未知的星球、遇见各种奇特的生物,并通过完成任务和挑战来提升自己的等级和能力。游戏采用了精美细致的3D画面,让玩家仿佛置身…
cw228 2024-05-30 02:18:06
诛仙人物名字生成器  诛仙人物命名工具 商务办公
导语:在游戏世界中,一个好听的人物名字往往能让玩家更容易记住和喜欢上这个角色。而对于玩家来说,起一个独特的名字也是一种展示自己个性的方式。但是,有时候我们可能会遇到起不出好听的名字或者想要更符合游戏背景的情况。这时候,诛仙人物名字生成器 诛仙人物命名工具就能帮助我们解决这个问题。一:诛仙人物名字的介绍诛仙是一款受欢迎的网游,它以古代神话故事为背景,讲述了一个关于修真者的奇幻冒险故事。在游戏中,玩…
cw228 2024-05-30 02:17:06
竞速赛车游戏 游戏测评
大家好,我是游戏博主,今天要为大家介绍的是一款刺激好玩的竞速赛车游戏。这款游戏拥有精美的画面和流畅的操作,让玩家仿佛置身于真实的赛车场上。接下来,就让我带你一起来探索这款游戏吧!首先,让我们来了解一下这款竞速赛车游戏的玩法。在游戏中,玩家将扮演职业选手参加各种不同类型的赛车比赛。通过不断地挑战和提升自己的驾驶技术,最终成为顶尖的赛车冠。除了单人模式外,游戏还提供多人在线对战模式,可以与全球其他玩…
hh 2024-05-30 02:16:05
音悦mini「V1.2」下载  音悦mini下载 商务办公
线索: 银月迷你是一款流行的手机音乐游戏软件,它为用户提供了多种音乐游戏,使用户可以在轻松愉快的氛围中享受音乐带来的快乐。现在,最新版本的银月迷你「V1.2」已经发布。 让我们来看看这个软件。 一:音悦mini的介绍 银月迷你版是一款专为手机用户设计的音乐游戏软件。它拥有大量的歌曲资源和多样化的播放方式,使用户可以随时随地播放它。它不仅提供经典流行歌曲,还提供最新流行歌曲和原创歌曲供用户选择。 同…
cw228 2024-05-30 02:15:06
深海大冒险「V1.3」下载  深海大冒险下载 策略游戏
导语:大家好,今天我要为大家介绍一款新鲜刺激的游戏——深海大冒险。这款游戏以其精美的画面、创新的玩法和丰富的内容受到了广大玩家的喜爱。现在,最新版本「V1.3」已经上线,让我们一起来看看这款游戏都有哪些亮点吧!一:深海大冒险的介绍深海大冒险是一款由知名游戏开发商开发的冒险类游戏。在这个游戏中,玩家将扮演一名勇敢的潜水员,在神秘的深海中探索未知的领域。玩家需要收集资源、建造设施、钓鱼捕鱼、与海洋生…
cw228 2024-05-30 02:14:07
快乐酷宝2「V1.3」下载  快乐酷宝2下载 影音应用
导语:随着智能手机的普及,移动游戏已经成为人们生活中不可或缺的一部分。而在众多的移动游戏中,快乐酷宝2「V1.3」无疑是一款备受欢迎的游戏。它拥有精美的画面、丰富多彩的玩法和流畅的操作体验,深受广大玩家的喜爱。现在,快乐酷宝2「V1.3」已经可以免费下载啦!让我们一起来看看这款游戏有什么特色吧!一:快乐酷宝2的介绍快乐酷宝2是一款休闲益智类游戏,由知名游戏开发商开发并推出。该游戏采用了Q版卡通风…
cw228 2024-05-30 02:13:06
哈喽姐妹们,我是游戏里的清纯小G。我是一位热爱游戏的峡谷先锋,性格活泼开朗,爱玩。这就是这款游戏能让我着迷和着迷的地方。我想只有这样我才能深深地享受它!欢迎兄弟姐妹们阅读留言! 富豪世界怎么玩?如何快速升级?余额宝小编带来了财富世界攻略,一起来看看吧。 富甲天下攻略 1、总体选型 1、初期武将建议选择吕布和貂蝉,因为这两个增加攻速,属性也不错; 2.前期可以先培养一个高攻武将,这样打副本会更轻松;…
cw228 2024-05-30 02:12:05
宾果消消乐下载,宾果消消乐(安卓版)下载 动作格斗
宾果消消乐是一款休闲益智类的手机游戏,它的游戏规则简单易懂,玩法多样,受到了广大玩家的喜爱。现在,它也推出了安卓版下载,让更多的用户能够轻松畅玩。 特色: 1.简单易上手:宾果消消乐的游戏规则非常简单,只需要通过交换两个相邻的水果来消除三个或以上相同水果即可得分。操作简单,上手容易。 2.多样玩法:游戏中有多种关卡和挑战模式可供选择,每一种模式都有不同的难度和挑战性。同时还有各种道具和技能可以帮…
cw228 2024-05-30 02:11:06
暗黑2补丁下载  暗黑2「V1.3」补丁更新 策略游戏
导语:作为暗黑2的忠实粉丝,相信大家都知道这款游戏的经典之处。而今天,我们将要介绍的就是暗黑2最新的补丁更新——「V1.3」补丁。这次更新主要针对游戏中的BUG和平衡性进行了优化,让游戏更加流畅、稳定,同时也为玩家带来更多全新的内容。让我们一起来看看这次更新究竟有哪些特色和亮点吧!一:暗黑2补丁的介绍「V1.3」补丁是暗黑2最新推出的一款补丁更新,它主要针对游戏中出现的各种BUG和平衡性问题进行…
cw228 2024-05-30 02:10:06