home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgLangD.iso / BORLAND TURBO / OWLSRC.PAK / MDICHILD.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-06  |  8.5 KB  |  326 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows
  3. // Copyright (c) 1991, 1997 by Borland International, All Rights Reserved
  4. //
  5. //$Revision:   10.8  $
  6. //
  7. // Implementation of TMDIChild. This defines the basic behavior of all MDI
  8. // child windows
  9. //----------------------------------------------------------------------------
  10. #pragma hdrignore SECTION
  11. #include <owl/pch.h>
  12. #if !defined(OWL_MDICHILD_H)
  13. # include <owl/mdichild.h>
  14. #endif
  15. #if !defined(OWL_MDI_H)
  16. # include <owl/mdi.h>
  17. #endif
  18. #if !defined(OWL_APPLICAT_H)
  19. # include <owl/applicat.h>
  20. #endif
  21.  
  22. OWL_DIAGINFO;
  23. DIAG_DECLARE_GROUP(OwlWin);  // diagnostic group for windows
  24.  
  25. #if !defined(WS_EX_MDICHILD)
  26. # define WS_EX_MDICHILD          0x00000040L
  27. #endif
  28.  
  29. //
  30. // Define to not work around here in the client, the 'creating MDI child
  31. // maximized corrupts the menu bar' bug
  32. //
  33. #if !defined(NO_MDIMAX_WORKAROUND)
  34. # define MDIMAX_WORKAROUND
  35. #endif
  36.  
  37. #if !defined(SECTION) || SECTION == 1
  38.  
  39. DEFINE_RESPONSE_TABLE1(TMDIChild, TFrameWindow)
  40.   EV_WM_MDIACTIVATE,
  41.   EV_WM_NCACTIVATE,
  42. END_RESPONSE_TABLE;
  43.  
  44. //
  45. // Constructor for a TMDIChild
  46. //
  47. TMDIChild::TMDIChild(TMDIClient&     parent,
  48.                      const char far* title,
  49.                      TWindow*        clientWnd,
  50.                      bool            shrinkToClient,
  51.                      TModule*        module)
  52. {
  53.   // Initialize virtual bases, in case the derived-most used default ctor
  54.   //
  55.   TWindow::Init(&parent, title, module);
  56.   TFrameWindow::Init(clientWnd, shrinkToClient);
  57.  
  58.   Attr.Style = WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
  59.                WS_SYSMENU | WS_CAPTION | WS_THICKFRAME |
  60.                WS_MINIMIZEBOX | WS_MAXIMIZEBOX;
  61.  
  62.   Attr.ExStyle |= WS_EX_MDICHILD;
  63.  
  64.   Attr.Y = Attr.H = CW_USEDEFAULT;
  65. }
  66.  
  67. //
  68. // Constructor for a TMDIChild which is being used in a DLL as an alias
  69. // for a non-OWL window
  70. //
  71. TMDIChild::TMDIChild(THandle handle, TModule* module)
  72. :
  73.   TFrameWindow(handle, module),
  74.   TWindow(handle, module)
  75. {
  76.   Attr.Style = WS_CLIPSIBLINGS;
  77.   Attr.ExStyle |= WS_EX_MDICHILD;
  78. }
  79.  
  80. //
  81. // Destructor for a MDI child
  82. //
  83. TMDIChild::~TMDIChild()
  84. {
  85. }
  86.  
  87. //
  88. // Don't allow NC Activation if we are only temporarily unhidden for window
  89. // menu maintainance
  90. //
  91. bool
  92. TMDIChild::EvNCActivate(bool active)
  93. {
  94.   return IsFlagSet(wfUnHidden) ? false : TFrameWindow::EvNCActivate(active);
  95. }
  96.  
  97. //
  98. // Perform special processing for showing MDI children to make sure that
  99. // the MDI client maintains the window list correctly
  100. //
  101. bool
  102. TMDIChild::ShowWindow(int cmdShow)
  103. {
  104.   int  retVal = TFrameWindow::ShowWindow(cmdShow);     // 0 if had been hidden
  105.  
  106.   // Process only if visible state has changed
  107.   //
  108.   if ((retVal != 0) != (cmdShow != SW_HIDE)) {
  109.     if ((THandle)Parent->HandleMessage(WM_MDIGETACTIVE) == *this) {
  110.       if (cmdShow == SW_HIDE)
  111.         Parent->HandleMessage(WM_MDINEXT, (uint)(THandle)*this);
  112.       else
  113.         HandleMessage(WM_NCACTIVATE, true); // resend suppressed message
  114.     }
  115. #if defined(BI_PLAT_WIN32)
  116.     Parent->HandleMessage(WM_MDIREFRESHMENU);
  117. #else
  118.     Parent->HandleMessage(WM_MDISETMENU, true);
  119. #endif
  120.   }
  121.   return retVal;
  122. }
  123.  
  124. //
  125. // Perform special processing for enabling MDI children to make sure that
  126. // the MDI client maintains the window list correctly
  127. //
  128. bool
  129. TMDIChild::EnableWindow(bool enable)
  130. {
  131.   int retVal = TFrameWindow::EnableWindow(enable);  // 0 if previously enabled
  132.  
  133.   // Process only if disabled state has actually changed
  134.   //
  135.   if ((retVal!=0) != (enable==0)) {
  136.     if (!enable && (THandle)Parent->HandleMessage(WM_MDIGETACTIVE) == *this)
  137.       Parent->HandleMessage(WM_MDINEXT, (uint)(THandle)*this);
  138. #if defined(BI_PLAT_WIN32)
  139.     Parent->HandleMessage(WM_MDIREFRESHMENU);
  140. #else
  141.     Parent->HandleMessage(WM_MDISETMENU, true);
  142. #endif
  143.   }
  144.   return retVal;
  145. }
  146.  
  147. //
  148. // If the MDI child has requested keyboard navigation then TFrameWindow's
  149. // PreProcessMsg() member function will call ::IsDialogMessage() which will
  150. // eat the event and the MDI client window won't get a chance to do MDI
  151. // accelerator processing
  152. //
  153. // So, we will do it here to make sure it gets done
  154. //
  155. bool
  156. TMDIChild::PreProcessMsg(MSG& msg)
  157. {
  158.   if (KeyboardHandling && Parent->PreProcessMsg(msg))
  159.     return true;
  160.  
  161.   if (HAccel && ::TranslateAccelerator(Parent->Parent->GetHandle(), HAccel, &msg))
  162.     return true;
  163.  
  164.   return TFrameWindow::PreProcessMsg(msg);
  165. }
  166.  
  167. //
  168. // Destroys the MS-Windows element associated with the TMDIChild
  169. //
  170. void
  171. TMDIChild::Destroy(int)
  172. {
  173.   if (GetHandle()) {
  174.     ForEach(::DoEnableAutoCreate);  // use iterator function in window.cpp
  175.  
  176.     if (Parent) {
  177.       // Send destroy message to MDI client window to have it destroy this THandle
  178.       //
  179.       Parent->HandleMessage(WM_MDIDESTROY, TParam1(GetHandle()));
  180.       SetHandle(0);  // Assume success
  181.     }
  182.     else {
  183.       if (::DestroyWindow(GetHandle()))
  184.         SetHandle(0);
  185.       GetApplication()->ResumeThrow();
  186.       WARNX(OwlWin, GetHandle(), 0, "::DestroyWindow(" << (uint)GetHandle() << ") failed");
  187.     }
  188.   }
  189. }
  190.  
  191. //
  192. // An MDI Child creates its GetHandle() by sending an MDI Create packet to the MDI
  193. // client.
  194. //
  195. void
  196. TMDIChild::PerformCreate(int)
  197. {
  198.   PRECONDITION(Parent);
  199.  
  200.   MDICREATESTRUCT  createStruct;
  201.   createStruct.szClass = GetClassName();
  202.   createStruct.szTitle = Title;
  203.   createStruct.hOwner = *GetModule();
  204.   createStruct.x = Attr.X;
  205.   createStruct.y = Attr.Y;
  206.   createStruct.cx = Attr.W;
  207.   createStruct.cy = Attr.H;
  208.   createStruct.style = Attr.Style;
  209.   createStruct.lParam = TParam2(Attr.Param);
  210.  
  211.   // Work around a Windows MDI bug w/ bad menus if MDI child is created
  212.   // maximized, by hiding child now & maximizing later
  213.   //
  214. #if defined(MDIMAX_WORKAROUND)
  215.   uint32 origStyle = Attr.Style;
  216.   if (createStruct.style & WS_MAXIMIZE)
  217.     createStruct.style &= ~(WS_MAXIMIZE | WS_VISIBLE);
  218. #endif
  219.  
  220.   SetHandle((THandle)Parent->HandleMessage(WM_MDICREATE, 0, TParam2(&createStruct)));
  221.  
  222.   // Finish up maximized MDI child workaround
  223.   //
  224. #if defined(MDIMAX_WORKAROUND)
  225.   if (GetHandle() && (origStyle & WS_MAXIMIZE)) {
  226.     Parent->HandleMessage(WM_MDIMAXIMIZE, TParam1(GetHandle()));
  227. #if defined(BI_PLAT_WIN32)
  228.     Parent->HandleMessage(WM_MDIREFRESHMENU);
  229. #else
  230.     Parent->HandleMessage(WM_MDISETMENU, true);
  231. #endif
  232.   }
  233. #endif
  234. }
  235.  
  236. //
  237. //
  238. //
  239. void
  240. TMDIChild::EvMDIActivate(THandle hActivated, THandle hDeactivated)
  241. {
  242.   if (GetHandle() == hActivated) {
  243.  
  244.     // A bug in Windows MDI causes the first MDI child to not get a
  245.     // WM_SETFOCUS. Simulate it now
  246.     //
  247.     if (!GetWindow(GW_HWNDNEXT) && GetFocus() != GetHandle())
  248.       HandleMessage(WM_SETFOCUS, TParam1(GetHandle()));
  249.  
  250.     // Merge this windows menubar with the MDI frame's if there is a
  251.     // MenuDescr assigned
  252.     //
  253.     if (GetMenuDescr()) {
  254.       TFrameWindow* frame = TYPESAFE_DOWNCAST(Parent->Parent,TFrameWindow);
  255.       if (frame)
  256.         frame->MergeMenu(*GetMenuDescr());
  257.     }
  258.   }
  259.   else {
  260.     // Restore the MDI frame's menubar if there is no other MDI child being
  261.     // activated
  262.     //
  263.     if (GetMenuDescr() && !hActivated) {
  264.       TFrameWindow* frame = TYPESAFE_DOWNCAST(Parent->Parent,TFrameWindow);
  265.       if (frame)
  266.         frame->RestoreMenu();
  267.     }
  268.   }
  269.  
  270.   // Forward MDI child activation to our client (if we have one) so that it can
  271.   // perform any type of activate/deactivate processing that it needs
  272.   //
  273.   TWindow* w = GetClientWindow();
  274.   if (w && w->IsWindow())
  275. #if defined(BI_PLAT_WIN32)
  276.     w->HandleMessage(WM_MDIACTIVATE, TParam1(hDeactivated), TParam2(hActivated));
  277. #else
  278.     w->HandleMessage(WM_MDIACTIVATE, 0, MkParam2(hActivated,hDeactivated));
  279. #endif
  280.  
  281.   DefaultProcessing();
  282. }
  283.  
  284. //
  285. // Override DefWindowProc to use DefMDIChildProc
  286. //
  287. TResult
  288. TMDIChild::DefWindowProc(uint msg, TParam1 param1, TParam2 param2)
  289. {
  290.   if (IsFlagSet(wfAlias))
  291.     return TWindow::DefWindowProc(msg, param1, param2);
  292.  
  293.   return ::DefMDIChildProc(GetHandle(), msg, param1, param2);
  294. }
  295.  
  296. #endif
  297. #if !defined(SECTION) || SECTION == 2
  298.  
  299.  
  300. IMPLEMENT_STREAMABLE2(TMDIChild, TFrameWindow, TWindow);
  301.  
  302. #if !defined(BI_NO_OBJ_STREAMING)
  303.  
  304. //
  305. // Reads data of the TMDIChild from the passed opstream
  306. //
  307. void*
  308. TMDIChild::Streamer::Read(ipstream& is, uint32 /*version*/) const
  309. {
  310.   ReadVirtualBase((TFrameWindow*)GetObject(), is);
  311.   return GetObject();
  312. }
  313.  
  314. //
  315. // Writes data of the TMDIChild to the passed opstream
  316. //
  317. void
  318. TMDIChild::Streamer::Write(opstream& os) const
  319. {
  320.   WriteVirtualBase((TFrameWindow*)GetObject(), os);
  321. }
  322.  
  323. #endif  // if !defined(BI_NO_OBJ_STREAMING)
  324.  
  325. #endif
  326.