我是靠谱客的博主 贪玩薯片,最近开发中收集的这篇文章主要介绍 Windows内部运行机制,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

 

1.API与SDK

api是windows操作系统提供给应用程序编程的接口(Application Proramming Interface)简称api函数,windows有1000多种api函数。

sdk全称是Software Development Kit,中文译为软件开发包。例如:购买语音卡的同时,厂商就会提供语音卡的sdk,这个sdk通常包含语音卡的api函数库、帮助文档、使用手册、辅助工具等资源。

2.句枘

句柄(HANDLE)是Windows程序中一个重要的概念,使用非常频繁。在windows程序中,有各种各样的资源(窗口、图标、光标等),系统在创建这些资源会为它们分配内存,并返回标识这些资源的标识号,即句柄。

例窗口句枘(HWND)、图标句柄(HICON)、光标句柄(HCURSOR)、画刷句柄(HBRUSH)

 

3.消息

windows程序设计是一事件驱动方式的程序设计模式,主要是基于消息的。

在windows程序中,消息是由MSG结构体来表示的。MSG结构体定义如下

typedef struct tagMSG {

HWND  hwnd;

//消息所属的窗口

 

UINT   message;

//消息的标识符,消息由数值表识的不便记忆,所以定义为宏WM_XXX(WM是windows message的缩写)XXX对定消息英文大写,例如鼠标左键按下消息WM_LBUTTONDOWN,键盘按下消息WM_KEYDOWN,字符消息就是WM_CHAR。

 

WPARAM wParam;

LPARAM lParam;

//wParam和lParam用于指定消息的附加信息。例如收到一个字符消息时,message的成员变量就是WM_CHAR,但用户到底输入的到底什么字符,就由wParam和lParam来说明。

 

DWORD  time;

//消息投递到消息队列的时间。

 

POINT  pt;

//鼠标的当前位置。

} MSG;

4.消息队列

每一个windows应用程序开始执行后,系统都会为该程序创建一个消息队列,这个消息队列用来存放该程序创建的窗口的消息。

当消息投放到消息队列中后,应用程序则通过一个消息循环不断地从消息队列中取出消息,并进行响应。这种消息机制,就是windows程序运行的机制。

5.进队消息和不进队消息

进队消息将由系统放入到应用程序的消息队列中,然后由应用程序取出并发送。不进队消息在系统调用窗口过程时直接发送给窗口。不管是进队消息还是不进队消息,最终都由系统调用窗口过程函数对消息进行处理。

6.WinMain函数

当Windows操作系统启动一个程序时,它调用的就是该程序的WinMain函数(实际是由插入到可执行文件中的启动代码调用的)。WinMain是Windows程序的入口点函数。当WinMain函数结束或返回时,Windows应用程序结束。

int WINAPI WinMain(

  HINSTANCE hInstance,

//当前运行实例的句柄

 

HINSTANCE hPrevInstance,

// 当前实例的前一个实例的句柄,在win32环境下,这个参数总是NULL

 

LPSTR lpCmdLine, 

//以空终止的字符串,指定传递给应用程序的命令行参数。

 

int nCmdShow

//指定程序的窗口应该如何显示,例如最大化、最小化、隐藏等。这个参数的值由该程序的调用者所指定,应用程序通常不需要理会这个参数的值。

);

7.窗口的创建过程

1.设计一个窗口类;

2.注册窗口类;

3.创建窗口;

4.显示及更新窗口;

8.窗口类

typedef struct _WNDCLASS {

UINT       style;

//指定这一类型窗口的样式,CS_HREDRAW水平重画,CS_VREDRAW垂直重画,CS_NOCLOSE 禁用Close命令,这将导致窗口没有关闭按钮。CS_DBLCLKS当用户在窗口中双击时,向窗口过程发送鼠标双击消息。CS(Class Style)

WNDPROC    lpfnWndProc;

//函数指针,指向窗口过程函数,窗口过程函数就是一个回调函数。一个Windows程序可以包包含多个窗口过程函数,一个窗口过程总是与某一个特定的窗口相关联(通过本成员变量指定),基于该窗口类创建的窗口使用同一窗口过程。

int        cbClsExtra;

//可以为窗口类分配一个附加的内存空间,由属于这种窗口类的所有窗口所共享,我们一般将这个参数设置为0。

int        cbWndExtra;

//为窗口分配一个附加内存空间,应用程序可以用这部分内存存储窗口的特有的数据。初始化一般为0。如果应用程序用WNDCLASS结构注册对话框(用资源文件中的CLASS伪指令创建)必须给DLGWINDOWEXTRA设置这个成员。

HINSTANCE  hInstance;

//指令包含窗口过程的程序的实例句柄。

HICON      hIcon;

//指定窗口类的图标句柄。如果这个成员为NULL,那么系统提供一个默认的图标。在为hIcon变量赋值时可以调用LoadIcon函数加载一个图标资源,返回一个图标句柄。

HCURSOR    hCursor;

//为光标变量赋值时,可以用LoadCusrsor加载一个光标资源,返回光标句柄。用法同LoadIcon

HBRUSH     hbrBackground;

//指定窗口类的画刷句柄,当窗口发生重绘时,系统使用这里指定的画刷来擦除窗口背景。,既可以指定画刷句柄,也可以指定标准系统颜色值。GetStockObject得到系统标准刷。还可以获取画笔、字体和调色板句柄,因为反回多种资源对像句柄,使用时要根据具体情况,强制转换。

LPCTSTR    lpszMenuName;

//指定菜单资源的名字。如果为NULL那么基于这个窗口类创建的窗口将没有菜单。

LPCTSTR    lpszClassName;

//指定窗口类的名字。

} WNDCLASS;

9.LoadIcon

HICON LoadIcon(HINSTANCE hInstance,LPCTSTR lpIconName)

如果加载的是系统的标准图标,第一个参数为NULL。

10.回调函数

回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外一方调用的,用于对该事件或条件进行响应。

11.回调函数实现机制

1.创建回调函数

2.函数实现一方在初始化时,将回调函数的指外针注册给调用者。

3.当特定的事件或条件发生时,调用函数通过函数指针调用函数对事件进行处理。

 

12.注册窗口类

RegisterClass(CONST WNDCLASS *lpWndClass)

13.创建窗口

HWND CreateWindow(

  LPCTSTR lpClassName, 

//指定一个注册过的窗口类的名字

  LPCTSTR lpWindowName,

//指定一个窗口名字,如果有窗口标题栏,窗口名字将显示在标题栏上

  DWORD dwStyle,     

//指定创建窗口的样式。与窗口类中的style不同,这里的样式,指的是特定某一窗口的样式,窗口类中的样式基于该窗口类创建的窗口都有该样式。

  int x,                // horizontal position of window

//如果被设为CW_USEDEFAULT将默认左上角坐标,忽略y坐标。

  int y,                // vertical position of window

  int nWidth,           // window width

//如果被设为CW_USEDEFAULT将默认窗品宽度,并忽略长度。

  int nHeight,          // window height

  HWND hWndParent,      // handle to parent or owner window

//子窗口必须有WS_CHILD样式。对父窗口的操作影响子窗口。

  HMENU hMenu,          // menu handle or child identifier

//指定窗口菜单句柄。

  HINSTANCE hInstance,  // handle to application instance

//指定窗口所属应用程序实例句柄

  LPVOID lpParam        // window-creation data

//做为WM_CREATE消息的附加参数lParam传入的数据指针。创建多文档界面的客户窗口时,lpParam必须指向CLIENTCREATESTRUCT结构体。多数窗口将这个参数设置为NULL。

);

 

14.显示窗口

调用ShowWindow显示窗口

BOOL ShowWindow(

HWND hWnd,

//调用CreateWindow时返回的句柄

int nCmdShow

//指定窗口显示状态,常用有如下

SW_HIDE:隐藏并激活其他窗口

SW_SHOW:在窗口原来的位置以原来的尺寸激活和显示窗口。

SW_SHOWMAXIMIZED:激活窗口并将其最大化显示。

SW_SHOWMINIMIZED:激活窗口并将其最小化显示。

SW_SHOWNORMAL:激活并显示窗口。如果窗口最小化或或最大化状态,系统将其恢复到原来的尺寸和大小。

);

 

15.更新窗口

调用ShowWindow后紧接着调用UpdateWindow来刷新窗口

BOOL UpdateWindow(

HWND hWnd

);

//此处也是CreateWindows返回的窗口句柄

UpdateWindow函数通过发送一个WM_PAINT消息来刷新窗口。UpdateWindow将WM_PAINT消息直接发送给了窗口过程函数进行处理。此消息并没有放进消息队列。

 

16.消息循环

在创建窗口,显示窗口,更新窗口后,需要一个消息循环,不断地从消息队列中取出消息,并进行响应。

BOOL GetMessage(

  LPMSG lpMsg,         // message information

//指向一个消息结构体,GetMessage从线程的消息队列中取出的消息将保存在该结构体对象中。

  HWND hWnd,           // handle to window

//指定接收属于哪一窗口的消息。通常设置成NULL,用于接收属于调用线程的所有窗口的窗口消息。

  UINT wMsgFilterMin,  // first message

//指定获取消息的最小值,通常设置为0。

  UINT wMsgFilterMax   // last message

//获取的消息的最大值。如果都设置为0将获取所有消息。

);

GetMessage函数接收到除WM_QUIT外的消息均返回非零值。对于WM_QUIT消息,该函数返回零。如果出现错误,如果返回-1。

 

 

BOOL PeekMessage(

  LPMSG lpMsg,         // message information

  HWND hWnd,           // handle to window

  UINT wMsgFilterMin,  // first message

  UINT wMsgFilterMax,  // last message

  UINT wRemoveMsg      // removal options

);

另一种从消息队列中获取消息的方法,唯一不同的是最后多一个参数,当参数是PM_NOREMOVE时,消息不会从消息队列中移除,PM_REMOVE时跟GetMessage一样

发送消息可以使用SendMessage和PostMessage函数。SendMessage将消息发送给窗口,并调用该窗口过程进行处理。在窗口过程对消息处理完毕后,该函数才返回。(SendMessage为不进队消息)。PostMessage函数将消息放入与创建窗口的线程相关联的消息队列后立即返回。PostThreadMessage函数用于向线程发送消息。

17.窗口过程函数

LRESULT CALLBACK WindowProc(

  HWND hwnd,      // handle to window

  UINT uMsg,      // message identifier

  WPARAM wParam,  // first message parameter

  LPARAM lParam   // second message parameter

);

18.DC

设备描述表,Device Context简称DC。DC是一个包含设备(物理输出设备,如显示器,以及设备驱动程序)信息的结构体,在Windows平台下,所有的图形操作都是利用DC来完成的。比如要得到与窗口相关联的DC句柄  HDC hdc=GetDC(hWnd);

19.WM_PAINT

当窗口客户区的一部分或者全部变为”无效时”系统会发送WM_PAINT消息,如果窗口从无到有、改变尺寸、最小化后在恢复、被其它窗口遮盖后再显示时。窗口大小变化是否会发生重绘也取决于在窗口类设计时style是否不水平重绘和垂直重绘。

在响应WM_PAINT消息代码中,要得到窗口的DC,必须调用BeginPaint函数。BeginPaint函数也只能在WM_PAINT消息响应代码中使用,在其他地方,只能使用GetDC。另代,BeginPaint函数得到的DC必须用EndPaint函数匀释放。

20.PostQuitMessage

投放一个WM_QUIT消息到消息队列中函数参数将做为WM_QUIT的wParam一般用做WinMain函数的返回值,GetMessage接到WM_QUIT消息时返回0消息循环结束程序退出。

21.DefWindowProc

此函数调用默认窗口过程,对应用程序没有处理的消息进行默认处理。在编写窗口过程时一般放在default里

 


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/subleo/archive/2009/08/13/4440532.aspx

最后

以上就是贪玩薯片为你收集整理的 Windows内部运行机制的全部内容,希望文章能够帮你解决 Windows内部运行机制所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(44)

评论列表共有 0 条评论

立即
投稿
返回
顶部