啰啰嗦嗦学习VC++_<<WINDOWS程序内部运行原理>>

作者在 2010-03-01 11:41:00 发布以下内容

WINDOWS程序内部运行原理

20092194:15:43(第一次)

API(Application programming interface) 应用程序编程的接口

MSG(message)  消息结构体   

操作系统将每一个事件包装成一个称为消息MSG的结构体传递给应用程序

MSG的结构定义如下:(windows user interface : platform sdk )

Typedef struct tagMSG{

              HWND hwnd;  窗口的句柄  句柄为资源的标识,按类型分为HICON \HCURSOR \HWND \HINSTANCE

              UINT message;      无符号整形具体的消息; 用宏来表示数值WM开头的为宏WM_*

              WPARAM wParam;  整型. 关于消息的附加信息. WM_CHAR消息字符的代码ASCII;

              LPARAM lParam;   ;整型. 关于消息的附加信息. PARAM=PARAMETER参数,参量

              DWORD time;      ;WORD16位的整数DWORD=Double WORD32位整数.指定消息的投递时间.

              POINT pt;          当消息被投递的时候光标太屏幕上的坐标;

}MSG,*PMSG;

POINT为一个结构体定义了点x坐标y坐标

Typedef struct tagPOINT{

              LONG x;

              LONG y;

} POINT,*PPOINT;                                                    结束时间20092194:57:49

200922013:18:04(第二次)

消息:消息本身,特定的消息响应

WINMAN函数

入口点函数类似于CMAN函数

int WINAPI WinMan(

              HINSTANCE hInstance,      //handle to cerrent instance   实例(资源)的句柄,当前运行的句柄;

              HINSTANCE hPrevinstance,  //handle to previous instance  先前实例的句柄,可能为空,兄弟的实例句柄

win32下这个实例总是为空(win982000);

              LPSTR lpCndLine,          //command line  LP->LONG POINTER长指针,ETRING字符串,指向字符

串的指针;类似于CHAR *   命令行参数

              int nCmdSbow              //show state  显示的状态,比如窗口的大小全屏

)   //这个分号在具体的编程过程中是不要的,需要删除掉。

DOS下的MAIN函数可以接收2个参数:ARJcARJv. ARJc用来接受、存放命令行参数的个数,ARJv指针数组用来存放命令行参数,同样的在windows程序当中他也可以接收命令行的参数.

WINAPI Calling convention for system functions.

200922415:10:15(第三次)

窗口的创建。创建一个完整的窗口需要经过下面四个操作步骤:

l         设计一个窗口类;

l         注册窗口类;

l         创建窗口;

l         显示及更新窗口;

1、设计窗口。设计一个窗口就是设计一个窗口类,他是一个结构体

WNDCLASS

Typedef struct _WNDCLASS{     //MSDN--WNDCLASS

UINIT style;   style //(Class Styles=CS)指定一个类的类型,这里是窗口类的类型;OR(|),(&),取反(~),

                       赋值:wndclass.style=CS_HREDRAW | CS_VREDRAW (水平和垂直重画)

WNDPROC lpfnWndProc; 窗口过程。Lp=long pointer.fn=functionProc= procedure用来接收一个函数指针。

回掉函数(lpfnWndProc: Pointer to the window procedure. You must use the

CallWindowProc[回调window进程] function to call the window procedure. For more

information, see WindowProc.)。这里我们会把一个窗口名赋给他(函数名相当于一个

函数的指针),即在设计的时候就确定了一个回调函数,这里给他赋了WinSunProc

这个函数,当然WinSunProc函数具体内容是什么需要程序员自己去编写。

int  cbClsExtra;   windows程序会为每一个类管理一个内部数据结构。类附加内存,通常情况下设为零.=0

                         类额外的一个数据。(附加字节数)

int  cbWndExtra;  windows程序会为每一个窗口管理一个内部数据结构。窗口附加内存,通常情况下也设

置为零。以上两个分配额外的内存,通常我们不需要所以设置为零。(=0)

窗口类额外的一个数据。通常赋值为零表示我们不需要额外的内存,但是如果我们需要则额外的内存空间会自己变为零。这里设置为零就是=0,不同于其他的设置为NULL,因为这里是整数。

HANDLE  hInstance;   代表我们当前程序的实例号。操作系统分配,直接通过WinMain的形参传递过来。

代表了我们当前应用程序的实例号,我们在设计窗口类的时候需要知道他是代表那

个应用程序实例的。从bInstance获得这个程序。

HICON   hIcon;   图标的句柄。用LoadIcon这个函数来赋值 hIcon=LoadIcon(……)

HCURSOR  hCursor; 光标句柄。用LoadCursor这个函数来赋值hCursor=LoadCursor(……)

HBRUSH  hbrBackground;  画刷的句柄,用的是GetStockObject()这么一个函数

LPCTSTR lpszMenuName;  LP=long point(32),CT=constant常量,STR=string.用来设定菜单的名字

可以直接设置为空NULL,如:lpszMenuNam=NULL;

 (如果这个类型不认识可以用data type 这个来查看不是SDK)

LPCTSTR lpszClassName;  设置一个类的名字(注册窗口的时候会用到,窗口设计完成之后需要给窗口取一

个名字。

}WNDCLASS,*PWNDCLASS;

这个函数是系统定义好了格式,我们只需要拿过来用,直接对参数进行赋值。

WindowProc 回调函数,窗口过程函数

LRESULT CALLBACK WindowProc(   //CALLBACK:窗口过程函数前边定义的时候加了一个CALLBACK

                                    #define CALLBACK  _stdcall

                                    CALLBACK就是一个类型的定义

                                    LRESULT就是一个长整型,返回一个结果码。

  HWND hwnd,      // handle to window

  UINT uMsg,      // message identifier

  WPARAM wParam,  // first message parameter

  LPARAM lParam   // second message parameter

);

DefWindowProc回调函数,窗口过程函数

LRESULT DefWindowProc(

  HWND hWnd,      // handle to window

  UINT Msg,       // message identifier

  WPARAM wParam,  // first message parameter

  LPARAM lParam   // second message parameter

);

_stdcall_cdecl这是两种调用的约定,_stdcall标准调用约定,_cdeclc语言的调用约定。标准调用约定也是PASCAL调用约定,dephi就是pascal调用约定。_stdcall_cdecl在参数的传递顺序和堆栈的清除这两个方面有差异。Vc++默认的调用约定选项是_cdecl.需要时要经行定义。也可以通过Project -> Project Settings ->C/C++ ->Calling convention:中选择_stdcall这种方式来设定。

LoadIcon

HICON LoadIcon(

    HINSTANCE hInstance // handle to application instance 应用程序实例的一个句柄。当标准的图标加载的
时候这个参数用空(NULL,

LPCTSTR lpIconName  // name string or resource identifier当第一个参数取值为NULL时第二个参数可以选择

);

如:LoadIcon(NULL,IDI_ERROR)     // ID=identifier

LoadCursor

HCURSOR LoadCursor(

HINSTANCE hInstance,  // handle to application instance 应用程序实例的一个句柄,如果想用一个标准的光标

这个参数需要设置为NULL

LPCTSTR lpCursorName  // name or resource identifier  同样当前一个参数设置为NULL是这个可以选择微

软提供的光标函数。

);

GetStockObject()  获取一个笔、画刷、调色板、的句柄。

HGDIOBJ GetStockObject(

  int fnObject   // stock object type

);

*=(HBRUSH) GetStockObject(WHITE_BRUSH);   // (HBRUSH) 这里是一个强制转换。因为GetStockObject返回的是一个GetStockObject的类型,而hbrBackground定义的为HBRUSH的类型,C++语言是一个强类型语言,对函数的类型要求的很严。强制类型转换必须要有可比性,即两个类型可以转换,这种转换在编译的时候不会报错但是在执行的时候会出现错误。

2、注册。窗口设置完之后需要对其进行注册(向操作系统注册),RegisterClass()窗口的注册函数

RegisterClass

ATOM RegisterClass(

  CONST WNDCLASS *lpWndClass  // class data 窗口类结构体的指针直接用定义的窗口类结构体的变量加上取

地址符&

);

3、创建一个窗口

首先需要定义一个句柄(HWND),利用这个句柄的变量保存我们新创建的窗口的标识。然后利用CreateWindow函数来进行窗口的创建。

HWND hwnd;

Hwnd=CreateWindow(……);

CreateWindow

HWND CreateWindow(

  LPCTSTR lpClassName,  // registered class name

VC++ | 阅读 1749 次
文章评论,共0条
游客请输入验证码