Reputation: 2422
I've successfully subclassed a CFileDialog
and added an area with a few controls that control load/save file format using SetTemplate()
. My control message handlers are being called correctly.
Depending on the file name typed, my controls may need to update. I'm getting OnFileNameChange()
when the file list is clicked, and OnTypeChange()
when the file type combo box is altered.
However, when a file name is simply typed, how can I get notification?
I've tried adding a PreTranslateMessage()
to this CFileDialog
subclass, but it's not getting called for anything. I know how to check pMsg->message == WM_KEYDOWN
but if I detect one, how would I know that it was a key pressed in the file input field? And since the key hasn't gotten to the control yet, GetEditBoxText()
, GetFileName()
etc. won't work...
I've also tried add the following to my constructor:
OPENFILENAME& ofn = GetOFN();
ofn.lpfnHook = &OFNHook;
With the function:
UINT_PTR CALLBACK OFNHook( HWND hdlg, UINT uiMsg,
WPARAM wParam, LPARAM lParam ) {
if ( uiMsg == WM_KEYDOWN )
MyLogging( "here" );
return 0;
}
OFNHook()
was called a lot, but uiMsg
never equaled WM_KEYDOWN
. So same questions as before: how do I know the key is for the file field, how do I get that file field's value AFTER the key has been applied, etc.
Upvotes: 1
Views: 741
Reputation: 2422
This solution doesn't feel good but this is what I ended up with:
1) Make a timer:
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) In timer, use GetPathName() to get drive, directory path, and sometimes filename. Then use GetWindowText() to get the exact text in the text field if the user is editing it. Sometimes GetPathName() returns the live edit (it seems, when no file is selected above) and sometimes not. So, I inspect both halves a bit then make a result out of one or the other or both.
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 ) );
Upvotes: 0