# Learn Me Dialogs!! [FIXED]

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

## Recommended Posts

I hate to ask this of you guys, but... can someone guide me to making dialogs? I have absolutely NO idea why mine are not working. I seem to have followed every step in my book, but they come out... wrong, to say the least. The dialog window appears to "sink in" to the parent window. Only the controls are visible. Thankfully, they work, but this is annoying. Can someone guide me step by step as to how to implement a dialog that works? I don't know what exactly I'm doing wrong, but they all end up like that. By they way, here are the functions I use for my dialog. I'm not sure if these are at fault here, perhaps it's the way I make it in the resource editor. In case, however, I will post these: THis function initializes the dialog. After it gets the dialog up and running, it uses the return value (which is actually stored into a global elsewhere) to determine what to do. This function is probably not to be blamed.
void RunMainMenu( void )
{
DialogBox( g_hInstance, MAKEINTRESOURCE( IDD_MAINMENU ), g_hWnd,
{
case HIDE_SELECTED:
{
BOOL GoAgain = HideMS();
while( GoAgain )
GoAgain = HideMS();
}
break;
case UNHIDE_SELECTED:
{
BOOL GoAgain = UnhideMS();
while( GoAgain )
GoAgain = UnhideMS();
}
break;
case SETPATH_SELECTED:
{
DialogBox( g_hInstance, MAKEINTRESOURCE( IDD_SETPATH ),
g_hWnd, (DLGPROC)SetPathDlgProc );
}
break;
{
// Not yet implemented
}
break;
default:
PostQuitMessage( 25 );
return;
}
return;
}


This function is the one that handles the dialog. If the resource editor isn't wrong, then this probably is:
BOOL CALLBACK MainMenuDlgProc( HWND hMainMenuDlg, UINT msg,
WPARAM wParam, LPARAM lParam )
{
switch( msg )
{
case WM_COMMAND:
{
switch( LOWORD( wParam ) )
{
case IDC_HIDE:
{
}
break;
case IDC_UNHIDE:
{
}
break;
case IDC_SETPATH:
{
}
break;
{
}
break;
case IDCANCEL:
break;
default:
return TRUE;
}
}
break;
default:
return TRUE;
}
return FALSE;
}


[Edited by - v0dKA on January 17, 2005 8:45:49 AM]

##### Share on other sites
Remove the default case in your dialog proc.

The dialog proc is basically a extension of the dialogs window proc. Returning TRUE signals Windows, that you already took care of that message. As in your default, you don't, so return FALSE for every unhandled message.

##### Share on other sites
Wow, thanks! Works perfectly now. I was sure of myself something else was wrong.

Can you look, then, at another problem I'm having? I'm trying to read in a string (password, to be precise), but it's working less than stellar. I immediately put a message box after the prompt to display what the user entered, but it displays an empty string (or only the first letter) no matter what I type in. It's probably a matter of messed up pointers/arrays. Here's the dialog proc:

BOOL CALLBACK PasswordPromptDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam ) {   switch( msg )   { 	 case WM_INITDIALOG:		SetFocus( GetDlgItem( hDlg, IDC_EDIT1 ) );		break;     case WM_COMMAND:      {         switch( LOWORD( wParam ) )         {            case IDOK:            { 			  char InPassLocalArray[ 21 ];			  GetDlgItemText( hDlg, IDC_EDIT1, InPassLocalArray, strlen( InPassLocalArray ) - 1 ); 			  string sInPassLocal = InPassLocalArray;			  g_sPassword = InPassLocalArray;			  ////////////			  MessageBox( g_hWnd, InPassLocalArray, "Your input", MB_OK | MB_ICONINFORMATION );			  ////////////              EndDialog( hDlg, IDOK );            }            break;            case IDCANCEL:               EndDialog( hDlg, IDCANCEL );            break;         }      }      break;      default:            return FALSE;  }   return TRUE; }

Like I said, the input string after this would only contain the first letter entered, or nothing at all. Anyone know what's wrong?

[Edited by - v0dKA on January 16, 2005 9:38:37 AM]

##### Share on other sites
I'm not sure about this, but maybe you're not using the 'MessageBox' Function correctly. Here it is defined in the msdn:
int MessageBox(
HWND hWnd, //Handle to the owner window
LPCTSTR lpText, //Pointer to null terminated string
LPCTSTR lpCaption, //Pointer to null terminated string
UINT uType //Specifies content and behavior
);
I think you might be getting mixed up in the 2nd argument of the 'MessageBox' function. If you want to know for yourself, lookup 'LPCTSTR' somewhere, but I think you just put in an address of the character array. (Why all of the excess?)
NOTE: This might go with the 'GetDlgItemText' function as well.
char InPassLocalArray[ 21 ];GetDlgItemText( hDlg, IDC_EDIT1, &InPassLocalArray, strlen( InPassLocalArray ) - 1 ); string sInPassLocal = InPassLocalArray;g_sPassword = InPassLocalArray; //What's this for?////////////MessageBox( g_hWnd, sInPassLocal.c_str(), "Your input", MB_OK | MB_ICONINFORMATION ); ////////////

I would again suggest looking up the definition of a 'LPCSTR' to get a better grip on this problem.
EDIT: Try doing something with the null-terminated character.

##### Share on other sites
I triple checked with the book - I'm doing everything as I am supposed to. The only difference is the dialog itself, so perhaps something is wrong there. Here's the resource script:

IDD_DIALOGBAR DIALOG DISCARDABLE  200, 150, 104, 49STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENUCAPTION "Enter Password"FONT 8, "MS Sans Serif"BEGIN    EDITTEXT        IDC_EDIT1,7,7,90,12,ES_PASSWORD | WS_BORDER | ES_AUTOHSCROLL    PUSHBUTTON      "OK",IDOK,7,29,32,14    PUSHBUTTON      "Cancel",IDCANCEL,49,29,48,14END

##### Share on other sites
Here's a snippet from a piece of my own code, which might help give an example of a working wndproc; the code you want is in IDSAVE:

BOOL CALLBACK AddNewIngredientProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam){	char itemName[255];	char itemUnit[255];	unsigned int itemCost = 0;	char itemWeight[255];	std::string thisUnit;	HWND hWndList;	int i = 0;	switch(message)	{	case WM_INITDIALOG:		hWndList = GetDlgItem(hDlg, IDC_COMBO1);		ConversionTable::Instance()->SetCurrentUnit(0);// Sets up amount units		while(1)		{			thisUnit = ConversionTable::Instance()->GetCurrentUnit();			SendMessage(hWndList, CB_ADDSTRING, 0, (LPARAM) thisUnit.c_str());			SendMessage(hWndList, CB_SETITEMDATA, i, (LPARAM) i);			++i;// Check to see if we've reached the end of the list			if(!ConversionTable::Instance()->DoesNextUnitExist())				break;		}// Set up default amount		SendDlgItemMessage(hDlg, IDC_COMBO1, CB_SETCURSEL, 0, 0);		SetFocus(GetDlgItem(hDlg, IDC_EDITINGREDIENTNAME));		return true;	case WM_COMMAND:		switch(LOWORD(wParam))		{		case IDCLOSE:			IngredientManager::Instance()->SaveIngredients();			EndDialog(hDlg, 0);			return true;		case IDSAVE:			itemCost = GetDlgItemInt(hDlg, IDC_EDITINGREDIENTCOST, NULL, false);			GetDlgItemText(hDlg, IDC_COMBO1, &itemUnit[0], 255);			if(GetDlgItemText(hDlg, IDC_EDITINGREDIENTNAME, &itemName[0], 255) &&				itemCost &&				GetDlgItemText(hDlg, IDC_EDITINGREDIENTWEIGHT, &itemWeight[0], 255)				)			{				IngredientManager::Instance()->AddNewIngredient(itemName, itemCost, itemWeight, itemUnit);				SetDlgItemText(hDlg, IDC_EDITINGREDIENTNAME, " ");				SetDlgItemText(hDlg, IDC_EDITINGREDIENTCOST, " ");				SetDlgItemText(hDlg, IDC_EDITINGREDIENTWEIGHT, " ");				SetFocus(GetDlgItem(hDlg, IDC_EDITINGREDIENTNAME));			}			return true;		default:			return false;		}	default:		return false;	}}

HTH,
Jim.

##### Share on other sites
You're declaring an char array and using strlen to tell GetDlgItemText the length of the buffer. Use sizeof or put the length as value inside.

##### Share on other sites
Quote:
 Original post by EndurionYou're declaring an char array and using strlen to tell GetDlgItemText the length of the buffer. Use sizeof or put the length as value inside.

Wow, nicely spotted! 'Twas the last thing I suspected.