友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!阅读过程发现任何错误请告诉我们,谢谢!! 报告错误
狗狗书籍 返回本书目录 我的书架 我的书签 TXT全本下载 进入书吧 加入书签

C语言实例教程(PDF格式)-第27章

按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!




     都有自已独立的地址空间,因此,它们之间互相独立,互不 

     干涉。但是,对于一些应用程序,只需要而且只应该有一个 

     实例在运行。什么情况下会是这样呢?假设我们编写了一个 

     应用程序,在默认情况下,该应用程序将在后台运行,通过 

     按下程序所定义的某一个热键,应用程序将被激活。对于这 

     样的应用程序,在同一时该只应该有一个实例在运行。另 

     外,像Windows  NT下在任务管理器,在同一时刻也只可以有 

     一个实例在运行。  



     使用下面的技巧可以保证在同一时刻只有应用程序的一个实 

     例:  



l #include 〃windows。h〃  



l   



l #define VK_X 0x58  



l   



l int WINAPI WinMain (HINSTANCE hInstance;  


…………………………………………………………Page 126……………………………………………………………

l HINSTANCE hPrevInstance;  



l LPSTR lpCmdLine;  



l int nCmdShow)  



l {  



l if (!CreateMutex(NULL;TRUE;〃No Previous Instance!〃))  



l {  



l MessageBox(NULL;〃创建Mutex失败!〃;〃NoPrev〃;MB_OK|MB_SYSTEMMODAL);  



l return FALSE;  



l }  



l if (GetLastError()==ERROR_ALREADY_EXISTS)  



l {  



l MessageBox(NULL;〃已有NoPrev的一个实例在运行; 当前实例将被终止!〃;  



l 〃NoPrev〃;MB_OK|MB_SYSTEMMODAL);  



l return FALSE;  



l }  



l if(!RegisterHotKey(NULL;0x0001;MOD_CONTROL|MOD_SHIFT;VK_X))  



l {  



l MessageBox(NULL;〃注册热键Ctrl+Shift+X失败!〃;  



l 〃NoPrev〃;MB_OK|MB_SYSTEMMODAL);  



l return FALSE;  



l }  



l MessageBox(NULL;〃NoPrev已启动!nn按下热键Ctrl+Shift+X将终止NoPrev。〃;  



l 〃NoPrev〃;MB_OK|MB_SYSTEMMODAL);  


…………………………………………………………Page 127……………………………………………………………

l MSG msg;  



l while (GetMessage(&msg;NULL;0;0))  



l {  



l switch (msg。message)  



l {  



l case WM_HOTKEY:  



l if (int(msg。wParam)==0x0001)  



l if (MessageBox(NULL;〃终止NoPrev?〃;  



l 〃NoPrev〃;MB_YESNO|MB_SYSTEMMODAL)==IDYES)  



l return TRUE;  



l }  



l }  



l return TRUE;  



l }  



      上面的代码是一个功能完整的Windows应用程序,其中用到了 

      一些到目前为止我们还未讲述到的内容。程序定义了热键 

      Ctrl+Shift+X,当按下该热键时将终止该程序。由于程序中 

       没有包括任何窗口,因此这是唯一的一种正常终止应用程序 

       的方法。当程序NoPrev正在后台运行时,如果用户按下了组 

      合键Ctrl+Shift+X,Windows将向程序主线程的消息队列中发 

      送一条称为WM_HOTKEY的消息,当程序收到这条消息时,即弹 

       出了消息框询问是否终止NoPrev。上面的说明将有助于你理 

      解以上代码,但是我们 目前对止并不做要求。这里,只需要 

       注意下面的代码 :  



l if (!CreateMutex(NULL;TRUE;〃No Previous Instance!〃))  



l {  


…………………………………………………………Page 128……………………………………………………………

  l MessageBox(NULL;〃创建Mutex失败!〃;〃NoPrev〃;MB_OK|MB_SYSTEMMODAL);  



  l return FALSE;  



  l }  



  l if (GetLastError()==ERROR_ALREADY_EXISTS)  



  l {  



  l MessageBox(NULL;〃已有NoPrev的一个实例在运行; 当前实例将被终止!〃;  



  l 〃NoPrev〃;MB_OK|MB_SYSTEMMODAL);  



  l return FALSE;  



  l }  



       在上面的代码 中,我们先调用CreateMutex创建一个名为 “ 

                                                          No  

       Previous     Instance”的命名互斥对象(named             mutex  

       object),如果该对象名已存在(注意这时函数CreateMutex仍 

       返回真值TRUE),则随后调用的GetLastError函数将返回 

       ERROR_ALREADY_EXISTS,由此得知已有一个应用程序的实例 

       正在运行。从而弹出消息框提醒用户,然后终止应用程序的 

        当前实例。  



在上面的WinMain函数原型中的另一个奇怪的标识符为WINAPI,这是 

一个在windef。h头文件中定义的宏,在当前版本Win32                       SDK中, 

WINAPI被定义为FAR PASCAL,因此,使用FAR PASCAL同使用WINAPI具 

有同样的效果,但是,我们强烈建议你使用WINAPI来代替以前常用的 

FAR PASCAL,因为Microsoft不保证FAR PASCAL能够在将来的Windows 

版本中正常工作。在目前情况下,和FAR                    PASCAL等价的标识符还有 

CALLBACK       (用在如窗口过程或对话框过程之类的回调函数前)和 

APIENTRY等。它们对编译器而言都是一回事,最终将被解释为 

__stdcall。在Windows环境下编程,会遇到很多这样的情况,注意不 

要混淆它们。  



一般情况下,我们应该在WinMain函数中完成下面的操作:  



1。 注册窗口类;  



2。 创建应用程序主窗口;  


…………………………………………………………Page 129……………………………………………………………

3。 进入应用程序消息循环。  



接下来我们将依次讨论这些内容。  



在Windows应用程序中,每一个窗口都必须从属于一个窗口类,窗口 

类定义了窗口所具有的属性,如它的样式、图标、鼠标指针、菜单名 

称及窗口过程名等。在注册窗口类前,我们先创建一个类型为 

WNDCLASS的结构,然后在该结构对象中填入窗口类的信息,最后将它 

传递给函数RegisterClass,整个过程如下面的代码所示:  



WNDCLASS wc;  



// 填充窗口类信息  



wc。style=CS_HREDRAW|CS_VREDRAW;  



wc。lpfnWndProc=WndProc;  



wc。cbClsExtra=0;  



wc。cbWndExtra=0;  



wc。hInstance=hInstance;  



wc。hIcon=LoadIcon(NULL;IDI_APPLICATION);  



wc。hCursor=LoadCursor(NULL;IDC_ARROW);  



wc。hbrBackground=GetStockObject(WHITE_BRUSH);  



wc。lpszMenuName=NULL;  



wc。lpszClassName=〃SdkDemo1〃;  



// 注册窗口类  



RegisterClass(&wc);  



下面解释一下结构WNDCLASS 中各成员的含义:  



                    style:  指定窗口样式。该样式可以为一系列屏 

                    蔽位的按位或,在前面的例子中,CS_HREDRAW表 

                    示当窗口用户区宽度改变时重绘整个窗口,而 

                    CS_VREDRAW则表则表示当窗口用户区高度改变时 

                    重绘整个窗口。对于其它的窗口样式,请参阅 

                    SDK中关于WNDCLASS的联机文档。(顺便说一句, 

                    请注意该成员的大小写,它是小写的style,而 


…………………………………………………………Page 130……………………………………………………………

不是Style。)  



lpfnWndProc:  指向窗口过程的指针。关于窗口 

过程我们将以后面的内容中讲述。在前面的例子 

中,我们使用名为WndProc的窗口过程。  



cbClsExtra: 指定在窗口类结构之后分配的附加 

字节数。操作系统将这些字节初始化为0。  



cbWndExtra: 指定在窗口实例之后分配的附加字 

节数。操作系统将这些字节初始化为0。如果应 

用程序使用WNDCLASS结构注册一个�
返回目录 上一页 下一页 回到顶部 赞(1) 踩(1)
未阅读完?加入书签已便下次继续阅读!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!