除非隐藏 CFrameWnd,否则文件对话框不会刷新
File Dialog does not get refreshed unless CFrameWnd is hidden
我正在更新一些不能在 Win7 或更高版本上运行的旧软件。因此,我正在重建一些使用最新 win32 更新的 MFC 库。
现在我有两个问题:
- MessageBox 出现在 CFrameWnd 后面,因此无法访问它并发送应用程序停止。
- 打开对话框(无论是基于 CFileDialog 还是 IFileDilog)在更改文件类型时不会刷新。
但是,如果隐藏CFrameWnd,这两个问题都可以解决。或者,对于 MessageBox,如果您编写:PostMessage(0x118),则无需隐藏 window;其实我也不知道为什么。
这里一定有我遗漏的东西。
我在使用继承自 IFileDialog 的 OpenFileDialog class 时还有另一个问题。是在没有选择文件的情况下关闭此对话框时,应用程序崩溃。
//--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...
}
如果您不在此帧中进行任何绘画 window 则删除整个 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
,这两种方式都不会导致错误,但它使代码更清晰。
我正在更新一些不能在 Win7 或更高版本上运行的旧软件。因此,我正在重建一些使用最新 win32 更新的 MFC 库。
现在我有两个问题:
- MessageBox 出现在 CFrameWnd 后面,因此无法访问它并发送应用程序停止。
- 打开对话框(无论是基于 CFileDialog 还是 IFileDilog)在更改文件类型时不会刷新。
但是,如果隐藏CFrameWnd,这两个问题都可以解决。或者,对于 MessageBox,如果您编写:PostMessage(0x118),则无需隐藏 window;其实我也不知道为什么。
这里一定有我遗漏的东西。
我在使用继承自 IFileDialog 的 OpenFileDialog class 时还有另一个问题。是在没有选择文件的情况下关闭此对话框时,应用程序崩溃。
//--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...
}
如果您不在此帧中进行任何绘画 window 则删除整个 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
,这两种方式都不会导致错误,但它使代码更清晰。