2010-11-01 6 views
0

J'ai une question vraiment difficile.MFC, Fichier Nouveau avec boîte de dialogue pour demander des paramètres et plusieurs types de document?

J'ai un programme avec six types différents de Windows MDI.

Une invite de dialogue doit s'afficher pour indiquer les dimensions graphiques (Hauteur, Largeur), puis créer six types différents de fenêtres MDI en fonction du type de graphique.

Question est:

Je l'ai déjà obtenu 6 types de MDI travail (dans une certaine mesure).

Que dois-je faire pour créer un fichier personnalisé | Nouveau pour répondre aux besoins d'un écran de dialogue personnalisé? Par exemple, dans MDI, il existe une boîte de dialogue Fichier | Nouveau générique. Je souhaite personnaliser cela dans MFC.

Répondre

0

Tout d'abord, vous devrez remplacer la fonction CDocument qui gère l'ouverture de nouveaux fichiers; c'est probablement l'un des CDocument::OnNewDocument ou CDocument::OnOpenDocument. Je l'ai aussi fait dans le passé en ajoutant la carte de message suivant à CMainFrame, pas sûr que l'un de la méthode correcte est:

ON_COMMAND(ID_FILE_OPEN, &CMainFrame::OnFileOpen) 

Ensuite, pour afficher une boîte de dialogue Nouveau fichier personnalisé, utilisez la fonction WINAPI GetOpenFileName. Notez que vous devez utiliser cette fonction, CFileDialog du MFC ne fonctionnera pas. Voici un extrait de code de la fonction CMainFrame::OnFileOpen I énuméré ci-dessus dans la carte du message:

/** 
* 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); 
    } 
} 

Dans ce projet, j'ai ajouté 2 ComboBoxes à la boîte de dialogue Ouvrir standard. These Les documents MSDN décrivent comment personnaliser les boîtes de dialogue standard. Ceci est le fichier de ressources (.rc2) personnalisation que je:

// 
// 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 


///////////////////////////////////////////////////////////////////////////// 

Notez que cette méthode de personnalisation est recommandé que si vous programmez pour les versions Windows XP et plus. À partir de Vista MS recommande l'utilisation de l'API Common Item Dialog pour la personnalisation, mais je n'ai jamais utilisé cela.

Questions connexes