Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. WM_SHOWWINDOW not called

WM_SHOWWINDOW not called

Scheduled Pinned Locked Moved C / C++ / MFC
debuggingquestion
13 Posts 3 Posters 2 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • _ _Flaviu

    Thank you ... I wonder how to know for sure when a childframe have been created ... I will do some tests.

    L Offline
    L Offline
    leon de boer
    wrote on last edited by
    #4

    Same way as your last question handle the WM_CREATE message of the child window (or WM_MDICREATE of the parent MDICLIENT) and you know when it's created. It's a basic thing if you want to know absolutely about something (without delay) then insert code in that handler instead of trying to determine it from a parent or associated window where the message chain gets involved. It's easier and safer than the alternatives. The other key things with MDI's is children will by default be handled by DefMDIChildProc and be inside an MDIClient window (which is like an invisible window that sits inside an normal window) for them to operate correctly. So basically your app window contains an MDICLient, and the MDICLient contains the MDI children. So be careful the children are not actually children of the APP window as such. If you try to insert an MDIChild directly into a normal window it won't operate correctly they must be in an invisible MDIClient window pane.

    In vino veritas

    _ 2 Replies Last reply
    0
    • L leon de boer

      Same way as your last question handle the WM_CREATE message of the child window (or WM_MDICREATE of the parent MDICLIENT) and you know when it's created. It's a basic thing if you want to know absolutely about something (without delay) then insert code in that handler instead of trying to determine it from a parent or associated window where the message chain gets involved. It's easier and safer than the alternatives. The other key things with MDI's is children will by default be handled by DefMDIChildProc and be inside an MDIClient window (which is like an invisible window that sits inside an normal window) for them to operate correctly. So basically your app window contains an MDICLient, and the MDICLient contains the MDI children. So be careful the children are not actually children of the APP window as such. If you try to insert an MDIChild directly into a normal window it won't operate correctly they must be in an invisible MDIClient window pane.

      In vino veritas

      _ Offline
      _ Offline
      _Flaviu
      wrote on last edited by
      #5

      Kindly thank you for your information. Actually I want to setup the window placement which have been saved in CChildFrame::OnDestroy():

      void CChildFrame::OnDestroy()
      {
      CMDIChildWnd::OnDestroy();

      // TODO: Add your message handler code here
      
      WINDOWPLACEMENT wp;
      GetWindowPlacement(&wp);
      if(wp.showCmd == SW\_SHOWMINIMIZED)
      	wp.showCmd = SW\_SHOWMAXIMIZED;
      AfxGetApp()->WriteProfileBinary(\_T("Settings"), \_T("WindowPlacementChild"), (LPBYTE)&wp, sizeof(wp));
      

      }

      and previously I setup the window placement on first CChildFrame::OnShowWindow call:

      void CChildFrame::OnShowWindow(BOOL bShow, UINT nStatus)
      {
      CMDIChildWnd::OnShowWindow(bShow, nStatus);

      // TODO: Add your message handler code here
      if(bShow && ! IsWindowVisible() && m\_bOnce)
      {
      	m\_bOnce = FALSE;
      	UINT nBytes = 0;
      	WINDOWPLACEMENT\* lwp;
      	if(AfxGetApp()->GetProfileBinary(\_T("Settings"), \_T("WindowPlacementChild"), (LPBYTE\*)&lwp, &nBytes))
      		SetWindowPlacement(lwp);
      	delete \[\]lwp;
      }
      

      }

      but I discovered that this handler are not called when the previous child frame open are maximized ... where should be the proper place to set the child frame placement on opening ?

      1 Reply Last reply
      0
      • L leon de boer

        Same way as your last question handle the WM_CREATE message of the child window (or WM_MDICREATE of the parent MDICLIENT) and you know when it's created. It's a basic thing if you want to know absolutely about something (without delay) then insert code in that handler instead of trying to determine it from a parent or associated window where the message chain gets involved. It's easier and safer than the alternatives. The other key things with MDI's is children will by default be handled by DefMDIChildProc and be inside an MDIClient window (which is like an invisible window that sits inside an normal window) for them to operate correctly. So basically your app window contains an MDICLient, and the MDICLient contains the MDI children. So be careful the children are not actually children of the APP window as such. If you try to insert an MDIChild directly into a normal window it won't operate correctly they must be in an invisible MDIClient window pane.

        In vino veritas

        _ Offline
        _ Offline
        _Flaviu
        wrote on last edited by
        #6

        "Same way as your last question handle the WM_CREATE message of the child window (or WM_MDICREATE of the parent MDICLIENT) and you know when it's created" You mean on creation of child frame ?

        _ 2 Replies Last reply
        0
        • _ _Flaviu

          "Same way as your last question handle the WM_CREATE message of the child window (or WM_MDICREATE of the parent MDICLIENT) and you know when it's created" You mean on creation of child frame ?

          _ Offline
          _ Offline
          _Flaviu
          wrote on last edited by
          #7

          I don't think that WM_CREATE is the right place to set child frame placement:

          int CChildFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
          {
          if (CMDIChildWnd::OnCreate(lpCreateStruct) == -1)
          return -1;

          // TODO: Add your specialized creation code here
          
          UINT nBytes = 0;
          WINDOWPLACEMENT\* lwp;
          if(AfxGetApp()->GetProfileBinary(\_T("Settings"), \_T("WindowPlacementChild"), (LPBYTE\*)&lwp, &nBytes))
          	SetWindowPlacement(lwp);
          delete \[\]lwp;
          
          return 0;
          

          }

          Once as I put here this code, I have not child frame system menu anymore.

          L 1 Reply Last reply
          0
          • _ _Flaviu

            I don't think that WM_CREATE is the right place to set child frame placement:

            int CChildFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
            {
            if (CMDIChildWnd::OnCreate(lpCreateStruct) == -1)
            return -1;

            // TODO: Add your specialized creation code here
            
            UINT nBytes = 0;
            WINDOWPLACEMENT\* lwp;
            if(AfxGetApp()->GetProfileBinary(\_T("Settings"), \_T("WindowPlacementChild"), (LPBYTE\*)&lwp, &nBytes))
            	SetWindowPlacement(lwp);
            delete \[\]lwp;
            
            return 0;
            

            }

            Once as I put here this code, I have not child frame system menu anymore.

            L Offline
            L Offline
            leon de boer
            wrote on last edited by
            #8

            You are returning zero and exiting ... try breaking and dropping thru to the default handler. I warned you about needing the default handler :-) MFC is always funky with its wrapper around the raw API so it's probably return one or some strange value to continue thru to the default handler. If all you are trying to do is reset the window placement use WM_WINDOWPOSCHANGED it is always called from WM_CREATE anyhow. I have did a sample with a different OPENGL in each MDICHILD here and the handler is in the text discussion even Native Win32 API OpenGL Tutorial - Part 2[^] You can ignore the OpenGL itself but the MDI does everything you wanted, it resize, minimizes, maximizes. tiles, cascade etc and you can see the messages I handled.

            In vino veritas

            1 Reply Last reply
            0
            • _ _Flaviu

              "Same way as your last question handle the WM_CREATE message of the child window (or WM_MDICREATE of the parent MDICLIENT) and you know when it's created" You mean on creation of child frame ?

              _ Offline
              _ Offline
              _Flaviu
              wrote on last edited by
              #9

              I guess I have found the right place to restore the child frame window placement:

              void CChildFrame::ActivateFrame(int nCmdShow)
              {
              // TODO: Add your specialized code here and/or call the base class

              CMDIChildWnd::ActivateFrame(nCmdShow);
              
              if(! m\_bOnce)
              	return;
              
              m\_bOnce = FALSE;
              UINT nBytes = 0;
              WINDOWPLACEMENT\* lwp;
              if(AfxGetApp()->GetProfileBinary(\_T("Settings"), \_T("WindowPlacementChild"), (LPBYTE\*)&lwp, &nBytes))
              	SetWindowPlacement(lwp);
              delete \[\]lwp;
              

              }

              L 1 Reply Last reply
              0
              • _ _Flaviu

                I guess I have found the right place to restore the child frame window placement:

                void CChildFrame::ActivateFrame(int nCmdShow)
                {
                // TODO: Add your specialized code here and/or call the base class

                CMDIChildWnd::ActivateFrame(nCmdShow);
                
                if(! m\_bOnce)
                	return;
                
                m\_bOnce = FALSE;
                UINT nBytes = 0;
                WINDOWPLACEMENT\* lwp;
                if(AfxGetApp()->GetProfileBinary(\_T("Settings"), \_T("WindowPlacementChild"), (LPBYTE\*)&lwp, &nBytes))
                	SetWindowPlacement(lwp);
                delete \[\]lwp;
                

                }

                L Offline
                L Offline
                leon de boer
                wrote on last edited by
                #10

                That should only work for the focused child window. Unless MFC overrides windows and activates each window in Z order. Windows normally when it brings up a group of children will only activate them along the focus chain in non MFC. Its very specific on the API. WM_ACTIVATE message (Windows)[^] Sent to both the window being activated and the window being deactivated. If the windows use the same input queue, the message is sent synchronously, first to the window procedure of the top-level window being deactivated, then to the window procedure of the top-level window being activated. By default each window will call down to it's parent to make sure it is activated in a direct line along the focus chain. You can basically follow the activation chain upwards from the application window and arrive at the focus window which is how keyboard messages etc find there way to the right window. So at no stage should two MDI children be active and the active one generally paints it's frame a different colour and brings itself to top (that is the default behviour). The only other child window that would get a normal windows API message is the one losing the focus chain. However if you had 3 children there would always be one window that would never get an activation message no matter what you did as it will neither be gaining or losing activation/focus chain. I would not expect that behaviour on MFC unless it does it's own thing and does a lot of repainting that is totally not done on actual windows API. Given the weird nature of that call with nCmdShow that is possible, all be it a bit naft and horrible hack. The WM_WINDOWPOSCHANGED I gave you does go to each and every child which is also why they tell you that you probably want to override it WM_WINDOWPOSCHANGED message (Windows)[^] By default, the DefWindowProc function sends the WM_SIZE and WM_MOVE messages to the window. The WM_SIZE and WM_MOVE messages are not sent if an application handles the WM_WINDOWPOSCHANGED message without calling DefWindowProc. It is more efficient to perform any

                _ 1 Reply Last reply
                0
                • L leon de boer

                  That should only work for the focused child window. Unless MFC overrides windows and activates each window in Z order. Windows normally when it brings up a group of children will only activate them along the focus chain in non MFC. Its very specific on the API. WM_ACTIVATE message (Windows)[^] Sent to both the window being activated and the window being deactivated. If the windows use the same input queue, the message is sent synchronously, first to the window procedure of the top-level window being deactivated, then to the window procedure of the top-level window being activated. By default each window will call down to it's parent to make sure it is activated in a direct line along the focus chain. You can basically follow the activation chain upwards from the application window and arrive at the focus window which is how keyboard messages etc find there way to the right window. So at no stage should two MDI children be active and the active one generally paints it's frame a different colour and brings itself to top (that is the default behviour). The only other child window that would get a normal windows API message is the one losing the focus chain. However if you had 3 children there would always be one window that would never get an activation message no matter what you did as it will neither be gaining or losing activation/focus chain. I would not expect that behaviour on MFC unless it does it's own thing and does a lot of repainting that is totally not done on actual windows API. Given the weird nature of that call with nCmdShow that is possible, all be it a bit naft and horrible hack. The WM_WINDOWPOSCHANGED I gave you does go to each and every child which is also why they tell you that you probably want to override it WM_WINDOWPOSCHANGED message (Windows)[^] By default, the DefWindowProc function sends the WM_SIZE and WM_MOVE messages to the window. The WM_SIZE and WM_MOVE messages are not sent if an application handles the WM_WINDOWPOSCHANGED message without calling DefWindowProc. It is more efficient to perform any

                  _ Offline
                  _ Offline
                  _Flaviu
                  wrote on last edited by
                  #11

                  Thank you for explanation. I have noticed something weird also: I open two child frames. Both of them are maximized. I have following code:

                  void CChildFrame::OnDestroy()
                  {
                  WINDOWPLACEMENT wp;
                  GetWindowPlacement(&wp);
                  TRACE("Window state: %d\n", wp.showCmd);

                  CMDIChildWnd::OnDestroy();
                  
                  // TODO: Add your message handler code here
                  

                  }

                  I repeat: both of child frames are maximized. I close one of them: the result of TRACE are

                  Window state: 1

                  which mean SW_SHOWNORMAL, not maximized. Then, I close the next child frame opened, the result is:

                  Window state: 3

                  which mean that is SW_MAXIMIZED .... although all child frame opened were maximized, the only last one tell me that was maximized ... rest of them tell me that was SSHOWNORMAL ? Why ?

                  L 1 Reply Last reply
                  0
                  • _ _Flaviu

                    Thank you for explanation. I have noticed something weird also: I open two child frames. Both of them are maximized. I have following code:

                    void CChildFrame::OnDestroy()
                    {
                    WINDOWPLACEMENT wp;
                    GetWindowPlacement(&wp);
                    TRACE("Window state: %d\n", wp.showCmd);

                    CMDIChildWnd::OnDestroy();
                    
                    // TODO: Add your message handler code here
                    

                    }

                    I repeat: both of child frames are maximized. I close one of them: the result of TRACE are

                    Window state: 1

                    which mean SW_SHOWNORMAL, not maximized. Then, I close the next child frame opened, the result is:

                    Window state: 3

                    which mean that is SW_MAXIMIZED .... although all child frame opened were maximized, the only last one tell me that was maximized ... rest of them tell me that was SSHOWNORMAL ? Why ?

                    L Offline
                    L Offline
                    leon de boer
                    wrote on last edited by
                    #12

                    When you close one child, the focus first shifts to the next child window. So at that point the window is not technically maximized, in that maximized is more than about size it is about focus as well. Think about the pesky icons placed in the parent frame that is the window that is maximized. So technically you can't have two child windows WM_MAXIMIZED you can have two of them maximum size but that isn't the same thing :-)

                    In vino veritas

                    _ 1 Reply Last reply
                    0
                    • L leon de boer

                      When you close one child, the focus first shifts to the next child window. So at that point the window is not technically maximized, in that maximized is more than about size it is about focus as well. Think about the pesky icons placed in the parent frame that is the window that is maximized. So technically you can't have two child windows WM_MAXIMIZED you can have two of them maximum size but that isn't the same thing :-)

                      In vino veritas

                      _ Offline
                      _ Offline
                      _Flaviu
                      wrote on last edited by
                      #13

                      Very good explanation, thank you !

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups