添加另一个VC ++对话框导致第二个在控件周围有焦点虚线矩形?

时间:2013-02-20 12:25:42

标签: c++ visual-studio visual-c++ mfc dialog

我制作了一个意外行为的Visual Studio 2012(专业版)项目。当我只有一个对话框时,除了我第一次按TAB或ALT之外,当我使用它们时,控件上没有出现焦点矩形(虚线边框)。当我尝试在主要对话框之前加载另一个对话框(作为初始屏幕)时,主要(第二个)对话框上出现焦点虚线边框执行,它们已经显示在第一个项目上窗口加载。为什么会如此?如何防止这种情况发生?

enter image description here

我唯一的猜测是按ENTER或ESC会导致与按TAB或ALT相同的行为,我总是看到效果,因为用户必须按ENTER或ESC才能关闭启动画面。人们会认为有一种方法可以从控件中移除焦点,但这似乎并不容易。我可以轻松地将焦点设置为控件,但不仅仅是将其删除。

对于那些对示例代码感兴趣的人:


我可以展示我整个项目的代码,但是老实说,自己测试它会更容易。创建一个新的VC ++项目> MFC应用程序,设置为“基于对话框”,完成。在资源视图中,右键单击对话框和“插入对话框”。使它成为与主窗口可识别的不同之处,并添加至少一个可以获得焦点的控件。最后,在主.cpp文件的顶部附近,您将找到文本“// The one and only”...在此下面是一行声明主应用程序对象。在 行下创建一个新的对话框类(对于“启动画面”,您可以在下面看到我的*),然后在主应用程序的InitInstance()内插入代码以加载启动画面就在看起来像这样的部分上方:

CDlg dlg;
m_pMainWnd = &dlg;
INT_PTR nResponse = dlg.DoModal();

我用来显示启动画面的代码是:

CSplashDlg dlgSplash;
dlgSplash.DoModal();

*我的启动对话框代码:

更新:我改变了我的代码,允许先点击对话框,而不是按回车(事实上,我会在某些时候覆盖pretranslatemsg()并捕捉ESC和ENTER。这是我的最新代码:

class CSplashDlg : public CDialogEx
{
public:
    CSplashDlg();
    enum { IDD = IDD_SPLASH };

    protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support

protected:
    DECLARE_MESSAGE_MAP()
public:
    afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
};

CSplashDlg::CSplashDlg() : CDialogEx(CSplashDlg::IDD) {}

void CSplashDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); }

BEGIN_MESSAGE_MAP(CSplashDlg, CDialogEx)
    ON_WM_LBUTTONUP()
END_MESSAGE_MAP()

void CSplashDlg::OnLButtonUp(UINT nFlags, CPoint point)
{
    EndDialog(1);
    CDialogEx::OnLButtonUp(nFlags, point);
}

2 个答案:

答案 0 :(得分:1)

似乎按ESC或ENTER在编程上类似于按TAB或ALT,这样点击任何这些键都会触发控件上的焦点边框。我的解决方案是手动关闭对话框,而不是使用默认的“OK”和“CANCEL”选项,这些选项由于某种原因触发了未来对话框中尚未创建的焦点边框。

我上面粘贴的最新代码是解决方案,作为最后一点,我应该指出,防止用户在对话框中按ENTER或ESC也很重要(即使他们可以点击它也可以这样做现在),所以我使用PreTranslateMessage来抓住那些按键。您可以在使用此方法时仍然允许使用ESCAPE和ENTER来防止原始问题的发生,但它并不像在PreTranslateMessage调用中包含CSplashDlg::EndDialog(1);那么简单(我试过并且失败了)

在我的CSplashDlg类定义中:

virtual BOOL PreTranslateMessage(MSG* pMsg);

我的功能看起来像这样:

BOOL CSplashDlg::PreTranslateMessage(MSG* pMsg) {
    if ( pMsg->message == WM_KEYDOWN ) {
        if ( pMsg->wParam == VK_ESCAPE || pMsg->wParam == VK_RETURN ) {
            pMsg->wParam = NULL;
            //return MAKELONG(0,DC_HASDEFID);
        }
    }
    return CDialog::PreTranslateMessage(pMsg);
}

答案 1 :(得分:0)

在OnInitDialog()的主对话框(不是启动画面)中,将return FALSE;作为最后一个声明