Jump to content
  • Advertisement
Sign in to follow this  
BrickInTheWall

Win32 Modeless Dialog is being a jerk.

This topic is 3162 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi guys, I'm going apeshit over a modeless dialog I'm trying to create. I don't know what I'm doing wrong but it's completely breaking my application. It's just supposed to be an about-box with an ok button, but nooo, the "Ok" button doesn't even show, and the whole program acts weird. I created a template in memory rather than use a resource since I don't have an editor and I'd like to learn how they are built. I tested the template in modal mode using DialogBoxIndirect and everything worked fine. Now I use CreateDialogIndirect and add a few changes and everything screws up, and I don't know why. here is my WndProc function in main.cpp:
...

// Global handles.
HWND hDlgHelpAbout = NULL;

...

// Window Procedure function definition.
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg)
	{
		case WM_CREATE:
			// Create the menu.
			initMenu(hWnd);
		break;

		case WM_COMMAND:
		{
			switch (LOWORD(wParam))
			{
				case ID_HELP_ABOUT:
					if (!IsWindow(hDlgHelpAbout))
					{
						// Create "About" dialog.
						LPDLGTEMPLATE lpDlgTemp = createHelpAbout(hWnd);
						hDlgHelpAbout = CreateDialogIndirect(GetModuleHandle(NULL), lpDlgTemp, hWnd, (DLGPROC)helpAboutProc);
						GlobalFree(lpDlgTemp);

						// Show it too.
						ShowWindow(hDlgHelpAbout, SW_SHOW);
					}
					break;
				case ID_FILE_EXIT:
					PostMessage(hWnd, WM_CLOSE, 0, 0);
					break;
			}
		}
		break;

		case WM_CLOSE:
			DestroyWindow(hWnd);
			break;

		case WM_DESTROY:
			DestroyWindow(hDlgHelpAbout);
			PostQuitMessage(0);
			break;

		default:
			return DefWindowProc(hWnd, msg, wParam, lParam);
	}

	return 0;
}
and here are the function I use to create the template and the dialogs procedure function (in another .cpp file):
#include <windows.h>
#include "ids.h"
#include "dialogTemplate.h"
#include "dialogFunctions.h"

BOOL CALLBACK helpAboutProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg)
	{
		case WM_COMMAND:
			switch (LOWORD(wParam))
			{
				case IDOK:
					DestroyWindow(hWnd);
					return TRUE;
			}

		case WM_DESTROY:
			PostQuitMessage(0);
			return TRUE;

		case WM_CLOSE:
			DestroyWindow(hWnd);
			return TRUE;
	}

	return FALSE;
}

LPDLGTEMPLATE createHelpAbout(HWND hWnd)
{
	// Handle to the memory.
	HANDLE hGlobal = GlobalAlloc(GMEM_ZEROINIT, 1024);

	LPWORD lpw = createDlgHeader(hGlobal, "About", DS_SETFONT | DS_CENTER | DS_3DLOOK | WS_POPUP | WS_SYSMENU | DS_MODALFRAME | WS_CAPTION, 1, 8, "MS Sans Serif", 0, 0, 319, 47);
	lpw = createDlgCtrl(lpw, BUTTON_CLASS, IDOK, "Ok", WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_DEFPUSHBUTTON, 264, 7, 48, 15);

	return (LPDLGTEMPLATE)hGlobal;
}
I know I should be setting hDlgHelpAbout to NULL in the WM_CLOSE of the dialogs procedure, but I'll take care of that later, that can't be the problem. That should only hinder it from being created again. Also, the close buttons (the "X") doesn't work either. Anyone know why this might be? Cheers

Share this post


Link to post
Share on other sites
Advertisement
Need to see where you call CreateDialog() and your message loop. Also you should put a "return FALSE;" after the switch statement in the WM_COMMAND handler in helpAboutProc().

Share this post


Link to post
Share on other sites
My message loop:


while (GetMessage(&msg, hWnd, 0, 0) > 0)
{
if (!IsDialogMessage(hDlgHelpAbout, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}



I call CreateDialogIndirect in the case ID_HELP_ABOUT of my main windows procedure function. Thanks for the heads up about the return FALSE.

Share this post


Link to post
Share on other sites
I don't know what's wrong with it from what you've shown -- I've never done the thing you do in which you create a template in memory. I've actually never even heard of doing that.

I guess if I were you I'd try commenting out the !IsDialogMessage() and just a do a regular Translate and Dispatch message loop and I'd comment out everything in the dialog procedure and just return FALSE and then see if I got different behavior. I guess if that doesn't change the behavior then the problem has to be in createDlgHeader or createDlgCtrl, even though they worked with the modal DialogBox() case.

If you're doing things the way you are for learning purposes fine, but if you just want to make a modeless "about box" without using a resource editor, there are easier ways to do it than building your own DLGITEMTEMPLATE. Either (a) don't use an official dialog box -- just make a custom window class with whatever controls you need on it with a few calls to CreateWindow or (b) define a dialog in a .rc file without using a resource editor (VC++ Express still compiles .rc files even though it doesn't have a visual resource editor)

[Edited by - jwezorek on April 16, 2010 7:41:35 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by jwezorek
I don't know what's wrong with it from what you've shown -- I've never done the thing you do in which you create a template in memory. I've actually never even heard of doing that.



I did it once, and it's insane. Of course I did it a long time ago, maybe the process by which to do it has gotten easier.

What the OP needs to do to debug this is to design an equivalent dialog in the resource editor, load the resource into memory, and then do a memcmp to make sure that it's actually the same.

Share this post


Link to post
Share on other sites
Quote:
Original post by cache_hit
Quote:
Original post by jwezorek
I don't know what's wrong with it from what you've shown -- I've never done the thing you do in which you create a template in memory. I've actually never even heard of doing that.



I did it once, and it's insane. Of course I did it a long time ago, maybe the process by which to do it has gotten easier.

What the OP needs to do to debug this is to design an equivalent dialog in the resource editor, load the resource into memory, and then do a memcmp to make sure that it's actually the same.

And since that requires a resource editor... just use the resource instead of doing it by hand.

Share this post


Link to post
Share on other sites
Quote:
Original post by cache_hit
I did it once, and it's insane.


Out of curiosity, what was the context? Did you have to do it for a reason or was it just Win32 spelunking?

Share this post


Link to post
Share on other sites
A few tiny mistakes:

1)
The main problem: Remove the HWND in your message loop. Pass NULL instead. Otherwise you only process messages of the main window.

2)
Move the return DefWindowProc OUT OF THE DEFAULT CASE AFTER THE SWITCH.

3)
You're calling PostQuitMessage twice, one in the main window close, one in the modeless dialog proc.

Share this post


Link to post
Share on other sites
Quote:
Original post by Endurion
A few tiny mistakes:

1)
The main problem: Remove the HWND in your message loop. Pass NULL instead. Otherwise you only process messages of the main window.

2)
Move the return DefWindowProc OUT OF THE DEFAULT CASE AFTER THE SWITCH.

3)
You're calling PostQuitMessage twice, one in the main window close, one in the modeless dialog proc.


Where his DefWindowProc call is shouldn't be a problem. If he handles a message he calls break which falls to return 0. Otherwise, it calls DefWindowProc (for message he doesn't handle.) Unless I missing something.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!