特殊 CWinApp 服务
除了运行消息循环以及支持你初始化应用程序然后进行清理之外,CWinApp 还提供了一些其他服务。
Shell 注册
默认情况下,MFC 应用程序向导使用户能够打开您的应用程序已创建的数据文件,方法是在文件资源管理器或文件管理器中打开它们。 如果你的应用程序是 MDI 应用程序,并且你为该应用程序创建的文件指定了扩展名,MFC 应用程序向导会将对 CWinApp 的 RegisterShellFileTypes 和 EnableShellOpen 成员函数的调用添加到它为你编写的 InitInstance
替代。
RegisterShellFileTypes
将您的应用程序的文档类型注册到文件资源管理器或文件管理器。 该函数可将项添加到 Windows 保留的注册数据库。 这些项注册每个文档类型、将文件扩展名与文件类型关联、指定用来打开应用程序的命令行并指定用来打开该类型的文档的动态数据交换 (DDE) 命令。
EnableShellOpen
通过以下方式完成这个过程:允许您的应用程序从文件资源管理器或文件管理器接收用来打开用户选择的文件的 DDE 命令。
CWinApp
中的此自动支持使您无需将 .reg 文件附加到您的应用程序或完成特殊安装工作。
如果要初始化应用程序的 GDI+(通过在 InitInstance 函数中调用 GdiplusStartup),则必须禁止 GDI+ 后台线程。
可通过将 GdiplusStartupInput 结构的 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 应用程序向导会在 InitInstance
中为主框架窗口编写对 CWnd 成员函数 DragAcceptFiles 的调用。 如果您不想实现拖放功能,则可以移除该调用。
注意
您还可以使用 OLE 实现更常见的拖放功能 — 在文档之间或文档中拖动数据。 相关信息,请参阅 OLE 拖放一文。
跟踪最近使用的文档
当用户打开和关闭文件时,应用程序对象将跟踪四个最近使用的文件。 这些文件的名称将添加到“文件”菜单并在更改时更新。 框架会将这些文件名存储在与您的项目同名的注册表或 .ini 文件中,并在您的应用程序启动时从文件中读取它们。 MFC 应用程序向导创建的 InitInstance
替代包含对 CWinApp 成员函数 LoadStdProfileSettings 的调用,该调用从注册表或 .ini 文件加载信息(包括最近使用的文件名)。
这些项按如下方式进行存储:
在 Windows NT、Windows 2000 和更高版本中,值存储到注册表项。
在 Windows 3.x 中,值存储在 WIN.INI 文件中。
在 Windows 95 和更高版本中,值存储在缓存版的 WIN.INI 中。