- UID
- 66114
注册时间2010-4-1
阅读权限30
最后登录1970-1-1
龙战于野
TA的每日心情 | 慵懒 2019-3-12 17:25 |
---|
签到天数: 3 天 [LV.2]偶尔看看I
|
本帖最后由 whypro 于 2010-5-28 17:51 编辑
像大多数教程一样,我们需要了解一下Windows的SDK编程方式,刚刚突然萌生了一个不成熟的想法,不知道对不对,大家应该对控制台下的编程有了一些概念,SDK的编程方式就好像是控制台下的C,没有封装(或者说封装稍微少一些),而MFC的编程方式就好像是控制台下的C++,动不动就来个类,来个对象,来个虚函数,+_+。
所以我们有必要把SDK的编程方式搞清楚,把SDK下的窗口创建自己实现一遍。
先来一个最简单的SDK程序,显示一个HelloWorld的MessageBox (MessageBox是一个API的名字,API全称为:Application Programming Inte**ce,即:应用编程接口,我将在下边进行详细说明)。
#include <windows.h>
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow
)
{
MessageBox(NULL,L"dd",L"dddd",MB_OK);
return 0;
}
首先是头文件,我们注意到SDK和控制台下的编程包含的头文件是不一样的,百度百科上边这样说:
WINDOWS.H是主要的含入档案,它包含了其他Windows表头档案,这些表头档案的某些也包含了其他表头档案。这些表头档案中最重要的和最基本的是:
WINDEF.H 基本型态定义。
WINNT.H 支援Unicode的型态定义。
WINBASE.H Kernel函式。
WINUSER.H 使用者介面函式。
WINGDI.H 图形装置介面函式。
这些表头档案定义了Windows的所有资料型态、函式呼叫、资料结构和常数识别字,它们是Windows文件中的一个重要部分。
如此看来,windows.h这个头文件包含了我们编程的一些基本需要的东西。在深入理解之前,先记住吧。
然后就是main函数的入口,我们会发现,和控制台的main函数是不一样的,但是功能和控制台下的类似,都是程序的入口点,参数稍微多了点,我们从第一个开始看。
HINSTANCE hInstance:MSDN上边这样解释:[in] Handle to the current instance of the application. 表示该程序当前运行的实例句柄(您可能对句柄的概念不是很清楚,我会在下文写出),同一个程序可以在同时运行多个实例,操作系统会为每个实例分配一个实例句柄,该实例句柄就传给这个参数。
HINSTANCE hPrevInstance:MSDN:[in] Handle to the current instance of the application.在同一个计算机上运行同一个程序的时候计算机会为它分配不同的实例句柄(关于句柄我会在下边讲解),这个参数就是存储的程序本身的实例句柄。
HINSTANCE hPrevInstance:MSDN:[in] Handle to the previous instance of the application. This parameter is always NULL. If you need to detect whether another instance already exists, create a uniquely named mutex using the CreateMutex function. CreateMutex will succeed even if the mutex already exists, but the function will return ERROR_ALREADY_EXISTS. This indicates that another instance of your application exists, because it created the mutex first. However, a malicious user can create this mutex before you do and prevent your application from starting. To prevent this situation, create a randomly named mutex and store the name so that it can only be obtained by an authorized user. Alternatively, you can use a file for this purpose. To limit your application to one instance per user, create a locked file in the user's profile directory.这个说的有点长,其实就是当程序不是第一个实例的时候,这个参数存储的是上一个实例的实例句柄,当是第一个实例的时候,存储的是NULL。
LPSTR lpCmdLine:MSDN:[in] Pointer to a null-terminated string specifying the command line for the application, excluding the program name. To retrieve the entire command line, use the GetCommandLine function.这个很好理解,该参数里边存储着传递给应用程序的参数串,举个例子:打开c盘的1.txt文件的时候,使用的是notepad(记事本),那么传递给notepad这个实例的参数串就是c:\1.txt。
int nCmdShow:[in] Specifies how the window is to be shown. 指定该窗口的显示方式:最大化,最小化,正常甚至是隐藏等。
看完了参数再回来看WinMain前边的WINAPI,我们通过“转到定义”可以发现WINAPI其实是 #define WINAPI __stdcall 。 关于__stdcall 百度百科上边这样解释: 被__stdcall修饰关键字修饰的函数,其参数都是从右向左通过堆栈传递的(__fastcall的前面部分由ecx,edx传),函数调用在返回前要清理堆栈,但由调用者还是被调用者清理不一定。 其实就是约定了一个堆栈平衡的方式。
下边我们说一下句柄,句柄在Windows编程里边是一个很重要的概念,但是重要并不代表难理解,摘自百度百科:WINDOWS程序中并不是用物理地址来标识一个内存块,文件,任务或动态装入模块的。相反,WINDOWS API给这些项目分配确定的句柄,并将句柄返回给应用程序,然后通过句柄来进行操作。在《WINDOWS编程短平快》(南京大学出版社)一书中是这么说的:句柄是WINDOWS用来标识被应用程序所建立或使用的对象的唯一整数,WINDOWS使用各种各样的句柄标识诸如应用程序实例,窗口,控制,位图,GDI对象等等。WINDOWS句柄有点象C语言中的文件句柄。从上面的2个定义中我们可以看到,句柄是一个标识符,是拿来标识对象或者项目的。它就像我们的车牌号一样,每一辆注册过的车都会有一个确定的号码,不同的车号码各不相同,但是也可能会在不同的时期出现两辆号码相同的车,只不过它们不会同时处于使用之中罢了。应用程序几乎总是通过调用一个WINDOWS函数来获得一个句柄,之后其他的WINDOWS函数就可以使用该句柄,以引用相应的对象。在WINDOWS编程中会用到大量的句柄,比如:HINSTANCE(实例句柄),HBITMAP(位图句柄),HDC(设备描述表句柄),HICON(图标句柄)等等。这当中还有一个通用的句柄,就是HANDLE。 初学者会认为句柄和指针有很多共同点,其实却是是有很多共同点,但是还是有不一样的,句柄只是一个标识(仅仅起到代表作用),而指针是指向。两者不同!但是又有相似的地方,比如,Windows中想要操作一个对象就要先得到它的句柄,当然,得到句柄的方法也有很多,我们在接下来遇到的时候再详细讲吧。
这样我们就完成了一个最简单的Windows环境下的程序。呼呼。好累!
可能您并不能理解我写的所有的东西,尤其是MSDN上边的那些,但是作为初学者,不需要掌握MSDN上边的那些,仅仅把WinMain函数的各个参数的意义和WINAPI的本质搞清楚就OK了! |
|