Reputation: 45
I have dialog window specified via a *.rc file that doesn't render properly on the screen. It exhibits the following set of anomalies:
Other than the default pushbutton anomaly and the weird appearance, the Dialog window operates as it should, as does the callback function -- SelectPuzzle() -- that it invokes. The source code for SelectPuzzle() is not enclosed but is available upon request as are screen shots.
This code is virtually identical to code I have used successfully in other projects. Why it doesn't work here remains a mystery. Can anyone help?
I've tried everything I can think of to diagnose this bug but without success, e.g.:
The following code excerpts are relevant:
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 ***********************************
Upvotes: 1
Views: 722
Reputation: 145389
The main problem is that you return TRUE
from the dialog procedure for all messages. Except for a handful of special messages, this indicates that you don't want default handling. Thus things that should be done, are not being done.
Tip for dialogs: seriously underdocumented, but where you need to return some specific value for some specific message, use SetDlgMsgResult
from <windowsx.h>
, or equivalent code.
In passing, the code can be greatly simplified and improved by
removing use of Visual C++ non-standard semantics precompiled headers (for standard-conformance and maintainability),
removing use of Visual C++ non-standard tWinMain
, just use standard main
,
removing use of Windows 9x support (the unmentionably silly Microsoft T
stuff for strings),
using std::wstring
instead of C library string handling,
and using wide string literals instead of narrow ones plus conversion,
etc.
A particularly bad apple, in the tWinMain
function this code:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
InitInstance
only makes sense for 16-bit Windows.
passing nCmdShow
around only makes sense for 16-bit Windows (in 32-bit Windows it is ignored by the first ShowWindow
call).
Returning FALSE
here erroneously indicates success, when it is a failure.
I have seen essentially this code many times, even in the D language's Windows support, and I suspect that it originates with Microsoft.
Anyway, wherever you got that from, that source is seriously outdated and unreliable, to be treated only as a source of bad programming habits and ingenious ways to introduce bugs.
Upvotes: 1