点击一个MFC编辑框

我在MFC对话框中创build了一个只读编辑框。 我试图让用户点击编辑框,这是只读的,它打开一个文件对话框,然后使用UpdateData将此值放入文本框中。 我正在捕获ON_EN_SETFOCUS消息,但在文件对话框上按下“确定”重新生成它,所以我陷入了无限循环。

 UpdateData(TRUE); CFileDialog fileDialog(TRUE,NULL, NULL,OFN_HIDEREADONLY|OFN_FILEMUSTEXIST, _T("Text Files(*.txt)|*.txt||")); if( fileDialog.DoModal() == IDOK ) { configFile=fileDialog.GetPathName(); //Note to self, this includes filename, getPathName includes filename and path. } else { return; } UpdateData(FALSE); 

如果您对此有何看法,我将非常感激。

Solutions Collecting From Web of "点击一个MFC编辑框"

好的李斯特先生我想我会添加一个答案。

首先,我会介绍这与我可能只是简单地添加一个按钮名称“…”启动文件对话框的编辑框右侧打开文件对话框,因为这是最简单的解决方案和大多数Windows用户将期望。

另一种选择是扩展MFC控件。 当决定扩展一个控件时,你希望选择一个主要具有所需行为的控件,并且该控件具有一个虚拟析构函数,该虚拟析构函数可以作为子类。 既然你想按钮行为CButton可能是一个不错的选择。

你的类接口可能看起来像这样:

 class CPathButton : public CButton { public: enum { ID /*= IDC_BUTTON1*/ }; const CString GetPath() const; const CString GetFileName() const; const CString GetDirectory() const; const CString GetExtension() const; // other useful methods for setting file filters etc protected: // add ON_CONTROL(BN_CLICKED, ID, &OnClick) or ON_BN_CLICKED(ID, &OnClick) DECLARE_MESSAGE_MAP() // CFileDialog fdlg.DoModal(), m_path = fdlg.GetPathName(), SetWindowText(fdlg.GetFileTitle()), etc afx_msg void OnClick(); // additional message handlers etc private: CString m_path; // save full path for after dialog is closed }; 

您可以根据需要添加尽可能多或者少量的定制,具体取决于控件是通过资源文件动态创建的,还是其他的。 其基本思想是在按钮上显示当前选定的文件名,同时将其他用途的完整路径存储为成员,这样用户不需要看到具有嵌套目录的长路径的混乱。

如果您不喜欢默认情况下的外观,您可以重写OnPaint并处理WM_PAINT消息,并使用自定义字体,大小或为长文件标题添加省略号。 你也可以通过使用文本指标和GetTextExtent来处理重新调整按钮的大小以适应文件标题,以确保名称符合或只是在将鼠标悬停在按钮上时显示CToolTipCtrl ,以便他们可以看到全名。 VS2008 +中的MFC功能包中的CMFCButton具有内置的工具提示功能,所以如果从继承而不是CButton显示工具提示,就像调用SetTooltip(m_path)一样简单,

如果你想得到真正的幻想,你可以使用一些uxtheme API或新的Windows动画API 。

您可以在对话框类中重写PreTranslateMessage() ,并确定编辑控件是否以这种方式单击:

 CEdit m_CEditCtrl; // ... BOOL YourDialogClass::PreTranslateMessage(MSG *pMsg) { if((pMsg->wParam == VK_LBUTTON) && (m_CEditCtrl.m_hWnd == pMsg->hwnd)) { // open your file dialog return TRUE; // Return that the message was translated and doesn't need to be dispatched } return CDialog::PreTranslateMessage(pMsg); } 

更新:你也可以(也许是一个更好的主意)来覆盖你的CEdit控件的CWnd::PreTranslateMessage()函数。 这需要从CEdit派生一个类。

如果您使用VS2008 SP1或更高版本,请求路径的最简单方法是使用CMFCEditBrowseCtrl 。 它显示一个按钮的编辑控件。 使用它的步骤是:

  • 将您的编辑控件的类更改为CMFCEditBrowseCtrl
  • 调用EnableFileBrowseButton来告诉它,你想浏览文件,而不是文件夹(你可以设置一个过滤器和默认的扩展名)
  • 当用户单击该按钮时,将出现一个文件对话框,并在其中单击确定时,选定的路径将写入编辑控件中。