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

File Dialog does not get refreshed unless CFrameWnd is hidden

本文关键字:对话框 文件 刷新 隐藏 cframewind      更新时间:2023-10-16

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

现在我有两个问题:

  1. MessageBox出现在cframewind后面,所以它不能被访问,发送应用程序停止。
  2. 打开对话框(无论是基于CFileDialog还是IFileDilog)在更改文件类型时不刷新

然而,如果隐藏cframewind,这两个问题都解决了。或者,在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,它不会导致错误,但它使代码更清晰。