У меня есть диалоговое окно, указанное через файл * .rc, который не отображается должным образом на экране. Он демонстрирует следующий набор аномалий:
Помимо аномалии кнопок по умолчанию и странного внешнего вида, диалоговое окно работает так же, как и функция обратного вызова — SelectPuzzle (), которую оно вызывает. Исходный код для SelectPuzzle () не прилагается, но доступен по запросу, как и снимки экрана.
Этот код практически идентичен коду, который я успешно использовал в других проектах. Почему это не работает здесь, остается загадкой. Кто-нибудь может помочь?
Я перепробовал все, что мог придумать, чтобы диагностировать эту ошибку, но безуспешно, например:
Следующие фрагменты кода актуальны:
MainApp.h (included in stdafx.h)
.
.
#define IDD_SELECTPUZZLE 9500
#define IDM_SelectPuzzle 9510
#define ID_CurrentPuzzle 9521
#define ID_SelectedPuzzle 9522
#define ID_PuzzleSelStatus 9523
.
.
PuzzleDB.h (included in stdafx.h)
//=======================================================================
// PuzzleDB.h : Defines the entry point for the application.
//=======================================================================
#pragma once
typedef struct {
int NumberOfPuzzles;
int *PuzzleNumbers;
int ndxCurrentPuzzleNumber;
clasPuzzle *Puzzle;
} PuzzleSelectionData, *pPuzzleSelectionData;
clasPuzzle *ResetPuzzle(
clasPuzzle *Puzzle
);
char *LoadPuzzle(
char *tstr
, int ndxSelectedPuzzle
, pPuzzleSelectionData pPuzzleDB );MainApp.cpp,
#include "stdafx.h".
.
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK SelectPuzzle(HWND, UINT, WPARAM, LPARAM);
.
.
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
.
.
static PuzzleSelectionData PuzzleDB;
.
.
switch (message)
.
.
case WM_COMMAND:
switch (wParam)
.
.
//*****WM_COMMAND********************************************
case IDM_SelectPuzzle:
k = PuzzleDB.ndxCurrentPuzzleNumber;
DialogBoxParam(
hInst
, MAKEINTRESOURCE(IDD_SELECTPUZZLE)
, hWnd, SelectPuzzle
, (unsigned long)(&PuzzleDB));
if (PuzzleDB.ndxCurrentPuzzleNumber != k)
SendMessage(hWnd,WM_COMMAND,IDM_LoadPuzzle,0L);
break;
.
.
AppName.rc
.
.
//**** BEGIN Application specific resources *********************************
//--------------------------------------------------------------------------------
// Application specific resource.
// Menu Dialog item "Select Puzzle"//--------------------------------------------------------------------------------
IDD_SELECTPUZZLE DIALOGEX 4, 4, 126, 74 // Position w.r.t. parent window.
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Select Puzzle"FONT 10, "MS Shell Dlg"BEGIN
ICON IDR_MAINFRAME , IDC_STATIC ,14,14, 21,20
LTEXT "Use Mouse Wheel to Select Puzzle." , IDC_STATIC , 8, 4,118,12,SS_NOPREFIX
LTEXT "Current Puzzle: " , IDC_STATIC , 8,16, 52,12,SS_NOPREFIX
LTEXT "New Selection: " , IDC_STATIC , 8,28, 52,12,SS_NOPREFIX
PUSHBUTTON "Accept" , ID_OK , 8,40, 52, 4,WS_GROUP
DEFPUSHBUTTON "CANCEL" , ID_CANCEL ,66,40, 52, 4,WS_GROUP
LTEXT " " , ID_CurrentPuzzle ,66,16, 52,12,SS_NOPREFIX
LTEXT " " , ID_SelectedPuzzle ,66,28, 52,12,SS_NOPREFIX
LTEXT " " , ID_PuzzleSelStatus, 8,60,110,12,SS_NOPREFIX
END
//**** END Application specific resources ***********************************
Основная проблема в том, что вы вернетесь TRUE
из диалоговой процедуры для всех сообщений. За исключением нескольких специальных сообщений, это означает, что вам не нужна обработка по умолчанию. Таким образом, то, что должно быть сделано, не делается.
Совет для диалогов: серьезно недокументирован, но там, где вам нужно вернуть какое-то конкретное значение для определенного сообщения, используйте SetDlgMsgResult
от <windowsx.h>
или эквивалентный код.
Попутно код может быть значительно упрощен и улучшен
устранение использования предварительно скомпилированных заголовков Visual C ++ нестандартной семантики (для соответствия стандартам и удобства сопровождения),
устранение использования Visual C ++ нестандартно tWinMain
Просто используйте стандарт main
,
устранение использования поддержки Windows 9x (бессмысленно глупая Microsoft T
вещи для струн),
с помощью std::wstring
вместо обработки строки библиотеки C,
и использование широких строковых литералов вместо узких плюс преобразование,
и т.п.
Особенно плохое яблоко, в tWinMain
функционировать этот код:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
InitInstance
имеет смысл только для 16-битной Windows.
прохождение nCmdShow
вокруг имеет смысл только для 16-битной Windows (в 32-битной Windows это игнорируются первым ShowWindow
вызов).
возврате FALSE
здесь ошибочно указывает на успех, когда это провал.
По сути, я видел этот код много раз, даже в поддержке Windows на языке D, и подозреваю, что он создан Microsoft.
В любом случае, откуда вы это ни взяли, этот источник серьезно устарел а также ненадежный, чтобы рассматриваться только как источник вредных привычек программирования и изобретательных способов введения ошибок.
Других решений пока нет …