Jump to content
  • Advertisement
Sign in to follow this  
v0dKA

Is It Possible To Pass Additional Parameters to DialogProc()?

This topic is 4855 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

My DialogProc() function needs the ability to modify variables that are outside of its domain. Ideally, I want the ability to pass additional data to the DialogProc() function without using globals. Is DialogBoxParam() the proper way to do this? I want the ability to modify that parameter too. Should I pass a pointer to DialogBoxParam()? How can I retrieve and edit that value in DialogProc()?

Share this post


Link to post
Share on other sites
Advertisement
One solution would be to pass a pointer to a structure or class to the DialogBoxParam function. Then on dialog init, you can save that variable to a static variable in the dialog proc.

Another would be to register a user-defined window message (RegisterWindowMessage) and use SendMessage to pass whatever you want in wParm/lParm. This is probably a cleaner solution than the local static. However, the custom message is only useful if you are using a modeless dialog.

Share this post


Link to post
Share on other sites
As Dave said, you can pass a pointer to a struct if you want more than one parameter.
I always use SetWindowLong() to set the user data long to whatever I need. For example:

struct MyParams
{
int n;
CClass* p;
string str;
};

MyParams* pParams = new MyParams;
pParams.n = 42;
pParams.p = this;
pParams.str = "Hello World!";
DialogBoxParam(hInstance,MAKEINTRESOURCE(IDD_DIALOG),NULL,StaticProc,(LPARAM)pParams);



BOOL CALLBACK DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
MyParams* pParams;
BOOL bRet;

// Store the data on WM_INITDIALOG //
if(uMsg == WM_INITDIALOG)
{
pParams = (MyParams*)lParam;
SetWindowLong(hWnd,GWL_USERDATA,lParam);
}

// Get pointer to struct //
pParams = (MyParams*)GetWindowLong(hWnd,GWL_USERDATA);
if(pParams)
{
bRet = pParams->p->DialogProc(hWnd,uMsg,wParam,lParam);

// Call delete on WM_DESTROY //
if(uMsg == WM_DESTROY)
{
delete pParams;
SetWindowLong(hWnd,GWL_USERDATA,0);
}

return bRet;
}

// Some message before WM_INITDIALOG //
return FALSE;
}



That's not actual tested code, it's just an example. In my code I often just store the this pointer in the user data, and I don't need to delete it obviously.

Share this post


Link to post
Share on other sites
Sorry for the late respone, but I just didn't get around to this by now.

After taking Evil Steve's code and tweaking it around to fit my program, I'm getting a few warnings. I'm not sure if they're serious or not. Other than that, my code is starting to look a bit freakish with all those pointers to vectors, so I'd like criticism on my code design too.

Here's my DialogProc(). I put comments around the lines where I get warnings:

INT_PTR CALLBACK PromptVerticesDialogProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
switch( uMsg )
{
case WM_INITDIALOG:
{
/////////////////////////// WARNING 1
SetWindowLongPtr( hDlg, GWL_USERDATA, lParam );
/////////////////////////////////////

PostMessage( hDlg, WM_NEXTDLGCTL, (WPARAM)(GetDlgItem( hDlg, IDC_PROMPTVERTICES_X )), TRUE );
}
break;
case WM_DESTROY:
{
SetWindowLongPtr( hDlg, GWL_USERDATA, 0 );
}
case WM_COMMAND:
{
switch( LOWORD( wParam ) )
{
case IDOK:
EndDialog( hDlg, IDOK );
break;
case IDCANCEL:
EndDialog( hDlg, IDCANCEL );
break;
case IDC_PROMPTVERTICES_ADDVERTEX:
{
POINT pt;
pt.x = GetDlgItemInt( hDlg, IDC_PROMPTVERTICES_X, NULL, TRUE );
pt.y = GetDlgItemInt( hDlg, IDC_PROMPTVERTICES_Y, NULL, TRUE );

////////////////////// WARNING 2
std::vector<POINT>* TmpVertexList = (std::vector<POINT>*)GetWindowLongPtr( hDlg, GWL_USERDATA );
///////////////////////
TmpVertexList->push_back( pt );

char NotificationText[ 1024 ];
wsprintf( NotificationText, "Added vertex ( %d, %d ).", pt.x, pt.y );

SetDlgItemText( hDlg, IDC_PROMPTVERTICES_X, NULL );
SetDlgItemText( hDlg, IDC_PROMPTVERTICES_Y, NULL );

SetWindowText( GetDlgItem( hDlg, IDC_PROMPTVERTICES_NOTIFICATIONTEXT ), NotificationText );
PostMessage( hDlg, WM_NEXTDLGCTL, (WPARAM)(GetDlgItem( hDlg, IDC_PROMPTVERTICES_X )), TRUE );
}
break;
}
}
break;
default:
return FALSE;
}

return TRUE;
}



If it matters, here's where I call the dialog box:

std::vector<POINT> TmpVertexList;
INT_PTR nResult = DialogBoxParam( g_hInst, MAKEINTRESOURCE( IDD_PROMPTVERTICES_MAIN ), g_hWnd,
reinterpret_cast<DLGPROC>(PromptVerticesDialogProc), (LPARAM)&TmpVertexList );


The warnings I receive are:

warning C4244: 'argument' : conversion from 'LPARAM' to 'LONG', possible loss of data

warning C4312: 'type cast' : conversion from 'LONG' to 'std::vector<_Ty> *' of greater size
with
[
_Ty=POINT
]



1) Do these warnings matter?
2) Is there a better way to restructure my code?

Share this post


Link to post
Share on other sites
1) Nope. That's MSVC going crazy over 64-bit portability issues. It's extremely annoying, since that warning is actually completely wrong.
2) Your code looks fine really, that's pretty much how I'd do it.

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!