单击MFC编辑框

时间:2012-07-19 16:21:48

标签: c++ windows mfc

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

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

如果您对如何做到这一点有任何想法,我将非常感激。

3 个答案:

答案 0 :(得分:3)

好莱特先生,我想我会补充一个答案。

首先我会在前面加上我可能只需添加一个按钮名称“...”来启动编辑框右侧的文件对话框,打开文件对话框,因为这是最简单的解决方案和大多数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 animation API中的一些。

答案 1 :(得分:1)

您可以在对话框类中覆盖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派生一个类。

答案 2 :(得分:1)

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

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