Link to home
Start Free TrialLog in
Avatar of MarcoHelmers
MarcoHelmers

asked on

Creating a child window

I want to create a simple child. For this purpose I created a new class derived from CWnd. I wrote a new Create method:
RECT WindowRect;
WindowRect.left=0;
WindowRect.top=0;
WindowRect.right=400;
WindowRect.bottom=400;
if(CWnd::Create(NULL,"AviWindow",WS_OVERLAPPED|WS_BORDER|WS_CAPTION|WS_VISIBLE|WS_CHILD,WindowRect,AfxGetMainWnd(),NULL,NULL))
      {            
      return(1);
      }

But I do not get a visible new child window when I call this method. I can call the program but nothing happens despite the fact that I get a warning:
Warning: calling DestroyWindow in CWnd::~CWnd; OnDestroy or PostNcDestroy in derived class will not be called.
What is wrong ?
ASKER CERTIFIED SOLUTION
Avatar of jhance
jhance

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of MarcoHelmers
MarcoHelmers

ASKER

This does not help me very much. I am trying to play a Video in Fullscreen Mode. Right now I am creating a child mci window and use Direct Draw to switch this window to Fullcreen Mode. Everything is alright. The video plays in Fullscreen Mode and stops when it is finished or 'ESC' is pressed. But if I try to do multitasking the applications hangs up. So I thought that it might help if I would switch back to normal mode when multitasking is performed. I know that I have to write this code into WM_ACTIVATEAPP (right?) but I can only do so if I have a new class in the class wizard which belongs to the Fullscreen Window. I cannot use the CMainFrame because in Fullscreen Mode I would have the Menu and the window frame and that does not look very good (or is there any possibility to hide those two things).
I'm afraid you've lost me.  The code I posted above will create a CWnd window on the screen of your specified size (400 x 400) as a child to the application's main window.  This is what you asked for.

If you do the following:

myWnd->Create(NULL, "AviWindow", WS_OVERLAPPED |WS_VISIBLE | WS_CHILD,WindowRect, AfxGetMainWnd(),NULL,NULL);

myWnd->ShowWindow(SW_SHOWMAXIMIZED);

You'll get a "blank" window without title bar or window controls.  It will also completely fill the owner window.
But I do not have a class to receive the WM_ACTIVATEAPP message with the code you offer, right ?
You didn't show your CWnd derived window class in the example above. Assuming that you have added a handler to that class for the WM_ACTIVATEAPP message and that your derived class is called MyDerivedCWnd, you create the window like this:

CWnd *myWnd = new MyDerivedCWnd();
if(!myWnd->Create(NULL, "AviWindow", WS_OVERLAPPED|WS_BORDER|WS_CAPTION|WS_VISIBLE | WS_CHILD,WindowRect,AfxGetMainWnd(),NULL,NULL)){
AfxMessageBox("Error in Create", MB_OK);
delete myWnd;
}

myWnd->ShowWindow(SW_SHOWNORMAL);


  Please describe the extent of the multitasking that you are trying to do.  If you are creating a worker thread, remember the threads get their own message queue, and you will need to pump messages with it.

-=- James.
I found out that it is not possible to create a new parent window with the create command of CWnd. Can you tell me how to do this with the CreateEx command ? I do not know which parameters to use when I only want to create a new parent window.
Here's an example of using the CWnd::CreateEx.  Again, this example uses CWnd but you should derive your own window class from CWnd and use it instead:


      CWnd *myWnd = new CWnd;
      if(!myWnd->CreateEx(
            0,
            AfxRegisterWndClass(0),
            "MyWindowName",
            WS_OVERLAPPEDWINDOW,
            0, 0, 500, 500,
            NULL,
            NULL,
            NULL
      )){
            AfxMessageBox("ERROR: CreateEx() failed!", MB_OK);
            delete myWnd;
            return;
      }
      myWnd->ShowWindow(SW_NORMAL);
Everything works fine now. The last small problem I have is the same I already described above : I receive a warning :

Warning: calling DestroyWindow in CWnd::~CWnd; OnDestroy or PostNcDestroy in derived class will not be called.

Why do I receive this warning and what can I do to avoid this ? Despite this warning everything works fine, but I am interested in getting to know what it means.
Microsoft Knowledge Base
PRB: "Warning: Calling DestroyWindow in CWnd::~CWnd" Message
Last reviewed: May 28, 1997
Article ID: Q105081  
The information in this article applies to:
The Microsoft Foundation Classes (MFC) included with:

    - Microsoft Visual C++ for Windows, versions 1.0, 1.5, 1.51, 1.52
    - Microsoft Visual C++ 32-bit Edition, versions 1.0, 2.0, 2.1, 4.0



SYMPTOMS
The following warnings are displayed when a debug version of a program is executed and TRACE() diagnostics are enabled:


   Warning: calling DestroyWindow in CWnd::~CWnd
   OnDestroy or PostNcDestroy in derived class will not be called

CAUSE
The above warnings are displayed by the CWnd::~CWnd() destructor. The warnings indicate the following:

The programmer has most likely called "delete" on a CWnd object rather than DestroyWindow().
An object derived from CWnd is not performing a DestroyWindow() call in its destructor.
Because the DestroyWindow() call is executed in the destructor for CWnd, only the CWnd portion of the CWnd-derived object is remaining when the DestroyWindow() is called. Thus, if you have a CWnd-derived object and receive this warning, the derived object's virtual functions will not exist and the CWnd functions will be called instead.

RESOLUTION
MFC Technote #17 contains more information on how to properly destroy a Window object and states the following cardinal rule:


   To destroy a C++ Windows object, use DestroyWindow, not "delete".

Also, examining CWnd::~CWnd() will reveal that the foremost task of the destructor is to ensure that the associated Windows window object has been destroyed. If a program calls DestroyWindow() before the CWnd destructor is called, the m_hWnd data member will be NULL, the TRACE0() messages will not occur, and DestroyWindow() will not be called in CWnd::~CWnd().