Creating a free floating child window?

I have run into a little problem with my class project, I'm trying to make a dialog box that will be created from my main window, the dialog box needs to have an edit control that a user can enter text into. Once the user presses the "Ok" button, the main window needs to retrieve the text from the dialog box using the WM_GETTEXT message, however the dialog box needs to stay open until the user pressed the "close" button.

I have tried doing this by creating a separate window class, creating a new window using the main window's handle for the parent argument and then creating the necessary child windows inside the dialog window, but this doesn't seem to work. The window is created as a free floating(By this I mean it is not inside the main window) window, but I am unable to move it like you would a normal window.

Do I have to create a child Window Class?(Which I have no idea how to do) or am I going to have to rework my main window as a MIDI window?
Look at the 3rd parameter to the function DialogBox(). It is the HWND of the parent. When you create your main window class allocate four bytes in the cbWndExtra bytes. In the InitiateDialog handler for the dialog store the dialog box's HWND in the main windows cbWndExtra bytes with SetWindowLong(). Then, since you'll have the HWND of the dialog in your main window's storage, you'll be able to get the text out of any control on the dialog box from the main window.
I had wanted to do this without using the DialogBox() function, the dialog has a few bits of data that need to be assessed upon creation. For instance, I had planned on the dialog window always existing but just being hidden and deactivated depending on if a menu item is ticked. Which is something I'm not sure you can do with DialogBox().

Both windows (This dialog and the main window) need to be active and able to be interacted with at the same time, but they need to be able to send messages to each other.

I had also wanted to do this without needing a .rc file to load the dialog template from.
Last edited on
You can still create the dialog with DialogBox() using the rc file and do evertthing you want to do. This is done all the time in a multitude of applications.

Your dialog box doesn't need its own class. It just inherits that from the main window. In fact, the project you have described is really a very simple thing to do.

In short, you create your dialog box and then when the user clicks the "OK" button you use SendDialogItemMessage() using WM_GETTEXT to retrive the text in the edit control and you're done. That is a very, very simple thing to do using a straightforward dialog box.
Do You need the second window to be an child window of the first one or is it even enough for the project to make both windows send WM_ - Messages to each other?... you can call SendMessage and PostMessage with a Handle to the target window... also im not sure why you cant move the window the way you want to when creating it as a chiled of the first one...
I had hoped to do it without using DialogBox(), because it would mean I needed to redo most of my SearchDialog class :/. Ah well, it needs to be a child because the dialog needs to bedestroyed/hidden/shown depending on what messages it was sent by the main window, which I assume means it needs to be considered a child window.

How would I retrieve the handle from a dialog box? From what I have been reading on msdn, DialogBox returns the result of the dialog rather than a HWND.

EDIT: Is there any functional difference between WM_CREATE and WM_INITDIALOG? From what I have seen some people use one in the place of the other.

EDIT 2 : Bah! Can't get it working, I decided to use CreateDialogParam() since I need the dialog to be modeless and DialogBox() only creates Modal. However it seems that I can't convert the this pointer from my class to the special type of LPARAM that CreateDialogParam() requires (Despite the fact that it works for CreateWindowEx, when it is passed a the LPARAM).

It seems half of the problem is that even when I typecast the this pointer as an LPARAM it doens't actually send anything (The lParam argument of my static DialogProc is 0) and I can't use CREATESTRUCT's to store the pointer since it's no longer a normal window.

EDIT 3 : It seems that what happens is, while running through it's message loop it comes across a piece of data that looks like the SearchDialog class, so it tries to call the classes DialogProc function.... Only for a read/write error to pop up crashing the program.

I have no clue how to fix this at this point, I was using a snippit of code from a website
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
LRESULT CALLBACK CWindow::StaticWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
CWindow* pParent;

   // Get pointer to window
   if(uMsg == WM_CREATE)
   {
      pParent = (CWindow*)((LPCREATESTRUCT)lParam)->lpCreateParams;
      SetWindowLongPtr(hWnd,GWL_USERDATA,(LONG_PTR)pParent);
   }
   else
   {
      pParent = (CWindow*)GetWindowLongPtr(hWnd,GWL_USERDATA);
      if(!pParent) return DefWindowProc(hWnd,uMsg,wParam,lParam);
   }

   pParent->m_hWnd = hWnd;
   return pParent->WndProc(uMsg,wParam,lParam);
}

LRESULT CWindow::WndProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
   switch(uMsg)
   {
      // Normal code here
   }

   // Call default window proc if we haven't handled the message
   return DefWindowProc(m_hWnd,uMsg,wParam,lParam);
}
(From http://www.gamedev.net/community/forums/topic.asp?topic_id=303854 )

And I will admit that I have little to no idea how exactly it works. For example, I have no idea how it gets the this pointer by just type casting a LPCREATESTRUCT into a pointer to the class.
I understand the SetWindowLong() which is what I think may be one of the things causing the problem, since LPARAM's are only 16 bits long, because I am having to type cast the this pointer to an LPARAM I am cutting off half of the pointer(I think). No idea how to fix it however.
Last edited on
If you need the dialog to be modeless you use CreateDialog() instead of DialogBox(), and you get the handle to it by doing this --

HWND hWnd=CreateDialog(hInst, szClassName, hwndParent, lpDialogFunc);

The way you are trying to do it is convoluted and overflowing with problems. In the above example, since you already have a parent window, then instead of szClassName you would use the MAKEINTRESOURCE() macro, so that it would be coded like this --

HWND hWnd=CreateDialog(hInst, MAKEINTRESOURCE(ID_MY_DIALOG), hwndParent, lpDialogFunc);
Last edited on
I can't use the normal CreateDialog() because it needs access to the this pointer, hence the reason for the static DialogProc redirecting the message to the correct instance of the class.

One of the requirements for the assignment is that everything be as self contained and Object orientated as possible, that means each window needs it's own class and should be able to manage it's own data and messages, only interacting with other classes/windows through functions and the windows message system.
pseudo code:

handle = create window1;
handle2 = create window2;

//if you want to close the second window when first gets closed:
SendMessage to handle2/window2 and transmit WM_DESTROY or any other...

that´s what i would do... no dialog box, no direct child...
That's what I ended up trying to do, only problem is my second window refuses to respond to anything I do. I think it might have something to do with the fact that only one GetMessage() can run on a single thread at a time, if I try running both at once the program freezes up, if I try only running one the other window becomes unresponsive.


EDIT : Well, the WinProc for the search window is working, even though I am not running it's GetMessage() loop, I guess GetMessage() directs the messages where they need to go automatically. Only problem now is that it refuses to change focus from the search window, or let me move the window.

EDIT 2 : Wow, I feel like an idiot. Turns out it was not working because I was not returning the DefWindowProc() in the WndProc for my search window. Works just fine now, I always did wonder just how important the return result from the WndProc's was... guess I know now.
Last edited on
Topic archived. No new replies allowed.