Thread: Unexpected Output, modal window!

  1. #1
    Registered User
    Join Date
    Dec 2010
    Location
    Delhi, India
    Posts
    59

    Unexpected Output, modal window!

    Hi all, I am new to Windows programming. I am trying to make a modal window from a main window on press of a button. The main window should be disabled and the modal window should be enabled, but instead I end up getting both the windows disabled in my output. Here's the code:

    Code:
    #include<windows.h>
    
    LRESULT CALLBACK WndProc      (HWND, UINT, WPARAM, LPARAM) ;
    LRESULT CALLBACK ChildWndProc (HWND, UINT, WPARAM, LPARAM) ;   //Child window procedure//
    
    #define ID_BUTTON1 1
    int CreateChildWindow(HINSTANCE, HWND);                        //Funtion to create child window//
    
    //global variables
    static MSG msg1;
    HWND b1,childHwnd;
    static TCHAR chappname[]= TEXT("Child");
    WNDCLASS child_window;
    static HINSTANCE ChildInstance;
    HWND hwnd;
    
    int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,PSTR szCmdLine, int iCmdShow)
    {
    	static TCHAR szAppName[] = TEXT ("Modal_Window") ;
    	MSG msg ;
        WNDCLASS wndclass ;
        wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
        wndclass.lpfnWndProc   = WndProc ;
        wndclass.cbClsExtra    = 0 ;
        wndclass.cbWndExtra    = 0 ;
        wndclass.hInstance     = hInstance ;
        wndclass.hIcon         = LoadIcon (hInstance, szAppName) ;   	 
        wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
      	wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
    	wndclass.lpszMenuName  = szAppName ;
    	wndclass.lpszClassName = szAppName ;
         
        if (!RegisterClass (&wndclass))
        {
              MessageBox (NULL, TEXT ("This program requires Windows NT!"),
                          szAppName, MB_ICONERROR) ;
              return 0 ;
         }
         
         hwnd=CreateWindow (szAppName, TEXT ("About Modal Window"),
                              WS_OVERLAPPEDWINDOW,
                              CW_USEDEFAULT, CW_USEDEFAULT,
                              CW_USEDEFAULT, CW_USEDEFAULT,
                              NULL, NULL, hInstance, NULL) ;
    	   
         
         ShowWindow (hwnd, iCmdShow) ;
         UpdateWindow (hwnd) ; 	 
         
         while (GetMessage (&msg, NULL, 0, 0))
         {
              TranslateMessage (&msg) ;
              DispatchMessage (&msg) ;
         }
         return msg.wParam ;
    }
    
    LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    
    	 static HINSTANCE hInstance ;
    	
         switch (message)
         {
    	 case WM_CREATE : b1=CreateWindow(TEXT("Button"),TEXT("Button1"),WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,10,20,50,30,hwnd,(HMENU) ID_BUTTON1,hInstance,0);
    		              return 0 ;
              
         case WM_COMMAND : 
    		      {
    			    switch(LOWORD(wParam))
    			    {
    		   	      case ID_BUTTON1: CreateChildWindow(ChildInstance,hwnd);
    				                   break;
    				  default : break;
    			    }
                  return 0 ;
    		     }
         case WM_DESTROY : PostQuitMessage (0) ;
    			          return 0; 
    	 }  //switch close
         return DefWindowProc (hwnd, message, wParam, lParam) ;
    }
    
    int CreateChildWindow(HINSTANCE ChildInstance, HWND hwnd)
    {
    	//int error,i;
    	child_window.style         = CS_HREDRAW | CS_VREDRAW ;
    	child_window.lpfnWndProc   = ChildWndProc ;
    	child_window.cbClsExtra    = 0 ;
    	child_window.cbWndExtra    = 0 ;
    	child_window.hInstance     = ChildInstance ;
    	child_window.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
    	child_window.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
    	child_window.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH) ;
    	child_window.lpszMenuName  = NULL;
    	child_window.lpszClassName = chappname;
    	
    	if (!RegisterClass (&child_window))
        {
    		MessageBox (hwnd, TEXT ("This program requires Windows NT!"), chappname, MB_ICONERROR) ;       //Problem here!//
    						  
    		return -1;
    	}
    			
    	// CreateChildWindow(ChildInstance,hwnd);
            childHwnd = CreateWindow (chappname, TEXT ("child Modal Window"),      
    		  WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                              CW_USEDEFAULT, CW_USEDEFAULT,
                             600, 600,
                              hwnd, NULL,ChildInstance , NULL) ;
    
    	 //error = GetLastError ();
    	 
    	 EnableWindow(hwnd,FALSE);               //disable main window
    	  return 0;
    }  
    
    LRESULT CALLBACK ChildWndProc(HWND childHwnd,UINT message,WPARAM wParam,LPARAM lParam)
    {
    	switch(message)
    	{
    	case WM_CREATE: break;
    	case WM_PAINT: break;
    	case WM_DESTROY :PostQuitMessage (0) ;
    			            EnableWindow(hwnd,TRUE);
                                        return 0;
    	default: break;
    	}
    	return DefWindowProc(childHwnd, message, wParam, lParam) ;
    }
    I tried again and what I found is that my child window is constrained inside the main window.. so when my main window is disabled the child becomes disabled. I can't find how to remove this so that my child window can move outside my main window as well.

    Well, I have removed this problem too.. Now the only issue is that when I close my modal window to enable the main window again and press the button to again create the modal window, I am unable to register it.. Code has been edited to show the changes done.

    Any suggestions would be greatly appreciated! Please reply!
    Last edited by gaurav_13191; 06-23-2011 at 11:08 PM.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Well one thing,

    static HINSTANCE ChildInstance;
    static HINSTANCE hInstance ;


    Neither of these is ever assigned a value (both will be 0)
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Dec 2010
    Location
    Delhi, India
    Posts
    59
    I am following Petzold's book for winapi but I didn't find any initialization statement for hInstance as you pointed out.. Can you please elaborate as I am completely new to this.

  4. #4
    Registered User
    Join Date
    Jan 2010
    Posts
    412
    Quote Originally Posted by Salem View Post
    Well one thing,

    static HINSTANCE ChildInstance;
    static HINSTANCE hInstance ;


    Neither of these is ever assigned a value (both will be 0)
    Some of the winapi functions which take a HINSTANCE parameter, including RegisterClass and CreateWindow, interpret a NULL HINSTANCE as GetModuleHandle(NULL). But this is undocumented behaviour* and I can't say for sure that it's valid for all windows versions as I have only tested it under XP. Can't remember which service pack though.

    *) I think. At least I can't find any official documentation for it.

  5. #5
    Registered User
    Join Date
    Dec 2010
    Location
    Delhi, India
    Posts
    59
    @Mike

    That guarantees that the problem is not due to hInstance as I am using Windows XP Pro, Service Pack 3.. So there is some other issue,, Need help on this!

  6. #6
    Registered User
    Join Date
    Jan 2010
    Posts
    412
    Quote Originally Posted by gaurav_13191 View Post
    @Mike

    That guarantees that the problem is not due to hInstance as I am using Windows XP Pro, Service Pack 3.. So there is some other issue,, Need help on this!
    You should still follow the API guidelines and use a valid HINSTANCE if you want to be sure it works on all windows versions. It's marked optional for CreateWindow but not for WNDCLASS/RegisterClass.
    I just mentioned it to Salem as a side-note because I know he understands the concept of undefined behaviour, not to say that it's okey to do it. Maybe I could have been more clear on that.
    In WinMain you have it as the first argument, so you can either store it as a global or cast the lparam of WM_CREATE to a CREATESTRUCT pointer if you need it in your window proc.

    Quote Originally Posted by gaurav_13191 View Post
    Now the only issue is that when I close my modal window to enable the main window again and press the button to again create the modal window, I am unable to register it.. Code has been edited to show the changes done.
    Because it has already been registered. Just register it once in WinMain or something. Don't try to do it every time you open a new window.

    Also,
    Code:
    LRESULT CALLBACK ChildWndProc(HWND childHwnd,UINT message,WPARAM wParam,LPARAM lParam)
    {
    	switch(message)
    	{
    	case WM_CREATE: break;
    	case WM_PAINT: break;
    	case WM_DESTROY :PostQuitMessage (0);
    			            EnableWindow(hwnd,TRUE);
                                        return 0;
    	default: break;
    	}
    	return DefWindowProc(childHwnd, message, wParam, lParam) ;
    }
    That will probably make opening a second window a bit problematic

  7. #7
    Registered User
    Join Date
    Dec 2010
    Location
    Delhi, India
    Posts
    59
    @Mike
    Thanks a lot.. and yes I will take care that I initialize hInstance from now onwards..

    @Salem
    Thanks for your reply too..

  8. #8
    Registered User
    Join Date
    Dec 2010
    Location
    Delhi, India
    Posts
    59
    Just another small question.. I modified my code posted above to make the modal window a child modal window using WS_CHILD . But then on running the code, both main window and child modal window get disabled even though only the main window should be disabled.. Can someone tell how to make the child modal window active while keeping the parent disabled ( I used EnableWindow function to disable parent)..

  9. #9
    Registered User
    Join Date
    Dec 2010
    Location
    Delhi, India
    Posts
    59
    No need to answer, I didn't know that all child windows are automatically disabled on disabling the parent.

  10. #10
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by gaurav_13191 View Post
    Just another small question.. I modified my code posted above to make the modal window a child modal window using WS_CHILD . But then on running the code, both main window and child modal window get disabled even though only the main window should be disabled.. Can someone tell how to make the child modal window active while keeping the parent disabled ( I used EnableWindow function to disable parent)..
    Ok, first, you really need to visit a couple of sites and do some reading...

    theForger's Win32 API Tutorial

    Win32 Tips, Tricks and Tutorials | www.catch22.net

    The first will give you a much better idea how to setup and use GUI mode windows. The second will help you with issues like windows that flicker when resized and the finer points of proper window creation and use. There are many things about your code that can be improved with simple changes. But mostly it's the structure of the code that's problematic.

    For your question about child windows... if you want two independent windows so that one can stay active while the other is disabled you need to make two top level windows from your self-registered class (i.e. no WS_CHILD for the main frame). Controls are children, top level windows are not.

    Also, when you have a window with child controls, they should all share the same WndProc... splitting them into separate procedures generally leads to messages being misdirected and can cause some very strange behavior.

    Finally, all windows in an execution unit (exe, dll, etc.) share the same instance handle. This is so the windows message loop knows where to send messages.

  11. #11
    Registered User
    Join Date
    Dec 2010
    Location
    Delhi, India
    Posts
    59
    @commontater
    Thanks for your suggestions.. yes my code needs a lot of changes.. as I am a complete beginner in windows programming,, regarding the reading material I read Petzold's book for windows programming.. but will definitely look upon the material suggested by you.. thanks a lot

  12. #12
    Registered User
    Join Date
    Mar 2007
    Posts
    142
    ... and I don't think that child modal windows should be created with the WS_OVERLAPPEDWINDOW flag. I can't remember that I found information about proper flags used for usual modal windows in Petzold. It was so long ago when I was dealing with basics of window creation, but I think I found what to use in some sample code I found googling around. Maybe on The Code Project or on this forum somewhere.
    Last edited by idelovski; 06-28-2011 at 05:18 PM.

  13. #13
    Registered User
    Join Date
    Dec 2010
    Location
    Delhi, India
    Posts
    59
    @idelovski
    You are right, Petzold doesn't have much about the modal windows.. So I am trying to do it myself and whenever I face some problems, I come here for answers
    I tried googling but could not find a satisfactory code sample or tutorial for this.

  14. #14
    Registered User
    Join Date
    Mar 2007
    Posts
    142
    Spend some time at Raymond Chen's place. He described dialog manager in great detail so we could almost create our own using regular windows.

    You can start here: The dialog manager, part 2: Creating the frame window and then search the archive on his blog.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Modify a Modal window?
    By guitarist809 in forum Windows Programming
    Replies: 2
    Last Post: 07-25-2008, 12:27 PM
  2. Unexpected Output in structure
    By bhagwat_maimt in forum C++ Programming
    Replies: 1
    Last Post: 12-29-2006, 10:50 PM
  3. unexpected output
    By crash88 in forum C Programming
    Replies: 2
    Last Post: 05-16-2006, 09:03 PM
  4. unexpected ( unwanted ) output in a file
    By Rpog in forum C Programming
    Replies: 2
    Last Post: 04-15-2004, 07:33 AM