Sign in to follow this  
d h k

[MSVC++] Reacting on events (strange bug now)

Recommended Posts

d h k    439
Hello everybody, I just recently got into windows programming using the Microsoft Visual C++ 6.0 compiler. First of all, I'll need to tell you how I have everything set up and then I'll demonstrate you my current problem. So, I have added an ".rc"-resource to my project. In this resourcce file, I added two dialogs (one called "IDDFORMLOGIN" and the other is named "IDDFORMMAIN"). I added all kinds of controls (labels, groups, buttons etc.) on those dialogs with the editor in MSVC++ 6. That all works fine. This is the way my source code looks right now:
// BarcodeDemo.cpp

#include "stdafx.h"
#include "windows.h"
#include "Resource.h"


HWND hWnd;
HINSTANCE hInstance;

LRESULT CALLBACK FormLoginProc ( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam );
LRESULT CALLBACK FormMainProc ( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam );

INT WINAPI WinMain ( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	DialogBox ( hInstance, MAKEINTRESOURCE ( IDD_FORMLOGIN ), hWnd, reinterpret_cast<DLGPROC> ( FormLoginProc ) );
	return FALSE;
}


LRESULT CALLBACK FormLoginProc ( HWND hWndDlg, UINT Msg, WPARAM wParam, LPARAM lParam )
{
	switch ( Msg )
	{
		case WM_INITDIALOG:
			return TRUE;
		break;

		case WM_CLOSE:
			EndDialog ( hWndDlg, 0 );
			DialogBox ( hInstance, MAKEINTRESOURCE ( IDD_FORMMAIN ), hWnd, reinterpret_cast<DLGPROC> ( FormMainProc ) );
		break;
	}

	return FALSE;
}

LRESULT CALLBACK FormMainProc ( HWND hWndDlg, UINT Msg, WPARAM wParam, LPARAM lParam )
{
	switch ( Msg )
	{
		case WM_INITDIALOG:
			return TRUE;
		break;

		case WM_CLOSE:
			EndDialog ( hWndDlg, 0 );
		break;
	}

	return FALSE;
}




This shows the first dialog (IDDFORMLOGIN), and then - after the user closes this dialog, it displays the second one (IDDFORMMAIN). I want to change this behaviour. I need to close the first dialog when the user presses a button on the first one. The problem is, I don't have any idea how to react to a button press. I searched through the MSDN and everything, but really didn't manage to find anything nearly useful. Also, I wonder if this is really the best way to achieve what I want. I basically need to display a first window with several controls on it, that allow you to log in using a username and a password. Then when the user clicks on the "log in" button, I want it to change to a second window with other controls, labels etc. on it. Do I need a new dialog for every of those "screens"? Thanks ahead of time, and make sure to ask if something is unclear to you. I am really new to this windows programming. [Edited by - d h k on March 26, 2006 6:28:43 AM]

Share this post


Link to post
Share on other sites
yadango    567
normally what you do for modal dialogs is (below is from the dialog proc):


case(WM_COMMAND) :
{
switch(LOWORD(wparam)) {
case(IDOK) :
EndDialog(window, IDOK);
return TRUE;
case(IDCANCEL) :
EndDialog(window, IDCANCEL);
return TRUE;
case(IDOFSOMEOTHERBUTTON) :
EndDialog(window, IDCANCEL (or IDOK or IDOFSOMEOTHERBUTTON));
return TRUE;
}
return FALSE;
}





also, instead of starting the second dialog from the first's dialog procedure, you should start it from WinMain. You also don't need reinterpret_cast if you declare your dialog procedure properly, using INT_PTR CALLBACK instead of LRESULT CALLBACK.


INT WINAPI WinMain ( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
// retval is equal to whatever EndDialog returns, or is -1 if it fails.
INT_PTR retval = DialogBox(hInstance, MAKEINTRESOURCE(IDD_FORMLOGIN), GetDesktopWindow(), FormLoginProc);

if(retval == IDOK) // if user chose OK, start next dialog
DialogBox(hInstance, MAKEINTRESOURCE(IDD_FORMMAIN), GetDesktopWindow(), FormMainProc);

return FALSE;
}




As for the rest of the stuff, you have the right idea. Basically you start dialog #1, fill it out, click on IDOK button, and on your WM_COMMAND's IDOK handler you fill out a global buffer storing all the info before you call EndDialog. Then you start the second dialog, using the global buffer info to do whatever.

Another nitpicky thing is that if you don't define your resource names as integers in your resource header... a la #define IDD_FORMMAIN 1000... you can say:

DialogBox(hInstance, "IDD_FORMMAIN", GetDesktopWindow(), FormMainProc);
instead of
DialogBox(hInstance, MAKEINTRESOURCE(IDD_FORMMAIN), GetDesktopWindow(), FormMainProc);

as I never use integer resource handlers for dialogs.

[Edited by - yadango on March 25, 2006 11:08:22 AM]

Share this post


Link to post
Share on other sites
d h k    439
Thank you very much for your response.. That helped me tons.

It works on my computer perfectly now, but whenever I run this on either one of my two laptops, it just closes after clicking on the "log in" button! They both run the very same Windows XP, too.

How could that happen?

Here is the code again (notice, I didn't include your "nitpicky" stuff just yet):


// BarcodeDemo.cpp

#include "stdafx.h"
#include "windows.h"
#include "Resource.h"

HWND hWnd = NULL;

LRESULT CALLBACK FormLoginProc ( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam );
LRESULT CALLBACK FormMainProc ( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam );

INT WINAPI WinMain ( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
INT_PTR return_value = DialogBox ( hInstance, MAKEINTRESOURCE ( IDD_FORMLOGIN ), GetDesktopWindow ( ), reinterpret_cast<DLGPROC> ( FormLoginProc ) );

if ( return_value == IDC_LOGINBUTTON )
{
DialogBox ( hInstance, MAKEINTRESOURCE ( IDD_FORMMAIN ), GetDesktopWindow ( ), reinterpret_cast<DLGPROC> ( FormMainProc ) );
}

return FALSE;
}


LRESULT CALLBACK FormLoginProc ( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam )
{
switch ( Msg )
{
case WM_COMMAND:
{
switch ( LOWORD ( wParam ) )
{
case IDC_LOGINBUTTON:

EndDialog ( hWnd, IDC_LOGINBUTTON );

return TRUE;

break;
}

return FALSE;
}

case WM_CLOSE:

EndDialog ( hWnd, 0 );

return TRUE;

break;
}

return FALSE;
}

LRESULT CALLBACK FormMainProc ( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam )
{
switch ( Msg )
{
case WM_CLOSE:

EndDialog ( hWnd, 0 );

return TRUE;

break;
}

return FALSE;
}



I have no idea what could cause the program to work on my computer while not working (and terminating after clicking the "log in" button instead) on any other system I run this on!

Share this post


Link to post
Share on other sites
yadango    567
One thing I still see wrong is that you don't have to call EndDialog from within WM_CLOSE. For modal dialogs, you don't have to respond to WM_CLOSE. Try removing WM_CLOSE entirely and instead respond to WM_COMMAND's IDCANCEL. Then let me know if you still get that crash. What might be happening is your EndDialog(IDC_LOGINBUTTON) closes the window first, then on WM_CLOSE your EndDialog(hWndDlg, 0) is trying to close it again. WM_CLOSE is a big no-no for modal dialogs.


case(WM_COMMAND) :
{
switch(LOWORD(wparam)) {
// make IDOK behave like IDC_LOGINBUTTON so that when you
// press the ENTER key it works just like IDC_LOGINBUTTON.
case(IDOK) :
case(IDC_LOGINBUTTON) :
// save login data
EndDialog(window, IDC_LOGINBUTTON);
return TRUE;
case(IDCANCEL) :
EndDialog(window, IDCANCEL);
return TRUE;
}
return FALSE;
}


Share this post


Link to post
Share on other sites
d h k    439
I just tried out your new code but the problem's still there... It won't work on different systems.

This is the most current source code:


// BarcodeDemo.cpp

#include "stdafx.h"
#include "windows.h"
#include "resource.h"

HWND hWnd = NULL;

LRESULT CALLBACK FormLoginProc ( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam );
LRESULT CALLBACK FormMainProc ( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam );

INT WINAPI WinMain ( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
INT_PTR return_value = DialogBox ( hInstance, MAKEINTRESOURCE ( IDD_FORMLOGIN ), GetDesktopWindow ( ), reinterpret_cast<DLGPROC> ( FormLoginProc ) );

if ( return_value == IDC_LOGINBUTTON )
{
DialogBox ( hInstance, MAKEINTRESOURCE ( IDD_FORMMAIN ), GetDesktopWindow ( ), reinterpret_cast<DLGPROC> ( FormMainProc ) );
}

return FALSE;
}


LRESULT CALLBACK FormLoginProc ( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam )
{
switch ( Msg )
{
case WM_COMMAND:
{
switch ( LOWORD ( wParam ) )
{
case IDOK:
case IDC_LOGINBUTTON:

EndDialog ( hWnd, IDC_LOGINBUTTON );

return TRUE;

break;

case IDCANCEL:

EndDialog ( hWnd, IDCANCEL );

return TRUE;

break;
}

return FALSE;
}
}

return FALSE;
}

LRESULT CALLBACK FormMainProc ( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam )
{
switch ( Msg )
{
case WM_COMMAND:
{
switch ( LOWORD ( wParam ) )
{
case IDCANCEL:

EndDialog ( hWnd, IDCANCEL );

return TRUE;

break;
}

return FALSE;
}
}

return FALSE;
}



Thanks again fro your help so far.

Share this post


Link to post
Share on other sites
yadango    567
hmmm... it could be lots of things... can you compile and debug the program on the laptop to see if it's the first dialog crashing or the second one as it is loading? Is that your whole dialog code that you posted? Did you strip out the GetDlgItem stuff in WM_INITDIALOG?

Share this post


Link to post
Share on other sites
d h k    439
Quote:

can you compile and debug the program on the laptop to see if it's the first dialog crashing or the second one as it is loading?


I could do that, but it would take quite some time and I'd really rather not go through the hazzle of this.

Quote:

Is that your whole dialog code that you posted? Did you strip out the GetDlgItem stuff in WM_INITDIALOG?


The code I posted is absolutely everything I have. How should I use the GetDlgItem function in WM_INITDIALOG exactly?

Thanks for your time!

Share this post


Link to post
Share on other sites
yadango    567
Ok, then if that's all your code and you aren't using GetDlgItem, it still could be a common control crash but I doubt it. Uhm, does this code and EXE crash for you? Very similar to yours but one or two different things. It should still compile on VC6 SP5 if I recall right.

code.

Share this post


Link to post
Share on other sites
d h k    439
Your application crashes on the computer where my own application works just fine. I didn't know that windows programming could be THIS tricky... ;)

Share this post


Link to post
Share on other sites
yadango    567
lol! yep. very tricky sometimes. i ran your last code sample exactly as you typed it (but with my own resource files) and it ran fine as well. on your sample program, what does each DialogBox return? Do any return -1? Does GetLastError() return any code? What value are you using for IDC_LOGINBUTTON? these are all things that can effect whether or not the next dialog appears.

Share this post


Link to post
Share on other sites
d h k    439
I ran some tests but I don't think anything really useful came out of it.

GetLastError ( ) doesn't return any data and none of the DialogBox ( ) functions return -1.

But what do you mean with "what value do you use for IDC_LOGINBUTTON"? IDC_LOGINBUTTON is the ID of the button on IDD_FORMLOGIN.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
does the second dialog box even return anything (when run on your laptop)? and what does the first box return? what I meant by 'the value' is in your resource header i.e. #define IDC_LOGINBUTTON 1000. but the way your code is in the last post, it's fine. should work on a PC or laptop (least I don't recall seeing anything ever on MSDN about special dialog treatment for laptops). could be a common controls type thing though... can you post the RC file? what happens when you gut all the controls (except for the button ones) out of the second dialog?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this