【问题标题】:CFileDialog file name change?CFileDialog 文件名改变?
【发布时间】:2018-08-27 08:58:06
【问题描述】:

我已经成功地将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 。所以和以前一样的问题:我如何知道文件字段的密钥,在应用密钥后如何获取文件字段的值等等。

【问题讨论】:

  • 大概,您会想要收听EN_CHANGE 通知。否则,如果用户使用鼠标界面粘贴文件名,您将不会收到通知。
  • 资源管理器风格的控件标识符是documented
  • 不应该是edt1吗?
  • Spy++报告控件ID为1148,即0x4ED,即cmb13。 (edt1 是 0x480。)这是有道理的,因为我看到了一个组合框。 Andrew thx 为您编辑到我的答案中的资源,但我认为那是用于 edt1 的“旧式”对话框,而不是我与 cmb13 一起使用的“探索器式”,所以我恢复了它。
  • 对于组合框,您必须处理 CBN_EDITCHANGE 通知。虽然我似乎记得,几年前我也在同样的问题上苦苦挣扎,也没有收到更改通知。我最后用丑陋的 hack 设置了一个计时器,并反复查询控件内容。

标签: mfc visual-studio-2017 windows-10 cfiledialog


【解决方案1】:

这个解决方案感觉不太好,但这是我最终得到的:

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 ) );

【讨论】:

    猜你喜欢
    • 2015-04-17
    • 2014-10-02
    • 2011-10-05
    • 2010-11-21
    • 2018-07-29
    • 2015-07-27
    • 2021-09-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多