我正在更新无法在Win7或更高版本上运行的某些旧软件。因此,我正在重建一些使用最新Win32更新的MFC库。

现在我有两个问题:

  • MessageBox出现在CFrameWnd的后面,因此无法访问,将应用程序暂停。
  • 更改文件类型时,
  • 打开对话框(基于CFileDialog或IFileDilog)不会刷新。

  • 但是,如果隐藏了CFrameWnd,则两个问题都可以解决。或者,对于MessageBox,如果您编写,则无需隐藏窗口:PostMessage(0x118);实际上我不知道为什么。

    这里一定有我想念的东西。

    使用从IFileDialog继承的OpenFileDialog类时,我也遇到另一个问题。是在关闭此对话框而不选择文件时,应用程序崩溃。
    //--targetver.h
            #pragma once
            #include <sdkddkver.h>
    
    //--stdafx.h:
            #ifndef CS_EXTRALEAN
            #define CS_EXTRALEAN
            #endif
            #pragma once
            #include "targetver.h"
            #include<afxwin.h>
            #include<afxext.h>
            #include<afxcmn.h>
    
    //--stdafx.cpp
            #include "stdafx.h"
    
    //--CMainWnd.h
            #pragma once
    
            class CMainWnd : public CFrameWnd
            {
            public:
                CMainWnd();
                ~CMainWnd();
    
                afx_msg void OnPaint();
                afx_msg void OnLButtonDown(UINT, CPoint);
    
                DECLARE_MESSAGE_MAP()
            };
    
    //--CMainWnd.cpp
        #include "stdafx.h"
        #include"CMainWnd.h"
    
        BEGIN_MESSAGE_MAP(CMainWnd, CFrameWnd)
            ON_WM_PAINT()
            ON_WM_LBUTTONDOWN()
        END_MESSAGE_MAP()
    
        CMainWnd::CMainWnd()
            : CFrameWnd()
        {
            CString class_name = AfxRegisterWndClass(
                CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS,
                AfxGetApp()->LoadStandardCursor(IDC_ARROW),
                (HBRUSH)::GetStockObject(BLACK_BRUSH),
                AfxGetApp()->LoadStandardIcon(IDI_ASTERISK));
    
            HRESULT hResult = this->Create(
                class_name,
                L"This is CMainWnd",
                WS_OVERLAPPEDWINDOW,
                this->rectDefault,
                NULL,
                NULL,
                0,
                NULL);
        }
    
        CMainWnd::~CMainWnd() { }
    
        void CMainWnd::OnPaint()
        { }
    
        void CMainWnd::OnLButtonDown(UINT, CPoint)
        {
            MessageBox(L"HELLO MFC", L"MFC", MB_OK);
        }
    
    //--CAppWnd.h
    #pragma once
    
    class CAppWnd : public CWinApp
    {
    public:
        CAppWnd();
        ~CAppWnd();
    
        BOOL InitInstance();
    
        DECLARE_MESSAGE_MAP()
    };
    
    //--CAppWnd.cpp
    #include "stdafx.h"
    #include "CAppWnd.h"
    #include "CMainWnd.h"
    
    BEGIN_MESSAGE_MAP(CAppWnd, CWinApp)
    END_MESSAGE_MAP()
    
    CAppWnd::CAppWnd()
        :CWinApp()
    { }
    
    CAppWnd::~CAppWnd()
    { }
    
    BOOL CAppWnd::InitInstance()
    {
        this->m_pMainWnd = new CMainWnd;
        this->m_pMainWnd->ShowWindow(m_nCmdShow);
    
        return CWinApp::InitInstance();
    }
    
    CAppWnd The_App;
    

    最佳答案

    有一个简单的问题。您覆盖了OnPaint,但没有调用默认过程。 OnPaint处理WM_PAINT消息,它不会原谅此错误。

    void CMainWnd::OnPaint()
    {
        CFrameWnd::OnPaint(); //<= this was missing
    
        //custom paint...
        //CClientDC dc(this);
        //dc.TextOut(0, 0, L"test");
        //dc is automatically released...
    }
    

    或者,您可以使用CPaintDC,它是BeginPaint / EndPaint API的包装器
    void CMainWnd::OnPaint()
    {
        CPaintDC dc(this);
    
        //custom paint...
        //dc.TextOut(0, 0, L"test");
        //dc is automatically released...
    }
    

    如果您没有在此框架窗口中进行任何绘画,则删除整个CMainWnd::OnPaint()函数和相应的ON_WM_PAINT消息。

    进行以上更改可以解决您的错误。我将重写其余代码,以便它首先调用默认覆盖。例:
    #include "stdafx.h"
    #include "resource.h"
    
    class CMainWnd : public CFrameWnd
    {
    public:
        CMainWnd();
        ~CMainWnd();
        afx_msg void OnPaint();
        afx_msg void OnLButtonDown(UINT, CPoint);
        DECLARE_MESSAGE_MAP()
    };
    
    BEGIN_MESSAGE_MAP(CMainWnd, CFrameWnd)
        ON_WM_PAINT()
        ON_WM_LBUTTONDOWN()
    END_MESSAGE_MAP()
    
    CMainWnd::CMainWnd() : CFrameWnd() {}
    CMainWnd::~CMainWnd() {}
    
    void CMainWnd::OnPaint()
    {
        CFrameWnd::OnPaint();
    }
    
    void CMainWnd::OnLButtonDown(UINT f, CPoint pt)
    {
        CFrameWnd::OnLButtonDown(f, pt);
        CFileDialog dlg(TRUE, 0, 0, 0,
            L"All files|*.*|"
            L"Text files|*.txt;*.txt||" , this);
        if (dlg.DoModal() == IDOK)
            MessageBox(dlg.GetPathName(), L"MFC", MB_OK);
    }
    
    class CAppWnd : public CWinApp
    {
    public:
        BOOL InitInstance();
    };
    
    BOOL CAppWnd::InitInstance()
    {
        CWinApp::InitInstance();
        CMainWnd *frame = new CMainWnd;
        CString class_name = AfxRegisterWndClass(
            CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS,
            AfxGetApp()->LoadStandardCursor(IDC_ARROW),
            (HBRUSH)::GetStockObject(BLACK_BRUSH),
            AfxGetApp()->LoadStandardIcon(IDI_ASTERISK));
    
        frame->Create(class_name, L"This is CMainWnd",
            WS_OVERLAPPEDWINDOW, CFrameWnd::rectDefault, NULL, NULL, 0, NULL);
        frame->ShowWindow(m_nCmdShow);
        m_pMainWnd = frame;
        return TRUE;
    }
    
    CAppWnd The_App;
    

    请注意,您可以直接调用静态成员,例如CFrameWnd::rectDefault,这两种方式都不会引起错误,但是会使代码更清晰。

    07-26 00:05