Jump to content
  • Advertisement
Sign in to follow this  
Twigletguy

Collecting Data From A Native WinAPI Dialog Box

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

I have a simple image processing program using a native c++ WinAPI window. I'd like to collect some user input for certain functions in my program. I can create a custom dialog box via the DialogBox() command, and can handle messages for that dialog box in its own DlgProc method. I don't understand however how to get any data from that dialog box back to my main window. I'm using VS2008, and defining my dialog box using the resource editor. Do I have to send messages back to the parent window before the dialog box is closed? If so, presumably I will have to convert to and from message parameters (WPARAM & LPARAM). I'd appreciate some guidance on this. If any more details or code samples would be helpful, I'd be happy to supply them, but as it stands I was hoping that a gentle nudge might get me heading in the right direction.

Share this post


Link to post
Share on other sites
Advertisement
For starter you could check GetDlgItemText and GetDlgItemInt.
The others controls can be queryed via windows messages, like LB_GETTEXT, LB is for list box, each control type has his kind of messages like this, just check msdn to check what parameters are expected and what's the return value, if needed.

Share this post


Link to post
Share on other sites
Use DialogBoxParam(). This allows you to pass data that gets passed to the dialog as the lParam of the WM_INITDIALOG message.

I tend to create a struct that represents all the data, fill it with the current data and pass a pointer into DialogBoxParam() which I then copy and store a pointer to the copy in the userdata space of the window within WM_INITDIALOG.

If the dialog returns IDOK, I then copy this back to the struct that was passed into the calling function.

Share this post


Link to post
Share on other sites
Thanks guys. Aardvajk, I've looked up that function on the MSDN and it seems to be just what I was looking for. I'll have a crack at that tomorrow. The MSDN seems to be a brilliant vault of knowledge, both in that it stores valuable information and that it's damn near impossible to easily access.

Vortez, thanks, those look like useful functions, I'd seen reference to them when I was researching, but actually collecting the data from the controls wasn't really my main issue.

Share this post


Link to post
Share on other sites
Where should I be storing the pointer? What do you mean by "the userdata space of the window"?

At the moment I've been trying to declare the pointer in the DlgProc function. I can collect the pointer and I can verify that it's stored correctly in the WM_INITDIALOG case, but when that function returns the variable falls out of scope and its value is lost.

Not sure how to get around this. Am I going to have to encapsulate it in a class and store it as a member variable?

Share this post


Link to post
Share on other sites
You can store it in the GWLP_USERDATA space with SetWindowLongPtr. Here's how I do it (I'm at work so this isn't actual code).


struct NewSizeInfo // for example
{
int width;
int height;
};

bool NewSizeDialog(NewSizeInfo &info)
{
NewSizeInfo local=info;

int R=DialogBoxParam(Blah,Blah,Blah,(LONG_PTR)&local);

if(R==IDOK)
{
info=local;
return true;
}

return false;
}

void OnCreate(HWND Hw,LPARAM lParam)
{
NewSizeInfo *I=reinterpret_cast<NewSizeInfo*>(lParam);
SetWindowLongPtr(Hw,GWLP_USERDATA,(LONG_PTR)(I));
}

void OnCommand(HWND Hw)
{
// assuming the OK button has fired this...

NewSizeInfo *I=reinterpret_cast<NewSizeInfo*>(GetWindowLongPtr(Hw,GWLP_USERDATA));

if(I!=0)
{
// get the data and convert it into I->width and I->height
EndDialog(Hw,IDOK);
}
}

HRESULT DlgProc(Blah,blah)
{
switch(Msg)
{
case WM_INITDIALOG: OnCreate(Hw,lParam); return FALSE;

case WM_COMMAND: OnCommand(Hw); return TRUE;
}

// etc
}





Then you can call from the application:


void OnNewClick()
{
NewSizeInfo info;
info.width=lastWidth;
info.height=lastHeight; // or whatever

if(NewSizeDialog(blah,blah,info))
{
// do what you want with the values in info
}
}


This way, all the instances of NewSizeInfo exist as locals so are guaranteed to exist for as long as the modal dialog does since DialogBox() and DialogBoxParam() do not return until the dialog is closed.

Yes, it's all horrible, that's why we have WinForms and C# now.

Share this post


Link to post
Share on other sites
Managed to get everything working just how I want it now, many thanks. Odd how such useful features as that seem to be hidden and buried in obscure places.

Just for curiosity's sake, in C# and using WinForms etc you would solve this problem using events and delegates, yes?

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.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!