目前来说,创建基于对话框的程序,Win32工程基本都能满足要求。现在MFC体积膨胀太厉害了,并且MFC的主要用途是编写框架程序,用它写基于对话框的程序有点杀鸡用牛刀了,其实大部分应用环境下用Win32就够了。Visual Studio 2015对话框设计器里共有28种通用控件可以在Win32工程中使用。
使用这个程序模板,可以开启对话框设计器里的所有通用控件。显然,以下两种控件是不可用的:
1.MFC增强控件(没加载MFC库)
XXXXtiveX控件(实现起来太复杂)如果以后又想加入ActiveX控件了怎么办?用原生方法的话太麻烦,因为添加ActiveX控件需要自己实现各种容器接口,WebBrowser这种复杂的控件的代码量更是可观的,我从网上找了一个例程,数了一下代码至少700行,其中一大半是无用代码。既然我们用Win32的目的是摆脱MFC,回去用MFC显然不划算。目前来看,向Win32工程添加ActiveX控件支持的最简单的办法还是用ATL。
ATL的CAxWindow和CAxDialogImpl可以支持ActiveX控件和包含ActiveX控件的对话框。使用这两个类必须要声明一个CComModule的全局变量以初始化环境,不然加载会失败。(一般使用CAxWindow手动创建,因为现在Visual Studio 2015不允许在非MFC对话框里添加ActiveX控件)
链接器指令:
1.链接XXXXXXXXXXXb2.通过/manifestdependency开关指定使用6.x版本的comctl32.dll,而不是默认的5.82版,不然会显示为2000样式,很多功能没有
显示对话框之前:
XXXXtProcessDPIAware——设置DPI兼容(对话框是矢量界面,高DPI显示基本没什么问题)XXXXInitalize——初始化COM环境XXXXitCommonControls——链接comctl32.dll(其实这只是一个空函数,只是告诉链接器一定要链接XXXXXXXXXXXb而已)XXXXitNetworkAddressControl——加载NetworkAddress控件(吐槽:一个破文本框也要加载?)5.LoadLibrary(L"riched20.dll")——加载RichEdit2.0控件
对话框退出之后:
XXXXeeLibrary——卸载RichEdit2.0控件XXXXUnintialize——卸载COM环境<code class="lang-cpp">#include "stdafx.h"
#include "resource.h"
// 链接comctl32.dll
#pragma comment(lib, "comctl32.lib")
// 指定加载6.x版本的comctl32.dll,而不是5.x版本(5.x版本很多功能没有)
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#include <windows.h>
#include <commctrl.h>
#include <richedit.h>
INT_PTR CALLBACK DlgProc(HWND, UINT, WPARAM, LPARAM);
int APIENTRY wWinMain(HINSTANCE hInst, HINSTANCE hPrevInst,
LPWSTR lpCmdLine, int nCmdShow)
{
SetProcessDPIAware(); // 设置DPI兼容
CoInitialize(NULL); // 初始化COM
InitCommonControls(); // 链接comctl32.dll
InitNetworkAddressControl(); // 加载NetworkAddress控件
HMODULE hriched20 = LoadLibrary(L"riched20.dll"); // 加载RichEdit2.0控件
int retval = DialogBox(NULL, (LPCTSTR)IDD_DIALOG1, NULL, DlgProc);
FreeLibrary(hriched20); // 卸载RichEdit2.0控件
CoUninitialize(); // 卸载COM
return retval;
}
INT_PTR CALLBACK DlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
case IDCANCEL:
EndDialog(hwnd, LOWORD(wParam));
return TRUE;
}
break;
case WM_CLOSE:
EndDialog(hwnd, 0);
return TRUE;
}
return FALSE;
}</richedit.h></commctrl.h></windows.h></code>
200字以内,仅用于支线交流,主线讨论请采用回复功能。