Win32 SDK封闭实例——普通的Windows程序(翻译) hqywork(翻译)
关键字 Win32,sdk
这个程序使用类封装了Windows API。
Controller-- 窗口过程和对象之间的桥梁。
View-- Windows程序的输出封装。
Canvas-- 封装了不同的设备描述符和事件,你可以去使用它们。
Model-- 工作者,你的程序的大脑。从不处理窗口。
注意: 这是一个Win32程序——它将运行在Windows95及WindowsNT下。
注意: _set_new_handler是Microsoft特定的。如果你使用的是其它的编译器,只要移去这行代码。依照当前的C++标准,new操作符无论如何都应该抛弃。
注意: 旧的编译器在模板方面可能有问题。你可以直接调用Get/SetWindowLong来代替Win[Get/Set]Long模板。实例,调用以下的来代替
Controller * pCtrl = WinGetLong (hwnd);
你可以调用
Controller * pCtrl = reinterpret_cast<Controller *> (::GetWindowLong (hwnd, GWL_USERDATA));
--------------------------------------------------------------------------------
让我们从WinMain开始,我们建立一个窗口类及我们的程序的最顶层窗口。我在两个类中封装了这些动作:WinClass和WinMaker。如果在那我们的程序已经运行了一个实例,WinClass可以告诉我们。当这样的事发生时,我们的例子,将简单的激活程序先前的实例后结束。当你只想让你的程序在同一时间运行一个实例时,你应该这样做。
一旦顶层窗口被成功的建立,我们开始消息循环。在这时我们通过调用TranslateMessage来处理快捷键。这是因为我们的程序的菜单条目可以使用Alt+键的组合来访问。
另外这个程序有趣的是我们不能使用很长的字符串去命名我们的资源——我们使用数字标识。即使是API调用的字符串,象窗口类型名或标题,我们都存贮在字符串资源中,通过标识符来访问。你们的Windows开发环境中多数有一个资源编辑器让你去建立图标,菜单,及字符串资源,给它们分配适当的数字标识符。这些标识符的符号名存贮在一个引审了的头文件中——我们程序去调用它resource.h。
常量,ID_MAIN是为实例的主程序引入的图标 (在同一资源中有一大一小),主菜单,及窗口类型句的字符串。ID_CAPTION是窗口标题字符串。
--------------------------------------------------------------------------------
int WINAPI WinMain
(HINSTANCE hInst, HINSTANCE hPrevInst,
char * cmdParam, int cmdShow)
{
_set_new_handler (& NewHandler);
// 使用异常帮助调试你的程序
// 防止异常事件
try
{
// 建立顶层窗口类
TopWinClass topWinClass (ID_MAIN, hInst, MainWndProc);
// 正在运行这个程序的实例吗?
HWND hwndOther = topWinClass.GetRunningWindow ();
if (hwndOther != 0)
{
::SetForegroundWindow (hwndOther);
if (::IsIconic (hwndOther))
::ShowWindow (hwndOther, SW_RESTORE);
return 0;
}
topWinClass.Register ();
// 建立顶层窗口
ResString caption (hInst, ID_CAPTION);
TopWinMaker topWin (topWinClass, caption);
topWin.Create ();
topWin.Show (cmdShow);
// 主消息循环
MSG msg;
int status;
while ((status = ::GetMessage (&msg, 0, 0, 0)) != 0)
{
if (status == -1)
return -1;
::TranslateMessage (&msg);
::DispatchMessage (&msg);
}
return msg.wParam;
}
catch ( WinException e )
{
char buf [50];
wsprintf (buf, "%s, Error %d", e.GetMessage (), e.GetError ());
::MessageBox (0, buf, "Exception", MB_ICONEXCLAMATION | MB_OK);
}
catch (...)
{
::MessageBox (0, "Unknown", "Exception", MB_ICONEXCLAMATION | MB_OK);
}
return 0;
}
--------------------------------------------------------------------------------
让我们一起看一下WinClass类。它封装了被WNDCLASSEX调用的窗口定义结构,为它的所有字段提供了合理的默认值。它来源于一个WinSimpleClass模板类,你可以使用去封装一些固定的窗口类型(象按钮,列表视)
我倘若有一个方法的例子可以不考虑默认。例如,SetBgSysColor可以改变默认的窗口的客户区的背景色。方法SetResIcons从资源中装入适当的图标,并把它们附在窗口类上。这些图标将在当时显示在主窗口和Windows的任务栏中。
TopWinClass来由于WinClass的方法的使用。它同样分配菜单到顶层窗口类中。
--------------------------------------------------------------------------------