Мне было поручено перенести пользовательский интерфейс нашего продукта на VS2010.Это приложение MFC, изначально написанное на VC6.Я выполнил следующие шаги:
- Преобразовал VDS-файл .dsp, используя VS2010
- Исправлены ошибки компиляции из-за более строгого компилятора VS2010
- Удалены все ссылки проекта на VC6MFC библиотеки и каталоги
Моя проблема в том, что для объекта диалога (на самом деле это объект CPropertyPage) OnInitDialog () не вызывается раньше других методов.Это вызывает исключение, так как OnInitDialog () должен настроить переменные-члены.
Класс диалога (CPAGEViewDefRecordFields) разделен на подклассы из нашего собственного CValidatedPropertyPage, который, в свою очередь, является производным от класса MFC CPropertyPage.Виртуальный метод OnInitDialog () присутствует во всех подклассах.
В версии VS2010, когда DoModal () вызывается на содержащем листе свойств, метод OnInitDialog () класса CPAGEViewDefRecordFields не вызывается.В версии VC6 он вызывается и все работает нормально.
В VC6 я вижу, что сообщение WM_INITDIALOG отправляется и обрабатывается в AfxDlgProc (), который, в свою очередь, затем вызывает OnInitDialog ()объект диалога.
В версии VS2010 первое обрабатываемое сообщение - WM_NOTIFY, а не WM_INITDIALOG.
К сожалению, у меня нет опыта работы с MFC.Что я предполагаю, что что-то изменилось в поведении MFC между версией VC6 и версией VS2010.Однако я не смог найти в сети ничего похожего на это.
Есть еще один шаг миграции, который я пропустил?Должен ли я что-то делать с ресурсами в проекте при выполнении миграции?
Я проверил, что ресурс привязан к правильному файлу cpp, так как я могу дважды щелкнуть страницу свойств и IDE.приводит меня к правильному файлу для класса CPAGEViewDefRecordFields.
Если у кого-либо из вас есть какие-либо идеи, я был бы очень признателен.
Спасибо!Крис.
class CPAGEViewDefRecordFields : public CValidatedPropertyPage
{
public:
// Construction
CPAGEViewDefRecordFields(CWnd* pParent,
CXpViewProp* pViewProp,
CFont* pFont = NULL,
UINT nIDCaption = 0,
BOOL bSumOpRequired = TRUE,
BOOL bMinMaxRequired = TRUE,
BOOL bAllRecords = TRUE,
BOOL bShowInitSel = TRUE,
XLong lLimits = 0,
BOOL bSortSelTree = TRUE,
CXpThreshBaseLogProp* pThreshLogProp = NULL);
~CPAGEViewDefRecordFields();
// Dialog Data
//{{AFX_DATA(CPAGEViewDefRecordFields)
enum { IDD = IDD_VIEW_DEF_RECORD_FIELDS };
//}}AFX_DATA
// Overrides
// ClassWizard generate virtual function overrides
//{{AFX_VIRTUAL(CPAGEViewDefRecordFields)
virtual BOOL OnInitDialog();
//}}AFX_VIRTUAL
virtual BOOL OnSetActive();
virtual BOOL OnKillActive();
virtual void OnOK();
protected:
...
// Generated message map functions
//{{AFX_MSG(CPAGEViewDefRecordFields)
afx_msg void OnPbRemove();
afx_msg void OnPbAdd();
afx_msg void OnDblclkAvailableFields(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnDblclkSelectedFields(NMHDR* pNMHDR, LRESULT* pResult);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
private:
...
ОБНОВЛЕНИЕ:
После некоторой отладки я вижу, в чем проблема.Однако, не будучи программистом MFC, я этого не понимаю.
Я вижу, что OnInitDialog () вызывается для листа свойств и что WM_INITDIALOG затем отправляется из листа свойств в свойство.страницы.однако в какой-то момент во внутреннем устройстве Windows отправляется сообщение WM_NOTIFY, так что это первое полученное сообщение, а не ожидаемое WM_INITDIALOG
Я выделил точки на трассировке стека, прикрепленные -Кто-нибудь может объяснить, почему это происходит?Является ли это нормальным поведением - должен ли я учесть это в будущем?
Я действительно нашел обходной путь, и у него должен быть инициализированный флаг, так что никакой код не выполняется, пока OnInitDialog () не был вызван,Это не лучшее решение, и я боюсь, что это скорее взлом, поэтому я все равно буду признателен за понимание этих сообщений.(По профессии я не программист MFC!)
спасибо!
![stack trace showing WM messages](https://i.stack.imgur.com/tcKOB.jpg)