文件对话框不刷新,除非CFrameWnd被隐藏 [英] File Dialog does not get refreshed unless CFrameWnd is hidden

查看:254
本文介绍了文件对话框不刷新,除非CFrameWnd被隐藏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



现在我有两个问题:



  1. 打开对话框(无论是基于CFileDialog还是IFileDilog)在更改时都不会刷新


  2. 但是,如果CFrameWnd被隐藏,这两个问题都会解决。或者,如果是MessageBox,你不需要隐藏窗口,如果你写:PostMessage(0x118);实际上我不知道为什么。



    这里一定有我遗漏的东西。



    还有另一个问题,当使用OpenFileDialog类继承自IFileDialog。是在关闭此对话框而不选择文件时,应用程序崩溃。

      //  -  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
    #includestdafx.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
    #includestdafx.h
    #includeCMainWnd.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,
    LThis is CMainWnd,
    WS_OVERLAPPEDWINDOW,
    this-> rectDefault,
    NULL,
    NULL,
    0,
    NULL);
    }

    CMainWnd ::〜CMainWnd(){}

    void CMainWnd :: OnPaint()
    {}

    void CMainWnd :: OnLButtonDown(UINT,CPoint)
    {
    MessageBox(LHELLO MFC,LMFC,MB_OK);
    }

    //--CAppWnd.h
    #pragma once

    class CAppWnd:public CWinApp
    {
    public :
    CAppWnd();
    〜CAppWnd();

    BOOL InitInstance();

    DECLARE_MESSAGE_MAP()
    };

    //--CAppWnd.cpp
    #includestdafx.h
    #includeCAppWnd.h
    #includeCMainWnd.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-& gt; ShowWindow(m_nCmdShow);

    return CWinApp :: InitInstance();
    }

    CAppWnd The_App;


    解决方案

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

      void CMainWnd :: OnPaint()
    {
    CFrameWnd :: OnPaint //< = this was missing

    //自定义绘图...
    // CClientDC dc(this);
    //dc.TextOut(0,0,Ltest);
    // dc会自动释放...
    }

    使用 CPaintDC ,它是 BeginPaint的包装器 / EndPaint API

      void CMainWnd :: OnPaint()
    {
    CPaintDC dc(this);

    // custom paint ...
    //dc.TextOut(0,0,Ltest);
    // dc会自动释放...
    }

    在此框架窗口中做任何绘画,然后删除整个 CMainWnd :: OnPaint()函数和相应的 ON_WM_PAINT



    以上更改应该可以解决您的错误。我将重写其余的代码,所以它先调用默认的覆盖。示例:

      #includestdafx.h
    #includeresource.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所有文件| *。* |
    L文本文件| * .txt; *。txt || );
    if(dlg.DoModal()== IDOK)
    MessageBox(dlg.GetPathName(),LMFC,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,LThis is CMainWnd,
    WS_OVERLAPPEDWINDOW,CFrameWnd :: rectDefault,NULL,NULL,0,NULL);
    frame-> ShowWindow(m_nCmdShow);
    m_pMainWnd = frame;
    return TRUE;
    }

    CAppWnd The_App;请注意,您可以直接调用静态成员,例如 CFrameWnd ::


    $ b < rectDefault
    ,它不会导致错误,但它使代码更清晰。


    I am updating some old software that does not work on Win7 or later. so, I am rebuilding some MFC libraries that are using latest win32 updates.

    Now I have two issues:

    1. MessageBox appears behind the CFrameWnd so it can't be accessed sending the application to halt.
    2. Open dialog box (whether is based on CFileDialog or IFileDilog) does not get refreshed when changing the file type.

    However, both problems are solved if the CFrameWnd is hidden. or, in case of MessageBox, you will not need to hide the window if you write: PostMessage(0x118); which in fact I don't know why.

    There must be something I am missing Here.

    I also Have another problem when using the OpenFileDialog class that inherits from the IFileDialog. is when closing this dialog without picking up a file, the application Crashes.

    //--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;
    

    解决方案

    There was a simple problem. You override OnPaint but didn't call the default procedure. OnPaint handles to WM_PAINT message, it doesn't forgive this error.

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

    Or you can use CPaintDC which is a wrapper for BeginPaint/EndPaint API

    void CMainWnd::OnPaint()
    { 
        CPaintDC dc(this);
    
        //custom paint...
        //dc.TextOut(0, 0, L"test");
        //dc is automatically released...
    }
    

    If you don't do any painting in this frame window then remove the whole CMainWnd::OnPaint() function and the correspoonding ON_WM_PAINT message.

    Above change should fix your error. I would rewrite the rest of the code so it calls the default override first. Example:

    #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;
    

    Note that you can call up static members directly, for example CFrameWnd::rectDefault, it doesn't cause an error either way but it makes the code more clear.

    这篇关于文件对话框不刷新,除非CFrameWnd被隐藏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆