除非隐藏CFrameWnd,否则文件对话框不会刷新

时间:2016-09-02 13:54:39

标签: c++ winforms mfc refresh openfiledialog

我正在更新一些在Win7或更高版本上无效的旧软件。所以,我正在重建一些使用最新的win32更新的MFC库。

现在我有两个问题:

  1. MessageBox出现在CFrameWnd后面,因此无法访问发送应用程序停止。
  2. 更改文件类型时,打开对话框(无论是基于CFileDialog还是IFileDilog)不会刷新。
  3. 但是,如果隐藏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;
    

1 个答案:

答案 0 :(得分:1)

有一个简单的问题。您覆盖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,它不会导致错误,但会使代码更清晰。