File Dialog не обновляется, если CFrameWnd не скрыт

Я обновляю старое программное обеспечение, которое не работает на Win7 или более поздней версии. Итак, я перестраиваю некоторые библиотеки MFC, которые используют последние обновления win32.

Теперь у меня есть две проблемы:

  1. MessageBox появляется за CFrameWnd, поэтому к нему нельзя получить доступ, посылая приложение для остановки.
  2. Открытое диалоговое окно (основано ли на CFileDialog или IFileDilog) не обновляется при изменении типа файла.

Однако обе проблемы решаются, если 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
#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

Решение

Была простая проблема. Вы переопределяете 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в любом случае это не вызывает ошибку, но делает код более понятным.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]