代码之家  ›  专栏  ›  技术社区  ›  buttercup

MFC,File New with dialog提示输入参数和多个文档类型?

mfc
  •  0
  • buttercup  · 技术社区  · 14 年前

    我有一个有六种不同MDI窗口的程序。

    需要有一个对话框提示来提示图形尺寸(高度、宽度),然后根据图形类型创建六种不同的MDI窗口。

    我已经有6种MDI类型工作(在某种程度上)。

    如何创建自定义文件|新文件以满足自定义对话框屏幕的需要?

    1 回复  |  直到 14 年前
        1
  •  0
  •   Praetorian Luchian Grigore    14 年前

    首先,您需要覆盖 CDocument 处理打开新文件的函数;它可能是 CDocument::OnNewDocument CDocument::OnOpenDocument . 在过去,我还通过将以下消息映射添加到 CMainFrame

    ON_COMMAND( ID_FILE_OPEN, &CMainFrame::OnFileOpen )
    

    然后,要显示自定义的新文件对话框,请使用WINAPI GetOpenFileName 功能。注意,您必须使用这个函数,MFC的 CFileDialog 不会起作用的。下面是来自 CMainFrame::OnFileOpen

    /**
     * Hook procedure for OPENFILENAME structure. This function processes messages from the custom 
     * controls added to the standard "Open File" dialog.
     *
     * @param [in]   hdlg 
     *  handle of the hdlg. 
     * @param [in]   uiMsg 
     *  message describing the user interface. 
     * @param [in]   wParam 
     *  the wParam field of the message. 
     * @param [in]   lParam 
     *  the lParam field of the message. 
     *
     * @return If the return value is zero, the default dialog box procedure processes the message; 
     *         otherwise it ignores the message.
     */
    UINT_PTR CALLBACK OpenHexFileHook( HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam )
    {
      (void)(wParam);
    
      if( !::IsWindow( hdlg ) ) {
        return 0;
      }
    
      switch( uiMsg ) {
        case WM_NOTIFY:
        /* Sent when an event occurs or the custom controls require information */
        {
          LPOFNOTIFY pOfnNotify = (LPOFNOTIFY)lParam;
    
          if( pOfnNotify == NULL ) {
            return 0;
          }
          CWinApp *app  = AfxGetApp();
    
          switch( pOfnNotify->hdr.code ) {
            case CDN_INITDONE:
            /* Sent when the system has finished arranging the controls in the dialog box */
            {
              CString rv;
              LRESULT idx;
    
              /* Configure the Hex file format ComboBox */
              HWND hHexFmt  = GetDlgItem( hdlg, IDC_HEX_FILE_FORMAT );
    
              ASSERT( hHexFmt );
              /* Clear existing content */
              ::SendMessage( hHexFmt, CB_RESETCONTENT, 0, 0 );
              /* Add new items to the list */
              ::SendMessage( hHexFmt, CB_ADDSTRING, 0, (LPARAM)_T("INTEL 32") );
              ::SendMessage( hHexFmt, CB_ADDSTRING, 0, (LPARAM)_T("INTEL 16") );
              ::SendMessage( hHexFmt, CB_ADDSTRING, 0, (LPARAM)_T("INTEL 8") );
              /* Read user's last selection from registry */
              rv  = app->GetProfileString( _T("Settings"), _T("HexFormat"), _T("INTEL 32") );
              idx = ::SendMessage( hHexFmt, CB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)((LPCTSTR)rv) );
              if( idx == CB_ERR ) {
                /* On error select the first item */
                idx = 0;
              }
              /* Set current selection to the previously selected item's index */
              ::SendMessage( hHexFmt, CB_SETCURSEL, idx, 0 );
    
              /* Configure the Bytes per address ComboBox */
              HWND hBytePerLoc = GetDlgItem( hdlg, IDC_BYTES_PER_ADDR );
    
              ASSERT( hBytePerLoc );
              /* Clear existing content */
              ::SendMessage( hBytePerLoc, CB_RESETCONTENT, 0, 0 );
              /* Add new items to the list */
              ::SendMessage( hBytePerLoc, CB_ADDSTRING, 0, (LPARAM)_T("1") );
              ::SendMessage( hBytePerLoc, CB_ADDSTRING, 0, (LPARAM)_T("2") );
              ::SendMessage( hBytePerLoc, CB_ADDSTRING, 0, (LPARAM)_T("4") );
              /* Read user's last selection from registry */
              rv  = app->GetProfileString( _T("Settings"), _T("BytesPerAddr"), _T("1") );
              idx = ::SendMessage( hBytePerLoc, CB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)((LPCTSTR)rv) );
              if( idx == CB_ERR ) {
                /* On error select the first item */
                idx = 0;
              }
              /* Set current selection to the previously selected item's index */
              ::SendMessage( hBytePerLoc, CB_SETCURSEL, idx, 0 );
              break;
            }
    
            case CDN_FILEOK:
            /* Sent when the user specifies a file name and clicks the OK button */
            {
              /* Save user selection for the Hex file format ComboBox */
              HWND hHexFmt  = GetDlgItem( hdlg, IDC_HEX_FILE_FORMAT );
    
              ASSERT( hHexFmt );
              /* Get current selection's index */
              LRESULT idx = ::SendMessage( hHexFmt, CB_GETCURSEL, 0, 0 );
    
              if( idx != CB_ERR ) {
                /* Get current selection's text length */
                LRESULT len1 = ::SendMessage( hHexFmt, CB_GETLBTEXTLEN, idx, 0 );
    
                if( len1 != CB_ERR ) {
                  TCHAR   *text = new TCHAR[len1 + 1];
                  /* Get current selection's text */
                  LRESULT len2  = ::SendMessage( hHexFmt, CB_GETLBTEXT, idx, (LPARAM)text );
    
                  if( len1 == len2 ) {
                    /* Write string to registry */
                    app->WriteProfileString( _T("Settings"), _T("HexFormat"), text );
                  }
                  delete[] text;
                }
              }
    
              /* Save user selection for the Bytes per address ComboBox */
              HWND hBytePerLoc  = GetDlgItem( hdlg, IDC_BYTES_PER_ADDR );
    
              ASSERT( hBytePerLoc );
              /* Get current selection's index */
              idx = ::SendMessage( hBytePerLoc, CB_GETCURSEL, 0, 0 );
    
              if( idx != CB_ERR ) {
                /* Get current selection's text length */
                LRESULT len1 = ::SendMessage( hBytePerLoc, CB_GETLBTEXTLEN, idx, 0 );
    
                if( len1 != CB_ERR ) {
                  TCHAR   *text = new TCHAR[len1 + 1];
                  /* Get current selection's text */
                  LRESULT len2  = ::SendMessage( hBytePerLoc, CB_GETLBTEXT, idx, (LPARAM)text );
    
                  if( len1 == len2 ) {
                    /* Write string to registry */
                    app->WriteProfileString( _T("Settings"), _T("BytesPerAddr"), text );
                  }
                  delete[] text;
                }
              }
              break;
            }
    
            default:
              /* Do nothing */
              break;
          }
          break;
        }
    
        default:
          /* Do nothing */
          break;
      }
      return 0;
    }
    
    
    void CMainFrame::OnFileOpen()
    {
      std::basic_string<TCHAR> filterSpec;
    
      /* Use *.hex filter */
      filterSpec  = _T("Hex Files (*.hex)");
      filterSpec += (std::basic_string<TCHAR>::value_type)'\0';
      filterSpec += _T("*.hex");
      filterSpec += (std::basic_string<TCHAR>::value_type)'\0';
    
    
      OPENFILENAME ofn                  = { sizeof(ofn) };
      TCHAR        filePath[MAX_PATH]   = { 0 };
      TCHAR        fileTitle[MAX_PATH]  = { 0 };
    
      ofn.hwndOwner           = AfxGetMainWnd()->GetSafeHwnd();
      ofn.hInstance           = AfxGetInstanceHandle();
      ofn.lpstrFilter         = filterSpec.c_str();
      ofn.lpstrCustomFilter   = NULL;
      ofn.nMaxCustFilter      = 0;
      ofn.nFilterIndex        = 1;
      ofn.lpstrFile           = filePath;
      ofn.nMaxFile            = sizeof(filePath) / sizeof(TCHAR);
      ofn.lpstrFileTitle      = fileTitle;
      ofn.nMaxFileTitle       = sizeof(fileTitle) / sizeof(TCHAR);
      ofn.lpstrInitialDir     = NULL;
      ofn.lpstrTitle          = _T("Select Intel HEX file");
      ofn.Flags               = OFN_ENABLETEMPLATE | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | 
                                OFN_EXPLORER | OFN_ENABLESIZING | OFN_DONTADDTORECENT | 
                                OFN_HIDEREADONLY | OFN_ENABLEHOOK;
      ofn.lpstrDefExt         = _T("hex");
      ofn.lCustData           = NULL;
      ofn.lpfnHook            = OpenHexFileHook;
      ofn.lpTemplateName      = MAKEINTRESOURCE(IDD_HEX_FILE_OPEN);
      ofn.FlagsEx             = 0;
    
      if( GetOpenFileName( &ofn ) != false ) {
        AfxGetApp()->m_pDocManager->OpenDocumentFile( ofn.lpstrFile );
    
        SetTitle( ofn.lpstrFileTitle );
      }
    }
    

    在那个项目中,我向标准的文件打开对话框添加了两个组合框。 These

    //
    // HexViewer.RC2 - resources Microsoft Visual C++ does not edit directly
    //
    
    #ifdef APSTUDIO_INVOKED
    #error this file is not editable by Microsoft Visual C++
    #endif //APSTUDIO_INVOKED
    
    
    /////////////////////////////////////////////////////////////////////////////
    // Add manually edited resources here...
    
    /////////////////////////////////////////////////////////////////////////////
    //
    // File Open Dialog Template
    //
    
    IDD_HEX_FILE_OPEN DIALOGEX 0, 0, 370, 40
    STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS
    EXSTYLE WS_EX_CONTROLPARENT
    FONT 8, "MS Shell Dlg", 0, 0, 0x1
    BEGIN
        LTEXT           "&HEX file format:", IDC_HEX_FILE_FORMAT_TEXT, 67, 2, 58, 8, SS_NOTIFY
        COMBOBOX        IDC_HEX_FILE_FORMAT, 130, 0, 164, 100,
                        CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
        LTEXT           "&Bytes per address:", IDC_BYTES_PER_ADDR_TEXT, 67, 20, 63, 8, SS_NOTIFY
        COMBOBOX        IDC_BYTES_PER_ADDR, 130, 18, 164, 100,
                        CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
    END
    
    
    /////////////////////////////////////////////////////////////////////////////
    

    请注意,只有在为Windows XP和旧版本编程时,才建议使用此自定义方法。从Vista开始MS建议使用 Common Item Dialog 用于定制的API,但我从未使用过。

    推荐文章