除了运行消息循环并让你有机会初始化应用程序并在应用程序之后进行清理, CWinApp 还提供其他几个服务。
Shell 注册
默认情况下,MFC 应用程序向导使用户能够在文件资源管理器或文件管理器中双击应用程序创建的数据文件。 如果你的应用程序是 MDI 应用程序,并且你为应用程序创建的文件指定了扩展名,那么 MFC 应用程序向导会将对 CWinApp 的 RegisterShellFileTypes 和 EnableShellOpen 成员函数的调用添加到它为你编写的重写中。
RegisterShellFileTypes 将你的应用程序的文档类型注册到文件资源管理器或文件管理器。 该函数将条目添加到 Windows 维护的注册数据库中。 这些条目注册每个文档类型,将文件扩展名与文件类型相关联,指定要打开应用程序的命令行,并指定动态数据交换 (DDE) 命令以打开该类型的文档。
EnableShellOpen 通过允许应用程序从文件资源管理器或文件管理器接收 DDE 命令以打开用户选择的文件,从而完成该过程。
CWinApp 中的此自动支持使您无需将 .reg 文件附加到您的应用程序或完成特殊安装工作。
如果要为应用程序初始化 GDI+ (通过在 InitInstance 函数中调用 GdiplusStartup),则必须取消 GDI+ 后台线程。
可以通过将 SuppressBackgroundThread 结构的 成员设置为 TRUE 来执行此操作。 当需要抑制 GDI+ 后台线程时,应在进入和退出应用程序消息循环之前分别进行 NotificationHook 和 NotificationUnhook 调用。 有关这些调用的详细信息,请参阅 GdiplusStartupOutput。 因此,适合调用 GdiplusStartup 和挂钩通知函数的位置是在虚函数 CWinApp::Run 的替代中,如下所示:
int CMyWinApp::Run()
{
GdiplusStartupInput gdiSI;
GdiplusStartupOutput gdiSO;
ULONG_PTR gdiToken;
ULONG_PTR gdiHookToken;
gdiSI.SuppressBackgroundThread = TRUE;
GdiplusStartup(&gdiToken, &gdiSI, &gdiSO);
gdiSO.NotificationHook(&gdiHookToken);
int nRet = CWinApp::Run();
gdiSO.NotificationUnhook(gdiHookToken);
GdiplusShutdown(gdiToken);
return nRet;
}
如果不取消后台 GDI+ 线程,可以在创建主窗口之前过早地向应用程序发出 DDE 命令。 shell 发出的 DDE 命令可能会过早中止,从而导致错误消息。
文件管理器拖放功能
可以将文件从文件管理器或文件资源管理器中的文件视图窗口拖动到应用程序中的窗口。 例如,可以启用一个或多个文件拖到 MDI 应用程序的主窗口,应用程序可以在其中检索文件名并打开这些文件的 MDI 子窗口。
若要在您的应用程序中启用文件拖放,MFC 应用程序向导会在您的主框架窗口中编写对CWnd 成员函数 DragAcceptFiles 的调用InitInstance。 如果不想实现拖放功能,可以删除该调用。
注释
还可以使用 OLE 实现更常规的拖放功能(在文档之间或文档中拖动数据)。 有关信息,请参阅 OLE 拖放文章。
跟踪最近使用的文档
当用户打开和关闭文件时,应用程序对象将跟踪最近使用的四个文件。 这些文件的名称将添加到“文件”菜单中,并在更改时更新。 框架将这些文件名存储在注册表或 .ini 文件中,其名称与项目相同,并在应用程序启动时从文件中读取它们。 InitInstance MFC 应用程序向导创建的替代包括对 CWinApp 成员函数 LoadStdProfileSettings 的调用,该函数从注册表或 .ini 文件加载信息,包括最近使用的文件名。
这些条目存储如下:
在 Windows NT、Windows 2000 及更高版本中,该值存储在注册表项中。
在 Windows 3.x 中,该值存储在 WIN.INI 文件中。
在 Windows 95 及更高版本中,该值存储在 WIN 的缓存版本中。INI.