• 自己动手让Visual Studio的Win32向导支持生成对话框程序


    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,可以参考http://msdn.microsoft.com/en-us/library/ms912047(WinEmbedded.10).aspx

    例如英文版的LCID就是1033,简体中文的就是2052。

    html\1033目录下有两个htm文件,AppSettings.htm、和Default.htm,这里先修改AppSettings.htm

    我这里用DW打开AppSettings.htm,然后定位到35行,按下图插入代码:

    这一段就是定义了顶部的图片,依样画葫芦,插入的代码内容如下:

            <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的同学应该知道了吧?这里就是向导对话框中那几单选按钮。还是和之前一样,依样画葫芦。插入的代码内容如下:

                            <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行,按图插入代码:

    插入的代码如下

            WIN_DLG_APP.disabled = true;

    然后定位到425行,由于我们是要创建基于对话框的的程序,所以没理由是空项目。。所以这里不需要添加空项目的开关;插入的代码如图:

    插入的代码如下:

    if (WIN_DLG_APP.checked)
        {
            SUPPORT_ATL.disabled = false;
            support_atl_title.disabled = false;
        }

    定位到526行,插入代码如图:

    插入的代码内容如下:

                if (WIN_DLG_APP.checked)
                {
                    SUPPORT_ATL.disabled = false;
                    support_atl_title.disabled = false;
                }

    定位到第562行,插入代码如图:

    插入的代码如下

    WIN_DLG_APP_IMAGE.style.display = 'none';
        if (WIN_DLG_APP.checked)
        {
            WIN_DLG_APP_IMAGE.style.display = 'block';
            return;
        }

     至此第一个文件修改完了。。好长呐。。。

     继续修改第二个文件default.htm,依然是用DW来打开。定位到11行,插入代码如图:

     插入的代码内容:

    <SYMBOL NAME="WIN_DLG_APP" TYPE=checkbox VALUE=false></SYMBOL>

    定位到342行,插入代码如图:

    顺便吐槽下:微软的coder原来用的是多层嵌套的if。。看着DT。于是我便改成了else if的。。看起来舒服。

    插入的代码内容如下:

    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行,插入代码如图:

    插入代码如下:

            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行,插入代码如图:

    插入代码内容如下:

                case "WIN_DLG":

    定位到192行,插入代码如图:

    然后再定位到241行和261行做同样的修改。又改完一个文件了。。。。

    找到"templates\1033"目录,打开readme.txt,分别定位到22行、73行、88行分别修改成如下文本:

    22行:

    [!if WIN_APP || WIN_DLG_APP]

    73行:

    [!if WIN_APP || WIN_DLG_APP || SUPPORT_MFC]

    88行:

    [!if WIN_APP || WIN_DLG_APP]

    这个文件就完事了,下一个文件resource.h

    将6-17行替换成如下代码:

    [!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",这个头文件的代码如下:

    #pragma once   // Include this header file once per compilation unit
    
    /////////////////////////// chHANDLE_DLGMSG Macro /////////////////////////////
    
    
    // The normal HANDLE_MSG macro in WindowsX.h does not work properly for dialog
    // boxes because DlgProc returns a BOOL instead of an LRESULT (like
    // WndProcs). This chHANDLE_DLGMSG macro corrects the problem:
    #define chHANDLE_DLGMSG(hWnd, message, fn)                 \
       case (message): return (SetDlgMsgResult(hWnd, uMsg,     \
       HANDLE_##message((hWnd), (wParam), (lParam), (fn))))
    
    
    //////////////////////// Dialog Box Icon Setting Macro ////////////////////////
    
    
    // Sets the dialog box icons
    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行:

    [!if WIN_APP || WIN_DLG_APP]

    13行:

    [!if WIN_APP || SUPPORT_MFC || WIN_DLG_APP]

    然后再定位240行,在[!else]之后插入如下代码:

    [!if WIN_DLG_APP]
    #include "CmnHdr.h"
    
    // Global Variables:
    const TCHAR g_szAppName[] = _T("[!output PROJECT_NAME]");    // The application title text
    
    // Forward declarations of functions included in this code module:
    INT_PTR CALLBACK Dlg_Proc(HWND, UINT, WPARAM, LPARAM);
    BOOL Dlg_OnInitDialog(HWND, HWND, LPARAM);
    void Dlg_OnCommand(HWND, int, HWND, UINT);
    
    // entry function
    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;
    }
    
    //
    //  FUNCTION: Dlg_Proc(HWND, UINT, WPARAM, LPARAM)
    //
    //  PURPOSE:  Message handler for Dialog box
    //
    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;
    }
    
    //
    //  FUNCTION: Dlg_OnInitDialog(HWND, HWND, LPARAM)
    //
    //  PURPOSE:  Initialize the dialog box.
    //
    BOOL Dlg_OnInitDialog(HWND hwndDlg, HWND hwndFocus, LPARAM lParam)
    {
        // Sets the dialog box icons
        chSETDLGICONS(hwndDlg, IDI_[!output UPPER_CASE_SAFE_PROJECT_IDENTIFIER_NAME]);
        return TRUE;
    }
    
    //
    //  FUNCTION: Dlg_OnCommand(HWND, int, HWND, UINT)
    //
    //  PURPOSE:  Command message handler for dialog box
    //
    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行的内容替换成如下的代码:

    [!if DLL_APP || WIN_APP || WIN_DLG_APP]
    // Windows Header Files:
    #include <windows.h>
    [!endif]
    [!if WIN_DLG_APP]
    // Message Crackers, Child Control Macros, and API Macros Header file:
    #include <Windowsx.h>
    [!endif]
    [!if WIN_APP || WIN_DLG_APP]

    然后在文件末尾加上下面这段代码:

    #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行:

            [!if WIN_APP || WIN_DLG_APP || SUPPORT_MFC]

    17行:

            [!if WIN_APP || WIN_DLG_APP || SUPPORT_MFC]

    24行:

            [!if WIN_APP || WIN_DLG_APP]

    然后再定位18行,在这行后面加上CmnHdr.h,这样在创建时就会自动把这个文件复制到工程目录下。

    最后一个要修改的文件,root.rc,这是一个资源脚本文件,为了方便,我调整了代码结构,这里将整个文件的代码发出来:

    //Microsoft Visual C++ generated resource script.
    //
    #include "resource.h"
    
    #define APSTUDIO_READONLY_SYMBOLS
    /////////////////////////////////////////////////////////////////////////////
    //
    // Generated from the TEXTINCLUDE 2 resource.
    //
    [!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]
    /////////////////////////////////////////////////////////////////////////////
    //
    // Icon
    //
    
    // Icon with lowest ID value placed first to ensure application icon
    // remains consistent on all systems.
    
    IDI_[!output UPPER_CASE_SAFE_PROJECT_IDENTIFIER_NAME]       ICON         "[!output PROJECT_NAME].ico"
    IDI_SMALL               ICON         "small.ico"
    [!if WIN_DLG_APP]
    
    /////////////////////////////////////////////////////////////////////////////
    //
    // DESIGNINFO
    //
    
    #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    // APSTUDIO_INVOKED
    
    /////////////////////////////////////////////////////////////////////////////
    //
    // Dialog
    //
    
    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]
    /////////////////////////////////////////////////////////////////////////////
    //
    // Menu
    //
    
    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
    
    
    /////////////////////////////////////////////////////////////////////////////
    //
    // Accelerator
    //
    
    IDC_[!output UPPER_CASE_SAFE_PROJECT_IDENTIFIER_NAME] ACCELERATORS
    BEGIN
        "?",            IDM_ABOUT,              ASCII,  ALT
        "/",            IDM_ABOUT,              ASCII,  ALT
    END
    
    /////////////////////////////////////////////////////////////////////////////
    //
    // String Table
    //
    
    STRINGTABLE
    BEGIN
       IDC_[!output UPPER_CASE_SAFE_PROJECT_IDENTIFIER_NAME]   "[!output UPPER_CASE_SAFE_PROJECT_IDENTIFIER_NAME]"
       IDS_APP_TITLE       "[!output PROJECT_NAME]"
    END
    
    /////////////////////////////////////////////////////////////////////////////
    //
    // Dialog
    //
    
    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
    
    /////////////////////////////////////////////////////////////////////////////
    //
    // DESIGNINFO
    //
    
    #ifdef APSTUDIO_INVOKED
    GUIDELINES DESIGNINFO
    BEGIN
        IDD_ABOUTBOX, DIALOG
        BEGIN
            LEFTMARGIN, 7
            RIGHTMARGIN, 163
            TOPMARGIN, 7
            BOTTOMMARGIN, 55
        END
    END
    #endif    // APSTUDIO_INVOKED
    [!endif]
    #ifdef APSTUDIO_INVOKED
    /////////////////////////////////////////////////////////////////////////////
    //
    // TEXTINCLUDE
    //
    1 TEXTINCLUDE
    BEGIN
        "resource.h\0"
    END
    
    2 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
    
    3 TEXTINCLUDE
    BEGIN
        "\r\n"
        "\0"
    END
    
    #endif    // APSTUDIO_INVOKED
    
    
    [!else]
    
    #ifdef APSTUDIO_INVOKED
    /////////////////////////////////////////////////////////////////////////////
    //
    // TEXTINCLUDE
    //
    
    1 TEXTINCLUDE
    BEGIN
        "resource.h\0"
    END
    
    2 TEXTINCLUDE
    BEGIN
        "#include ""afxres.h""\r\n"
        "\0"
    END
    
    3 TEXTINCLUDE
    BEGIN
        "\r\n"
        "\0"
    END
    
    #endif    // APSTUDIO_INVOKED
    
    /////////////////////////////////////////////////////////////////////////////
    //
    // String Table
    //
    
    STRINGTABLE
    BEGIN
       IDS_APP_TITLE       "[!output PROJECT_NAME]"
    END
    
    [!endif]
    #endif
    /////////////////////////////////////////////////////////////////////////////
    
    
    
    #ifndef APSTUDIO_INVOKED
    /////////////////////////////////////////////////////////////////////////////
    //
    // Generated from the TEXTINCLUDE 3 resource.
    //
    [!if SUPPORT_MFC]
    #ifndef _AFXDLL
    #include "[!output MFC_RC_INCLUDE_PREFIX]afxres.rc"
    #endif
    [!endif]
    
    /////////////////////////////////////////////////////////////////////////////
    #endif    // not APSTUDIO_INVOKED

    终于修改完成了,赶紧创建一个新项目试试吧。。。

    测试截图:

    下面提供两份已经改好的文件,直接覆盖即可:

    VS2010英文旗舰版:Generic_for_VS10.7z

    VS2012英文旗舰版:Generic_for_VS11.7z

    以上两份均测试通过,其他版本请自行修改测试。

    欢迎转载本文章,但请标明出处,原文地址:
    http://www.cnblogs.com/hwangbae/archive/2012/07/26/2610469.html
    如果觉得本文对您有帮助,请支持一下,您的支持是我写作最大的动力,谢谢。


  • 相关阅读:
    NC_100_ATOI NC_102_lowestCommonAncestor NC_104_COMPARE_VERSION NC_109_ISLAND_NUM
    Spring自动注入新写法
    NC_91_LONGEST_INCRE_SUBARRY NC_92_LCSII NC_93_LRU
    linux 下vsftpd安装使用
    IDEA Jrebel 激活方法
    Salieri
    长乐集训集合
    [学习笔记]Prufer序列
    [学习笔记]回文算法
    [学习笔记]基础字符串算法
  • 原文地址:https://www.cnblogs.com/hwangbae/p/2610469.html
Copyright © 2020-2023  润新知