⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chap03.html

📁 利用软件开发
💻 HTML
📖 第 1 页 / 共 5 页
字号:
<P ALIGN="JUSTIFY"><LI>&#9;</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=1>return TRUE;</LI></P>
</FONT><FONT FACE="楷体_GB2312" LANG="ZH-CN" SIZE=1><P ALIGN="JUSTIFY"><LI>}</LI></P></UL>
<DIR>
<DIR>

</FONT><FONT FACE="楷体_GB2312" LANG="ZH-CN" SIZE=3><P ALIGN="JUSTIFY">上面的代码是一个功能完整的</FONT><FONT SIZE=3>Windows</FONT><FONT FACE="楷体_GB2312" LANG="ZH-CN" SIZE=3>应用程序,其中用到了一些到目前为止我们还未讲述到的内容。程序定义了热键</FONT><FONT SIZE=3>Ctrl+Shift+X</FONT><FONT FACE="楷体_GB2312" LANG="ZH-CN" SIZE=3>,当按下该热键时将终止该程序。由于程序中没有包括任何窗口,因此这是唯一的一种正常终止应用程序的方法。当程序</FONT><FONT SIZE=3>NoPrev</FONT><FONT FACE="楷体_GB2312" LANG="ZH-CN" SIZE=3>正在后台运行时,如果用户按下了组合键</FONT><FONT SIZE=3>Ctrl+Shift+X</FONT><FONT FACE="楷体_GB2312" LANG="ZH-CN" SIZE=3>,</FONT><FONT SIZE=3>Windows</FONT><FONT FACE="楷体_GB2312" LANG="ZH-CN" SIZE=3>将向程序主线程的消息队列中发送一条称为</FONT><FONT SIZE=3>WM_HOTKEY</FONT><FONT FACE="楷体_GB2312" LANG="ZH-CN" SIZE=3>的消息,当程序收到这条消息时,即弹出了消息框询问是否终止</FONT><FONT SIZE=3>NoPrev</FONT><FONT FACE="楷体_GB2312" LANG="ZH-CN" SIZE=3>。上面的说明将有助于你理解以上代码,但是我们目前对止并不做要求。这里,只需要注意下面的代码:</P></DIR>
</DIR>


<UL>
</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=1><P ALIGN="JUSTIFY"><LI>if (!CreateMutex(NULL,TRUE,"No Previous Instance!"))</LI></P>
</FONT><FONT FACE="楷体_GB2312" LANG="ZH-CN" SIZE=1><P ALIGN="JUSTIFY"><LI>{</LI></P>
<P ALIGN="JUSTIFY"><LI>&#9;</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=1>MessageBox(NULL,"</FONT><FONT FACE="楷体_GB2312" LANG="ZH-CN" SIZE=1>创建</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=1>Mutex</FONT><FONT FACE="楷体_GB2312" LANG="ZH-CN" SIZE=1>失败</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=1>!","NoPrev",MB_OK|MB_SYSTEMMODAL);</LI></P>
</FONT><FONT FACE="楷体_GB2312" LANG="ZH-CN" SIZE=1><P ALIGN="JUSTIFY"><LI>&#9;</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=1>return FALSE;</LI></P>
</FONT><FONT FACE="楷体_GB2312" LANG="ZH-CN" SIZE=1><P ALIGN="JUSTIFY"><LI>}</LI></P>
</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=1><P ALIGN="JUSTIFY"><LI>if (GetLastError()==ERROR_ALREADY_EXISTS)</LI></P>
</FONT><FONT FACE="楷体_GB2312" LANG="ZH-CN" SIZE=1><P ALIGN="JUSTIFY"><LI>{</LI></P>
<P ALIGN="JUSTIFY"><LI>&#9;</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=1>MessageBox(NULL,"</FONT><FONT FACE="楷体_GB2312" LANG="ZH-CN" SIZE=1>已有</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=1>NoPrev</FONT><FONT FACE="楷体_GB2312" LANG="ZH-CN" SIZE=1>的一个实例在运行</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=1>, </FONT><FONT FACE="楷体_GB2312" LANG="ZH-CN" SIZE=1>当前实例将被终止</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=1>!",</LI></P>
</FONT><FONT FACE="楷体_GB2312" LANG="ZH-CN" SIZE=1><P ALIGN="JUSTIFY"><LI>&#9;&#9;</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=1>"NoPrev",MB_OK|MB_SYSTEMMODAL);</LI></P>
</FONT><FONT FACE="楷体_GB2312" LANG="ZH-CN" SIZE=1><P ALIGN="JUSTIFY"><LI>&#9;</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=1>return FALSE;</LI></P>
</FONT><FONT FACE="楷体_GB2312" LANG="ZH-CN" SIZE=1><P ALIGN="JUSTIFY"><LI>}</LI></P></UL>
<DIR>
<DIR>

</FONT><FONT FACE="楷体_GB2312" LANG="ZH-CN" SIZE=3><P ALIGN="JUSTIFY">在上面的代码中,我们先调用</FONT><FONT SIZE=3>CreateMutex</FONT><FONT FACE="楷体_GB2312" LANG="ZH-CN" SIZE=3>创建一个名为“</FONT><FONT SIZE=3>No Previous Instance</FONT><FONT FACE="楷体_GB2312" LANG="ZH-CN" SIZE=3>”的命名互斥对象</FONT><FONT SIZE=3>(named mutex object)</FONT><FONT FACE="楷体_GB2312" LANG="ZH-CN" SIZE=3>,如果该对象名已存在</FONT><FONT SIZE=3>(</FONT><FONT FACE="楷体_GB2312" LANG="ZH-CN" SIZE=3>注意这时函数</FONT><FONT SIZE=3>CreateMutex</FONT><FONT FACE="楷体_GB2312" LANG="ZH-CN" SIZE=3>仍返回真值</FONT><FONT SIZE=3>TRUE)</FONT><FONT FACE="楷体_GB2312" LANG="ZH-CN" SIZE=3>,则随后调用的</FONT><FONT SIZE=3>GetLastError</FONT><FONT FACE="楷体_GB2312" LANG="ZH-CN" SIZE=3>函数将返回</FONT><FONT SIZE=3>ERROR_ALREADY_EXISTS</FONT><FONT FACE="楷体_GB2312" LANG="ZH-CN" SIZE=3>,由此得知已有一个应用程序的实例正在运行。从而弹出消息框提醒用户,然后终止应用程序的当前实例。</P>
</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3><P ALIGN="JUSTIFY"></P></DIR>
</DIR>

<P ALIGN="JUSTIFY">在上面的</FONT><FONT SIZE=3>WinMain</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>函数原型中的另一个奇怪的标识符为</FONT><FONT SIZE=3>WINAPI</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,这是一个在</FONT><FONT SIZE=3>windef.h</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>头文件中定义的宏,在当前版本</FONT><FONT SIZE=3>Win32 SDK</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>中,</FONT><FONT SIZE=3>WINAPI</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>被定义为</FONT><FONT SIZE=3>FAR PASCAL</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,因此,使用</FONT><FONT SIZE=3>FAR PASCAL</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>同使用</FONT><FONT SIZE=3>WINAPI</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>具有同样的效果,但是,我们强烈建议你使用</FONT><FONT SIZE=3>WINAPI</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>来代替以前常用的</FONT><FONT SIZE=3>FAR PASCAL</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,因为</FONT><FONT SIZE=3>Microsoft</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>不保证</FONT><FONT SIZE=3>FAR PASCAL</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>能够在将来的</FONT><FONT SIZE=3>Windows</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>版本中正常工作。在目前情况下,和</FONT><FONT SIZE=3>FAR PASCAL</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>等价的标识符还有</FONT><FONT SIZE=3>CALLBACK (</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>用在如窗口过程或对话框过程之类的回调函数前</FONT><FONT SIZE=3>)</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>和</FONT><FONT SIZE=3>APIENTRY</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>等。它们对编译器而言都是一回事,最终将被解释为</FONT><FONT SIZE=3>__stdcall</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>。在</FONT><FONT SIZE=3>Windows</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>环境下编程,会遇到很多这样的情况,注意不要混淆它们。</P>
<P ALIGN="JUSTIFY">一般情况下,我们应该在</FONT><FONT SIZE=3>WinMain</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>函数中完成下面的操作:</P>
</FONT><FONT SIZE=3><P ALIGN="JUSTIFY">1.&#9;</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>注册窗口类;</P>
</FONT><FONT SIZE=3><P ALIGN="JUSTIFY">2.&#9;</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>创建应用程序主窗口;</P>
</FONT><FONT SIZE=3><P ALIGN="JUSTIFY">3.&#9;</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>进入应用程序消息循环。</P>
<P ALIGN="JUSTIFY">接下来我们将依次讨论这些内容。</P>
<P ALIGN="JUSTIFY">在</FONT><FONT SIZE=3>Windows</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>应用程序中,每一个窗口都必须从属于一个窗口类,窗口类定义了窗口所具有的属性,如它的样式、图标、鼠标指针、菜单名称及窗口过程名等。在注册窗口类前,我们先创建一个类型为</FONT><FONT SIZE=3>WNDCLASS</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>的结构,然后在该结构对象中填入窗口类的信息,最后将它传递给函数</FONT><FONT SIZE=3>RegisterClass</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,整个过程如下面的代码所示:</P>
</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=1><P>WNDCLASS wc;</P>

<P>// 填充窗口类信息</P>
<P>wc.style=CS_HREDRAW|CS_VREDRAW;</P>
<P>wc.lpfnWndProc=WndProc;</P>
<P>wc.cbClsExtra=0;</P>
<P>wc.cbWndExtra=0;</P>
<P>wc.hInstance=hInstance;</P>
<P>wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);</P>
<P>wc.hCursor=LoadCursor(NULL,IDC_ARROW);</P>
<P>wc.hbrBackground=GetStockObject(WHITE_BRUSH);</P>
<P>wc.lpszMenuName=NULL;</P>
<P>wc.lpszClassName="SdkDemo1";</P>

<P>// 注册窗口类</P>
<P>RegisterClass(&amp;wc);</P>
</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3><P ALIGN="JUSTIFY">下面解释一下结构</FONT><FONT SIZE=3>WNDCLASS</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>中各成员的含义:</P><DIR>
<DIR>
<DIR>
<DIR>
<DIR>

</FONT><FONT SIZE=3><P ALIGN="JUSTIFY">style:&#9;</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>指定窗口样式。该样式可以为一系列屏蔽位的按位或,在前面的例子中,</FONT><FONT SIZE=3>CS_HREDRAW</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>表示当窗口用户区宽度改变时重绘整个窗口,而</FONT><FONT SIZE=3>CS_VREDRAW</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>则表则表示当窗口用户区高度改变时重绘整个窗口。对于其它的窗口样式,请参阅</FONT><FONT SIZE=3>SDK</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>中关于</FONT><FONT SIZE=3>WNDCLASS</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>的联机文档。</FONT><FONT SIZE=3>(</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>顺便说一句,请注意该成员的大小写,它是小写的</FONT><FONT SIZE=3>style</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,而不是</FONT><FONT SIZE=3>Style</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>。</FONT><FONT SIZE=3>)</P>
<P ALIGN="JUSTIFY">lpfnWndProc:&#9;</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>指向窗口过程的指针。关于窗口过程我们将以后面的内容中讲述。在前面的例子中,我们使用名为</FONT><FONT SIZE=3>WndProc</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>的窗口过程。</P>
</FONT><FONT SIZE=3><P ALIGN="JUSTIFY">cbClsExtra:&#9;</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>指定在窗口类结构之后分配的附加字节数。操作系统将这些字节初始化为</FONT><FONT SIZE=3>0</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>。</P>
</FONT><FONT SIZE=3><P ALIGN="JUSTIFY">cbWndExtra:&#9;</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>指定在窗口实例之后分配的附加字节数。操作系统将这些字节初始化为</FONT><FONT SIZE=3>0</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>。如果应用程序使用</FONT><FONT SIZE=3>WNDCLASS</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>结构注册一个使用资源文件中的</FONT><FONT SIZE=3>CLASS</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>指令创建的对话框,那么</FONT><FONT SIZE=3>cbWndExtra</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>必须被设置为</FONT><FONT SIZE=3>DLGWINDOWEXTRA</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>。</P>
</FONT><FONT SIZE=3><P ALIGN="JUSTIFY">hInstance :&#9;</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>标识该类的窗口过程所属的实例。</P>
</FONT><FONT SIZE=3><P ALIGN="JUSTIFY">hIcon :&#9;</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>标识类图标。该成员必须为一个图标资源的句柄。如果该成员为</FONT><FONT SIZE=3>NULL</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,则应用程序必须在用户最小化应用程序窗口时绘制图标。</P>
</FONT><FONT SIZE=3><P ALIGN="JUSTIFY">hCursor :&#9;</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>标识类鼠标指针。该成员必须为一个光标资源的句柄,如果该成员为</FONT><FONT SIZE=3>NULL</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,当鼠标移进应用程序窗口时应用程序必须显式指定指针形状。</P>
</FONT><FONT SIZE=3><P ALIGN="JUSTIFY">hbrBackground:&#9;</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>标识类背景刷子。该成员可以为一个用来绘制背景的画刷句柄,或者为标准系统颜色值之一。</FONT><FONT SIZE=3> </P>
<P ALIGN="JUSTIFY">lpszMenuName:&#9;</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>指向一個以</FONT><FONT SIZE=3>NULL</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>结尾的字符串的指针,该字符串指定了类菜单的资源名称。如果在资源名称为的菜单为一个整数所标识,则可以使用</FONT><FONT SIZE=3>MAKEINTRESOURCE</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>宏将其转换为一个字符串;如果该成员为</FONT><FONT SIZE=3>NULL</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>,则属于该类的窗口无默认菜单。</P>
</FONT><FONT SIZE=3><P ALIGN="JUSTIFY">lpszClassName:&#9;</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>指向一个以</FONT><FONT SIZE=3>NULL</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>结尾的字符串或为一个原子。如果该参数为一个原子,那么它必须是一个使用</FONT><FONT SIZE=3>GlobalAddAtom</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>函数创建的全局原子;如果为一个字符串,该字符器将成员窗口类名。</P></DIR>
</DIR>
</DIR>
</DIR>
</DIR>


<UL>
</FONT><FONT FACE="黑体" LANG="ZH-CN" SIZE=3><P ALIGN="JUSTIFY"><LI>注意:</LI></P>
</FONT><FONT FACE="楷体_GB2312" LANG="ZH-CN" SIZE=3><P ALIGN="JUSTIFY"><LI>这里多次提到窗口类这一名词,但是它和前面常说的</FONT><FONT SIZE=3>C++</FONT><FONT FACE="楷体_GB2312" LANG="ZH-CN" SIZE=3>类没有任何联系。窗口类只表示了窗口的类型,它完全不是面向对象意义上的类,因为它不支持面向对象技术中的继承及多态等。</LI></P></UL>

</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3><P ALIGN="JUSTIFY"></P>
<P ALIGN="JUSTIFY">在使用</FONT><FONT SIZE=3>RegisterClass</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>注册窗口类成功之后,即可以使用该窗口类创建并显示应用程序的窗口。这个过程如下面的代码所示:</P>
</FONT><FONT FACE="宋体" LANG="ZH-CN" SIZE=1><P>// 创建应用程序主窗口</P>
<P>hWnd=CreateWindow ("SdkDemo1",&#9;&#9;&#9;&#9;&#9;// 窗口类名</P>
<P>&#9;&#9;&#9;&#9;   "第一个Win32 SDK应用程序",&#9;// 窗口标题</P>
<P>&#9;&#9;&#9;&#9;   WS_OVERLAPPEDWINDOW,&#9;&#9;// 窗口样式</P>
<P>&#9;&#9;&#9;&#9;   CW_USEDEFAULT,&#9;&#9;&#9;&#9;// 初始化 x 坐标</P>
<P>&#9;&#9;&#9;&#9;   CW_USEDEFAULT,&#9;&#9;&#9;&#9;// 初始化 y 坐标</P>
<P>&#9;&#9;&#9;&#9;   CW_USEDEFAULT,&#9;&#9;&#9;&#9;// 初始化窗口宽度</P>
<P>&#9;&#9;&#9;&#9;   CW_USEDEFAULT,&#9;&#9;&#9;&#9;// 初始化窗口高度</P>
<P>&#9;&#9;&#9;&#9;   NULL,&#9;&#9;&#9;&#9;&#9;&#9;// 父窗口句柄</P>
<P>&#9;&#9;&#9;&#9;   NULL,&#9;&#9;&#9;&#9;&#9;&#9;// 窗口菜单句柄</P>
<P>&#9;&#9;&#9;&#9;   hInstance,&#9;&#9;&#9;&#9;&#9;// 程序实例句柄</P>
<P>&#9;&#9;&#9;&#9;   NULL);&#9;&

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -