我已经成功地对CFileDialog
进行了子类化,并添加了一个区域,其中包含一些使用SetTemplate()
控制加载/保存文件格式的控件。我的控制消息处理程序正在被正确调用。
根据输入的文件名,我的控件可能需要更新。单击文件列表时收到OnFileNameChange()
,更改文件类型组合框时收到OnTypeChange()
。
但是,只需键入文件名,我该如何获得通知?
我尝试在这个PreTranslateMessage()
子类中添加CFileDialog
,但它没有被调用任何东西。我知道如何检查pMsg->message == WM_KEYDOWN
但如果我检测到一个,我怎么知道它是在文件输入字段中按下的键?由于密钥还没有得到控制,GetEditBoxText()
,GetFileName()
等不起作用......
我也尝试将以下内容添加到构造函数中:
OPENFILENAME& ofn = GetOFN();
ofn.lpfnHook = &OFNHook;
使用功能:
UINT_PTR CALLBACK OFNHook( HWND hdlg, UINT uiMsg,
WPARAM wParam, LPARAM lParam ) {
if ( uiMsg == WM_KEYDOWN )
MyLogging( "here" );
return 0;
}
OFNHook()
被召唤了很多,但uiMsg
永远不等于WM_KEYDOWN
。与以前一样的问题:我如何知道密钥是否为文件字段,如何在应用密钥后获取该文件字段的值等等。
答案 0 :(得分:0)
此解决方案感觉不太好,但这就是我最终得到的结果:
1)设置一个计时器:
BOOL WinTableEditFileDialog::OnInitDialog() {
// There doesn't seem to be a way to get events for changes in the edit
// field, so instead we check it on a timer.
timerid = SetTimer( 1, 100, NULL );
}
2)在计时器中,使用GetPathName()获取驱动器,目录路径,有时还获取文件名。然后,如果用户正在编辑文本,请使用GetWindowText()获取文本字段中的确切文本。有时,GetPathName()返回实时编辑(看来,当上面没有选择文件时),有时则没有。因此,我检查了一下两半,然后从一个或另一个或两者中得出结果。
void WinTableEditFileDialog::OnTimer( UINT_PTR nIdEvent ) {
CComboBox* pcombo = (CComboBox*) GetParent()->GetDlgItem( cmb1 );
// GetPathName() often doesn't update on text field edits, such as when
// you select a file with the mouse then edit by hand. GetWindowText()
// does respond to edits but doesn't have the path. So we build the full
// name by combining the two.
char szFull[1024];
strncpy( szFull, sizeof( szFull ), GetPathName() );
szFull[ sizeof( szFull ) - 1 ] = '\0';
char* pcFile = strrchr( szFull, '\\' );
if ( pcFile )
pcFile++; // skip slash
else
pcFile = szFull;
CComboBox* pcomboFileName = (CComboBox*) GetParent()->GetDlgItem( cmb13 );
pcomboFileName->GetWindowText( pcFile, sizeof( szFull ) - ( pcFile-szFull ) );
// If the user has typed a full path, then we don't need GetPathName();
if ( isalpha( pcFile[0] ) && pcFile[1] == ':' )
pcomboFileName->GetWindowText( szFull, sizeof( szFull ) );