MFC,文件新建对话框提示参数和多个文档类型?
Posted
技术标签:
【中文标题】MFC,文件新建对话框提示参数和多个文档类型?【英文标题】:MFC, File New with dialog to prompt for paramters and multiple Doc Types? 【发布时间】:2010-11-01 03:52:59 【问题描述】:我有一个非常棘手的问题。
我有一个包含六种不同类型 MDI 窗口的程序。
需要有对话框提示提示图形尺寸(高度、宽度),然后根据图形的种类创建六种不同的MDI窗口。
问题是:
我已经让 6 种 MDI 类型工作(在某种程度上)。
如何创建自定义文件|新建以适应自定义对话框屏幕的需要?
例如,在 MDI 中,有一个通用的文件|新建对话框。我希望在 MFC 中自定义它。
【问题讨论】:
【参考方案1】:首先,您需要覆盖处理打开新文件的CDocument
函数;它可能是CDocument::OnNewDocument
或CDocument::OnOpenDocument
之一。我过去也这样做过,将以下消息映射添加到CMainFrame
,不确定哪个是正确的方法:
ON_COMMAND( ID_FILE_OPEN, &CMainFrame::OnFileOpen )
然后,要显示自定义的新建文件对话框,请使用 WINAPI GetOpenFileName
函数。注意必须使用这个功能,MFC 的CFileDialog
不起作用。这是我在上面的消息映射中列出的CMainFrame::OnFileOpen
函数的代码 sn-p:
/**
* 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 );
在那个项目中,我在标准文件打开对话框中添加了 2 个组合框。 These MSDN 文档描述了如何自定义标准对话框。这是我使用的资源文件 (.rc2) 自定义:
//
// 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 进行自定义,但我从未使用过。
【讨论】:
以上是关于MFC,文件新建对话框提示参数和多个文档类型?的主要内容,如果未能解决你的问题,请参考以下文章
新建一个MFC单文档程序含有菜单和工具栏,又建了一个对话框,如何直接显示对话框?