简体   繁体   中英

Clicking in an MFC edit box

I've created a read-only edit box in an MFC dialog box. I'm trying to have it so a user clicks in the edit box, which is read-only, it opens a file dialog, and then puts this value into the text box using UpdateData. I'm catching the ON_EN_SETFOCUS message but pressing OK on the file dialog respawns it, so I get caught in an infinite loop.

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

If you've got any ideas on how this should be done, I would be very grateful.

Alright Mr. Lister I guess I'll add an answer.

First off I would preface this with I would probably simply add a button name "..." to launch the file dialog to the right of the edit box for opening the file dialog as that's the simplest solution and what most windows users will expect.

Another option however is to extend an MFC control. When deciding to extend a control you want to pick one that mostly has the desired behavior and that has a virtual destructor which lends itself to being a subclass. Since you want button like behavior CButton may be a good choice.

Your class interface might look something like this:

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

You can add as much or as little customization as you want depending on if the control will be created dynamically, via the resource file, or whatever. The basic idea being that you display the currently selected file name on the button while storing the full path for other uses as a member so the user doesn't need to see the clutter of a long path with nested directories.

If you don't like the way it looks by default you can override OnPaint and handle WM_PAINT messages and use a custom font, size, or add ellipsis for a long file title. You could also handle re-sizing the button to fit the file title by using text metrics and GetTextExtent to ensure the name fits or simply display a CToolTipCtrl when they hover the mouse over the button so they can see the full name. The CMFCButton from the MFC feature pack in VS2008+ has tool tip functionality built in so if you inherit from that instead of CButton displaying a tool tip would be as simple as calling SetTooltip(m_path)

If you want to get really fancy you could use some of the uxtheme API or new windows animation API .

You can override PreTranslateMessage() in your dialog class, and determine if the edit control was clicked that way:

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

Update: You can also (and it may be a better idea) to override your CEdit control's CWnd::PreTranslateMessage() function. This would require deriving a class from CEdit.

If you are using VS2008 SP1 or above, the easiest way to ask for a path is with CMFCEditBrowseCtrl . It displays an edit control with a button. The steps to use it are:

  • Change your edit control's class to CMFCEditBrowseCtrl
  • Call EnableFileBrowseButton to tell it that you want to browse for files, not folders (you can set a filter and default extension)
  • When the user clicks the button, a file dialog appears, and when you click OK in it, the selected path is written in the edit control.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM