【问题标题】:MFC modeless dialog close immediatelyMFC 无模式对话框立即关闭
【发布时间】:2012-02-09 20:16:03
【问题描述】:

我喜欢编写基于无模式对话框的应用程序,但我遇到了问题。当程序启动时,窗口立即关闭。

当我创建一个模态对话框时,相同的代码可以正常工作。 (DoModal())

Csetkliens.h

#pragma once

#ifndef __AFXWIN_H__
    #error "include 'stdafx.h' before including this file for PCH"
#endif

#include "resource.h"       // main symbols
#include "CsetkliensDlg.h"

class CCsetkliensApp : public CWinApp
{
public:
    CCsetkliensApp();
    virtual BOOL InitInstance();
    DECLARE_MESSAGE_MAP()

private:
    CCsetkliensDlg* dlg;
};

extern CCsetkliensApp theApp;

Csetkliens.cpp

#include "stdafx.h"
#include "Csetkliens.h"
#include "CsetkliensDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

BEGIN_MESSAGE_MAP(CCsetkliensApp, CWinApp)
    ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
END_MESSAGE_MAP()

CCsetkliensApp::CCsetkliensApp()
{
    dlg = NULL;
}

CCsetkliensApp theApp;

BOOL CCsetkliensApp::InitInstance()
{
    INITCOMMONCONTROLSEX InitCtrls;
    InitCtrls.dwSize = sizeof(InitCtrls);
    InitCtrls.dwICC = ICC_WIN95_CLASSES;
    InitCommonControlsEx(&InitCtrls);

    CWinApp::InitInstance();

    if (!AfxSocketInit())
    {
        AfxMessageBox(IDP_SOCKETS_INIT_FAILED);
        return FALSE;
    }

    CShellManager *pShellManager = new CShellManager;

    dlg = new CCsetkliensDlg();
    m_pMainWnd = dlg;
    dlg->Create(CCsetkliensDlg::IDD);
    dlg->ShowWindow(SW_SHOW);


    if (pShellManager != NULL)
    {
        delete pShellManager;
    }

    return FALSE;
}

CsetkliensDlg.h

#pragma once
#include "ConnectDlg.h"

class CCsetkliensDlg : public CDialogEx
{

public:
    CCsetkliensDlg(CWnd* pParent = NULL);
    enum { IDD = IDD_CSETKLIENS_DIALOG };
protected:
    virtual BOOL OnInitDialog();
    DECLARE_MESSAGE_MAP()
};

CsetkliensDlg.cpp

#include "stdafx.h"
#include "Csetkliens.h"
#include "CsetkliensDlg.h"
#include "afxdialogex.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

CCsetkliensDlg::CCsetkliensDlg(CWnd* pParent /*=NULL*/)
    : CDialogEx(CCsetkliensDlg::IDD, pParent)
{
}

BEGIN_MESSAGE_MAP(CCsetkliensDlg, CDialogEx)
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
END_MESSAGE_MAP()

BOOL CCsetkliensDlg::OnInitDialog()
{
    CDialogEx::OnInitDialog();
    return TRUE;
}

【问题讨论】:

  • 我遇到了同样的问题,我什至返回了TRUE!我的问题是 Visual Studio 的默认代码使我的 dlg 成为堆栈上的局部变量,而不是堆上的类成员。当InitInstance 函数退出时,我的dlg 堆栈实例被释放,我收到一条警告,说m_pMainWnd 成员被设置为NULL,导致应用程序终止。

标签: c++ winapi mfc dialog modeless


【解决方案1】:

从应用程序类的InitInstance method 返回FALSE 告诉 MFC 初始化失败并且应用程序应该终止。

将喜欢的内容更改为return TRUE;,一切正常。

BOOL CCsetkliensApp::InitInstance()
{
    INITCOMMONCONTROLSEX InitCtrls;
    InitCtrls.dwSize = sizeof(InitCtrls);
    InitCtrls.dwICC = ICC_WIN95_CLASSES;
    InitCommonControlsEx(&InitCtrls);

    CWinApp::InitInstance();

    if (!AfxSocketInit())
    {
        AfxMessageBox(IDP_SOCKETS_INIT_FAILED);
        return FALSE;
    }

    CShellManager *pShellManager = new CShellManager;

    dlg = new CCsetkliensDlg();
    m_pMainWnd = dlg;
    dlg->Create(CCsetkliensDlg::IDD);
    dlg->ShowWindow(SW_SHOW); // this is not a blocking call!


    if (pShellManager != NULL)
    {
        delete pShellManager;
    }

    return TRUE; // change this one!
}

它与模态对话框一起工作的原因(通过调用DoModal 方法显示)是因为模态对话框创建了自己的消息循环,该循环一直运行到您关闭对话框为止。这意味着执行在DoModal 调用处有效地“阻塞”,而不会将控制权返回给您的InitInstance 方法,因此它不会返回FALSE 并且MFC 不会退出。至少在您关闭对话框之前是这样,在这种情况下您希望它退出,所以一切看起来都正常。

【讨论】:

    【解决方案2】:

    在打开无模式窗口后,我没有看到任何告诉应用程序保持活动状态的内容。您至少需要一个“模态”样式的窗口,或其他东西来控制应用程序的终止。

    【讨论】:

    • 没有。所需要的是一个消息循环,它将向窗口发送消息,无论它们是否是模态的。
    猜你喜欢
    • 2020-02-12
    • 1970-01-01
    • 2020-06-02
    • 2011-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-07
    • 1970-01-01
    相关资源
    最近更新 更多