Erstellen von Fenster. Einmal geht es, einmal nicht. Gleiche Methode. Warum?
-
Ich erstelle mit CreateWindowEx zwei Fenster. Beim ersten mal wird das Fenster ordentlich erstellt und nach Aufruf von Show und UpdateWindow und Eintritt in die MessageLoop funktioniert alles ordnungsgemäß.
Beim zweiten Fenster, welches ich mit der gleichen Methode erstelle (Copy und Paste, dann entsprechende Anpassungen) kriege ich NULL von CreateWindowEx zurückgeliefert. GetLastError liefert ebenfalls 0 und FormatMessage liefert "Der Vorgang wurde erfolgreich beendet". Wieso geht es einmal und einmal nicht?Hier der relevante Code:
(Initialisiert die WindowClass mit Standard Werten)
const char g_szClassName[] = "myInputDialog"; const char g_szClassName2[] = "myCheckSettingsDialog"; void DiffusionFitDialogT::initWindowClassWithStdValues(WNDCLASSEX &wcex){ ZeroMemory(&wcex, sizeof wcex); wcex.cbSize = sizeof wcex; wcex.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1); wcex.lpszMenuName = NULL; wcex.style = 0;//CS_HREDRAW | CS_VREDRAW; wcex.hIcon = LoadIcon(0, (LPCTSTR)IDI_APPLICATION); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION); wcex.hInstance = hInstance; }
(Erstellt das Fenster, bei dem die Erstellung funktioniert)
int DiffusionFitDialogT::setupInputValuesDlg(void){ WNDCLASSEX wcex; initWindowClassWithStdValues(wcex); wcex.lpfnWndProc = WndProc;//DefWindowProc;// wcex.lpszClassName = g_szClassName; if (!RegisterClassEx(&wcex)){ throw( (LPCSTR)"Error Registering InputValuesWindowClass"); } hWndInputSett = SaveCreateWindowEx(0, g_szClassName, "Input Settings", WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYSMENU, CW_USEDEFAULT, CW_USEDEFAULT, 450, 392, HWND_DESKTOP, NULL, hInstance, NULL ); return 0; }
(Erstellt das Fenster bei dem die Erstellung nicht funktioniert)
int DiffusionFitDialogT::setupCheckSettingsDlg(void){ WNDCLASSEX wcex; initWindowClassWithStdValues(wcex); wcex.lpfnWndProc = WndProc2;//DefWindowProc;// wcex.lpszClassName = g_szClassName2; if (!RegisterClassEx(&wcex)){ throw( (LPCTSTR)"Error Registering CheckSettingsWindowClass"); } hWndCheckSett = SaveCreateWindowEx( 0, g_szClassName2, "Check Diffusion Fit Settings", WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYSMENU, CW_USEDEFAULT, CW_USEDEFAULT, 308, 309, HWND_DESKTOP, NULL, hInstance, NULL ); /*SaveCreateWindowEx(0, WC_BUTTON, ("OK"), WS_VISIBLE | WS_CHILD | WS_TABSTOP | 0x00000001, 45, 244, 75, 23, hWndCheckSett, (HMENU)IDB_CHECKSETTINGS_OK, DiffusionFitDialogT::hInstance, 0); SaveCreateWindowEx(0, WC_BUTTON, ("Abbrechen"), WS_VISIBLE | WS_CHILD | WS_TABSTOP, 188, 244, 75, 23, hWndCheckSett, (HMENU)IDB_CHECKSETTINGS_CANCEL, DiffusionFitDialogT::hInstance, 0); SaveCreateWindowEx(0, WC_LISTBOX, 0, WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_VSCROLL | WS_BORDER | LBS_NOINTEGRALHEIGHT | LBS_NOTIFY, 8, 8, 143, 229, hWndCheckSett, (HMENU)IDL_CHECKSETTINGS_NAMES, DiffusionFitDialogT::hInstance, 0); SaveCreateWindowEx(0, WC_LISTBOX, 0, WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_VSCROLL | WS_BORDER | LBS_NOINTEGRALHEIGHT | LBS_NOTIFY, 150, 8, 143, 229, hWndCheckSett, (HMENU)IDL_CHECKSETTINGS_VALUES, DiffusionFitDialogT::hInstance, 0); */ return 0; }
(Eigene CreateWindowEx mit Fehlerabfrage)
HWND WINAPI SaveCreateWindowEx( DWORD dwExStyle, LPCTSTR lpClassName, LPCTSTR lpWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam ){ HWND hwnd = CreateWindowEx(dwExStyle, lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam); if(NULL == hwnd) { LPVOID lpMsgBuf; LPVOID lpDisplayBuf; DWORD dw = GetLastError(); FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); // Display the error message and exit the process lpDisplayBuf = (LPVOID) LocalAlloc( LMEM_ZEROINIT, (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen(lpWindowName) + 40) * sizeof(TCHAR) ); wsprintf ( (LPTSTR)lpDisplayBuf, TEXT("%s failed with error %d: %s"), lpWindowName, dw, lpMsgBuf ); LocalFree(lpMsgBuf); //ExitProcess(dw); throw((LPCTSTR)lpDisplayBuf); LocalFree(lpDisplayBuf); } return hwnd; }
(Ruft die Routinen zum Erstellen der Fenster auf.)
int DiffusionFitDialogT::setupDiffusionFitDialogs(void){ try{ setupInputValuesDlg(); setupCheckSettingsDlg(); } catch(LPCTSTR strWin){ MessageBox ( NULL, strWin, "Window Creation Failed!", MB_ICONEXCLAMATION | MB_OK ); PostQuitMessage(0); return EXIT_FAILURE; } return EXIT_SUCCESS; }
(Konstruktor der Klasse, welche alle Funktionalität bzgl. der Fenster enthält.
Die jeweilige WndProc wird über einen Wrapper aufgerufen, welcher eine Klasseneigene WndProc aufruft. Dafür brauche ich auch den Zeiger zum aktuellen Objekt)DiffusionFitDialogT::DiffusionFitDialogT( HINSTANCE hInstance, WndProcCallbackFnc_t *InputDialogWndProc, WndProcCallbackFnc_t *CheckSettingsDialogWndProc, DiffusionFitDialogT **thisDialogPtr) { this->hInstance = hInstance; *thisDialogPtr = this; InitCommonControls(); WndProc = InputDialogWndProc; WndProc2 = CheckSettingsDialogWndProc; setupDiffusionFitDialogs(); }
-
Dummheit. Hab den Fehler schon gefunden. War die Windows Procedure vom zweiten Fenster, die eigentlich noch eine DialogProc war und daher TRUE (für eine behandelte DlgMessage) und FALSE(für eine nichtbehandelte DlgMessage) statt 0 (für eine behandelte Window Msg) und den Rückgabewert von DefWndProc(...) (Für eine nichtbehandelte WinMsg) zurückgegeben hat. Da wurde einfach die Message NCREATE nicht behandelt, weil ja die DefWndProc nicht angesprungen wurde und daher Fehler.