文章来源 https://www.freesion.com/article/730931766/
Visual Studio的MFC向导可以生成基于对话框的程序,而win32向导却不支持,是不是很不给力呢?虽然VAX可以直接插入对话框的代码段,但还是没有直接生成来得爽,下面就动手来改造吧。
本文所做的修改仅在自己的VS里测试通过,大家修改之前请备份原文件。
那我们需要改什么呢?看图吧:
首先,找到"VS安装目录\VC\VCWizards\AppWiz\Generic\Application",如我电脑上的目录就是
“D:\Program Files\Microsoft Visual Studio 11.0\VC\VCWizards\AppWiz\Generic\Application” 这个目录下就是Win向导的文件了,有四个文件夹,分别是:
不同语言版本的VS,这些目录下会有不同名字的文件夹,都是按LCID来命名,关于LCID,可以参考 MSDN
例如英文版的LCID就是1033,简体中文的就是2052。
html\1033目录下有两个htm文件,AppSettings.htm、和Default.htm,这里先修改AppSettings.htm,
我这里用DW打开AppSettings.htm,然后定位到35行,按下图插入代码:
这一段就是定义了顶部的图片,依样画葫芦,插入的代码内容如下:
1 2 3 <DIV CLASS ="SMALL" ID ="WIN_DLG_APP_IMAGE" STYLE ="DISPLAY:NONE;" > <IMG CLASS ="SMALL" SRC ="..\..\Images\Dialog.gif" ALT ="" BORDER ="0" > </DIV >
这里我为了偷懒,直接将
“D:\Program Files\Microsoft Visual Studio 11.0\VC\VCWizards\AppWiz\MFC\Application\images\Dialog.gif”
复制到
"D:\Program Files\Microsoft Visual Studio 11.0\VC\VCWizards\AppWiz\Generic\Application\images"目录下。
接着,定位到197行,按图插入代码:
看到这里懂点html的同学应该知道了吧?这里就是向导对话框中那几单选按钮。还是和之前一样,依样画葫芦。插入的代码内容如下:
1 2 3 4 5 <INPUT TYPE ="radio" CLASS ="Radio" onPropertyChange ="InitControls();" NAME ="apptype" ID ="WIN_DLG_APP" ACCESSKEY ="B" TITLE ="Creates a dialog-based Windows application. The application files include a <projectname>.cpp file that contains the _tWinMain function, and stdafx.cpp and stdafx.h files that are used to create the precompiled header file." > <DIV CLASS ="itemTextRadioB" ID ="WIN_DLG_APP_DIV" TITLE ="Creates a dialog-based Windows application. The application files include a <projectname>.cpp file that contains the _tWinMain function, and stdafx.cpp and stdafx.h files that are used to create the precompiled header file." > <LABEL FOR ="WIN_DLG_APP" ID ="WIN_DLG_APP_LABEL" > Dialog-<U > b</U > ased windows application</LABEL > </DIV > <BR >
然后再定位到370行,按图插入代码:
插入的代码如下:
1 WIN_DLG_APP.disabled = true ;
然后定位到425行,由于我们是要创建基于对话框的的程序,所以没理由是空项目。。所以这里不需要添加空项目的开关;插入的代码如图:
插入的代码如下:
1 2 3 4 5 if (WIN_DLG_APP.checked){ SUPPORT_ATL.disabled = false ; support_atl_title.disabled = false ; }
定位到526行,插入代码如图:
插入的代码内容如下:
1 2 3 4 5 6 7 if (WIN_DLG_APP.checked){ SUPPORT_ATL.disabled = false ; support_atl_title.disabled = false ; }
定位到第562行,插入代码如图:
插入的代码如下:
1 2 3 4 5 6 WIN_DLG_APP_IMAGE.style.display = 'none' ; if (WIN_DLG_APP.checked) { WIN_DLG_APP_IMAGE.style.display = 'block' ; return ; }
至此第一个文件修改完了。。好长呐。。。
继续修改第二个文件default.htm,依然是用DW来打开。定位到11行,插入代码如图:
插入的代码内容:
1 <SYMBOL NAME ="WIN_DLG_APP" TYPE =checkbox VALUE =false > </SYMBOL >
定位到342行,插入代码如图:
顺便吐槽下:微软的coder原来用的是多层嵌套的if。。看着DT。于是我便改成了else if的。。看起来舒服。
插入的代码内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 var L_APPTYPEWIN_DLG_TEXT = "Dialog-based windows application" ; if (window .external.FindSymbol("DLL_APP" )) { APPTYPE.innerText = L_APPTYPEDLL_TEXT; } else if (window .external.FindSymbol("CONSOLE_APP" )) { APPTYPE.innerText = L_APPTYPECON_TEXT; } else if (window .external.FindSymbol("LIB_APP" )) { APPTYPE.innerText = L_APPTYPELIB_TEXT; } else if (window .external.FindSymbol("WIN_DLG_APP" )) { APPTYPE.innerText = L_APPTYPEWIN_DLG_TEXT; } else { APPTYPE.innerText = L_APPTYPEWIN_TEXT; }
hoho,第二个文件改好了。
此时打开向导就可以看到已经添加好了,剩下的就是修改代码模板了,继续吧。
打开"scripts\1033\default.js",定位到96行,插入代码如图:
插入代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 if (wizard.FindSymbol("CONSOLE_APP" )) { strAppType = "CONSOLE" ; } else if (wizard.FindSymbol("WIN_APP" )) { strAppType = "WIN" ; } else if (wizard.FindSymbol("WIN_DLG_APP" )) { strAppType = "WIN_DLG" ; } else if (wizard.FindSymbol("DLL_APP" )) { strAppType = "DLL" ; } else if (wizard.FindSymbol("LIB_APP" )) { strAppType = "LIB" ; }
然后再定位到176行,插入代码如图:
插入代码内容如下:
定位到192行,插入代码如图:
然后再定位到241行和261行做同样的修改。又改完一个文件了。。。。
找到"templates\1033"目录,打开readme.txt,分别定位到22行、73行、88行分别修改成如下文本:
22行:
1 [!if WIN_APP || WIN_DLG_APP]
73行:
1 [!if WIN_APP || WIN_DLG_APP || SUPPORT_MFC]
88行:
1 [!if WIN_APP || WIN_DLG_APP]
这个文件就完事了,下一个文件resource.h
将6-17行替换成如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 [!if !WIN_DLG_APP] #define IDS_APP_TITLE 103 [!endif] [!if WIN_APP || WIN_DLG_APP] [!if WIN_APP] #define IDR_MAINFRAME 128 #define IDD_ABOUTBOX 103 #define IDM_ABOUT 104 #define IDM_EXIT 105 #define IDC_[!output UPPER_CASE_SAFE_PROJECT_IDENTIFIER_NAME] 109 #define IDC_MYICON 2 [!endif] #define IDD_[!output UPPER_CASE_SAFE_PROJECT_IDENTIFIER_NAME]_DIALOG 102 #define IDI_[!output UPPER_CASE_SAFE_PROJECT_IDENTIFIER_NAME] 107 #define IDI_SMALL 108
接下来需要先在这个目录下创建一个文件,名为"CmnHdr.h",这个头文件的代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #pragma once #define chHANDLE_DLGMSG(hWnd, message, fn) \ case (message): return (SetDlgMsgResult (hWnd, uMsg, \ HANDLE_##message((hWnd), (wParam), (lParam), (fn)))) inline void chSETDLGICONS (HWND hWnd, int idi) { SendMessage (hWnd, WM_SETICON, ICON_BIG, (LPARAM) LoadIcon ((HINSTANCE) GetWindowLongPtr (hWnd, GWLP_HINSTANCE), MAKEINTRESOURCE (idi))); SendMessage (hWnd, WM_SETICON, ICON_SMALL, (LPARAM) LoadIcon ((HINSTANCE) GetWindowLongPtr (hWnd, GWLP_HINSTANCE), MAKEINTRESOURCE (idi))); }
看过《Windows 核心编程》的都应该见过上面这段代码吧。作用我就不解释了。
接着修改root.cpp,这个文件里就引用到了刚才上一步添加的头文件,定位到第4行和第13行,修改成如下代码:
4行:
1 [!if WIN_APP || WIN_DLG_APP]
13行:
1 [!if WIN_APP || SUPPORT_MFC || WIN_DLG_APP]
然后再定位240行,在[!else]之后插入如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 [!if WIN_DLG_APP] #include "CmnHdr.h" const TCHAR g_szAppName[] = _T("[!output PROJECT_NAME]" ); INT_PTR CALLBACK Dlg_Proc(HWND, UINT, WPARAM, LPARAM); BOOL Dlg_OnInitDialog(HWND, HWND, LPARAM); void Dlg_OnCommand(HWND, int, HWND, UINT); int APIENTRY _tWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPTSTR lpCmdLine, _In_ int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); INT_PTR nResult = DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_[!output UPPER_CASE_SAFE_PROJECT_IDENTIFIER_NAME]_DIALOG), NULL, Dlg_Proc, _ttoi(lpCmdLine)); return nResult; } INT_PTR CALLBACK Dlg_Proc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { chHANDLE_DLGMSG(hwndDlg, WM_INITDIALOG, Dlg_OnInitDialog); chHANDLE_DLGMSG(hwndDlg, WM_COMMAND, Dlg_OnCommand); } return FALSE; } BOOL Dlg_OnInitDialog(HWND hwndDlg, HWND hwndFocus, LPARAM lParam) { chSETDLGICONS(hwndDlg, IDI_[!output UPPER_CASE_SAFE_PROJECT_IDENTIFIER_NAME]); return TRUE; } void Dlg_OnCommand(HWND hwndDlg, int id, HWND hwndCtl, UINT codeNotify){ switch (id) { case IDOK: case IDCANCEL: EndDialog(hwndDlg, id); break ; default :break ; } } [!endif]
又一文件改好,继续下一个文件stdafx.h,将38行-43行的内容替换成如下的代码:
1 2 3 4 5 6 7 8 9 [!if DLL_APP || WIN_APP || WIN_DLG_APP] #include <windows.h> [!endif] [!if WIN_DLG_APP] #include <Windowsx.h> [!endif] [!if WIN_APP || WIN_DLG_APP]
然后在文件末尾加上下面这段代码:
1 2 3 4 5 6 7 8 9 #ifdef _UNICODE #if defined _M_IX86 #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"" ) #elif defined _M_X64 #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"" ) #else #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"" ) #endif #endif
目的是为了在UNICODE环境下支持XP/Vista/Win7的样式.
然后再修改下一个文件,Templates.inf,将13行、17行、24行修改成如下代码:
13行:
1 [!if WIN_APP || WIN_DLG_APP || SUPPORT_MFC]
17行:
1 [!if WIN_APP || WIN_DLG_APP || SUPPORT_MFC]
24行:
1 [!if WIN_APP || WIN_DLG_APP]
然后再定位18行,在这行后面加上CmnHdr.h,这样在创建时就会自动把这个文件复制到工程目录下。
最后一个要修改的文件,root.rc,这是一个资源脚本文件,为了方便,我调整了代码结构,这里将整个文件的代码发出来:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 #include "resource.h" #define APSTUDIO_READONLY_SYMBOLS [!if WIN_APP || WIN_DLG_APP] #ifndef APSTUDIO_INVOKED #include "targetver.h" #endif #define APSTUDIO_HIDDEN_SYMBOLS #include "windows.h" #undef APSTUDIO_HIDDEN_SYMBOLS [!else ] #include "afxres.h" [!endif] #undef APSTUDIO_READONLY_SYMBOLS #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_[!output LANG_SUFFIX]) LANGUAGE [!output PRIMARY_LANG_ID], [!output SUB_LANG_ID] [!if WIN_APP || WIN_DLG_APP] IDI_[!output UPPER_CASE_SAFE_PROJECT_IDENTIFIER_NAME] ICON "[!output PROJECT_NAME].ico" IDI_SMALL ICON "small.ico" [!if WIN_DLG_APP] #ifdef APSTUDIO_INVOKED GUIDELINES DESIGNINFO BEGIN IDD_[!output UPPER_CASE_SAFE_PROJECT_IDENTIFIER_NAME]_DIALOG, DIALOG BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 313 TOPMARGIN, 7 BOTTOMMARGIN, 193 END END #endif IDD_[!output UPPER_CASE_SAFE_PROJECT_IDENTIFIER_NAME]_DIALOG DIALOGEX 0 , 0 , 320 , 200 STYLE DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME EXSTYLE WS_EX_APPWINDOW CAPTION "[!output PROJECT_NAME]" FONT 8 , "MS Shell Dlg" BEGIN DEFPUSHBUTTON "OK" ,IDOK,209 ,179 ,50 ,14 PUSHBUTTON "Cancel" ,IDCANCEL,263 ,179 ,50 ,14 CTEXT "TODO: Place dialog controls here." ,IDC_STATIC,10 ,96 ,300 ,8 END [!else ] IDC_[!output UPPER_CASE_SAFE_PROJECT_IDENTIFIER_NAME] MENU BEGIN POPUP "&File" BEGIN MENUITEM "E&xit" , IDM_EXIT END POPUP "&Help" BEGIN MENUITEM "&About ..." , IDM_ABOUT END END IDC_[!output UPPER_CASE_SAFE_PROJECT_IDENTIFIER_NAME] ACCELERATORS BEGIN "?" , IDM_ABOUT, ASCII, ALT "/" , IDM_ABOUT, ASCII, ALT END STRINGTABLE BEGIN IDC_[!output UPPER_CASE_SAFE_PROJECT_IDENTIFIER_NAME] "[!output UPPER_CASE_SAFE_PROJECT_IDENTIFIER_NAME]" IDS_APP_TITLE "[!output PROJECT_NAME]" END IDD_ABOUTBOX DIALOGEX 0 , 0 , 170 , 62 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "About [!output PROJECT_NAME]" FONT [!output DLG_FONT_SIZE], "[!output DLG_FONT_NAME]" BEGIN ICON IDR_MAINFRAME,IDC_STATIC,14 ,14 ,21 ,20 LTEXT "[!output PROJECT_NAME], Version 1.0" ,IDC_STATIC,42 ,14 ,114 ,8 ,SS_NOPREFIX LTEXT "Copyright (C) [!output YEAR]" ,IDC_STATIC,42 ,26 ,114 ,8 DEFPUSHBUTTON "OK" ,IDOK,113 ,41 ,50 ,14 ,WS_GROUP END #ifdef APSTUDIO_INVOKED GUIDELINES DESIGNINFO BEGIN IDD_ABOUTBOX, DIALOG BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 163 TOPMARGIN, 7 BOTTOMMARGIN, 55 END END #endif [!endif] #ifdef APSTUDIO_INVOKED TEXTINCLUDE BEGIN "resource.h\0" END TEXTINCLUDE BEGIN "#ifndef APSTUDIO_INVOKED\r\n" "#include " "targetver.h" "\r\n" "#endif\r\n" "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" "#include " "windows.h" "\r\n" "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" "\0" END TEXTINCLUDE BEGIN "\r\n" "\0" END #endif [!else ] #ifdef APSTUDIO_INVOKED TEXTINCLUDE BEGIN "resource.h\0" END TEXTINCLUDE BEGIN "#include " "afxres.h" "\r\n" "\0" END TEXTINCLUDE BEGIN "\r\n" "\0" END #endif STRINGTABLE BEGIN IDS_APP_TITLE "[!output PROJECT_NAME]" END [!endif] #endif #ifndef APSTUDIO_INVOKED [!if SUPPORT_MFC] #ifndef _AFXDLL #include "[!output MFC_RC_INCLUDE_PREFIX]afxres.rc" #endif [!endif] #endif
终于修改完成了,赶紧创建一个新项目试试吧。。。
测试截图: