home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c083 / 11.ddi / OWLSRC.PAK / MDICLIEN.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-02  |  7.3 KB  |  307 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows - (C) Copyright 1991, 1993 by Borland International
  3. //   source\owl\mdiclien.cpp
  4. //   Implementation of class TMDIClient.  This defines the basic behavior
  5. //   of all MDI client windows.
  6. //----------------------------------------------------------------------------
  7. #pragma hdrignore SECTION
  8. #include <owl\owlpch.h>
  9. #include <owl\mdi.h>
  10.  
  11. #if !defined(SECTION) || SECTION == 1
  12.  
  13. DEFINE_RESPONSE_TABLE1(TMDIClient, TWindow)
  14.   EV_COMMAND(CM_CREATECHILD, CmCreateChild),
  15.   EV_COMMAND(CM_TILECHILDREN, CmTileChildren),
  16.   EV_COMMAND(CM_TILECHILDRENHORIZ, CmTileChildrenHoriz),
  17.   EV_COMMAND(CM_CASCADECHILDREN, CmCascadeChildren),
  18.   EV_COMMAND(CM_ARRANGEICONS, CmArrangeIcons),
  19.   EV_COMMAND(CM_CLOSECHILDREN, CmCloseChildren),
  20.   EV_COMMAND_ENABLE(CM_TILECHILDREN, CmChildActionEnable),
  21.   EV_COMMAND_ENABLE(CM_CASCADECHILDREN, CmChildActionEnable),
  22.   EV_COMMAND_ENABLE(CM_ARRANGEICONS, CmChildActionEnable),
  23.   EV_COMMAND_ENABLE(CM_CLOSECHILDREN, CmChildActionEnable),
  24.   EV_WM_MDICREATE,
  25.   EV_WM_MDIDESTROY,
  26. END_RESPONSE_TABLE;
  27.  
  28. //
  29. // constructor for a TMDIClient
  30. //
  31. // allocates space for the CLIENTCREATESTRUCT on the heap and sets
  32. // ClientAttr to point to this space
  33. //
  34. TMDIClient::TMDIClient(TModule* module)
  35. {
  36.   //
  37.   // Initialize virtual base, in case the derived-most used default ctor
  38.   //
  39.   TWindow::Init(0, 0, module);
  40.  
  41.   Attr.Id = IDW_MDICLIENT;
  42.   //
  43.   // allow client area to grow scroll bars if necessary
  44.   //
  45.   Attr.Style |= MDIS_ALLCHILDSTYLES | WS_GROUP | WS_TABSTOP | WS_CLIPCHILDREN|
  46.                 WS_VSCROLL | WS_HSCROLL;
  47.   ClientAttr = new CLIENTCREATESTRUCT; // far
  48.   ClientAttr->hWindowMenu = 0;
  49.   ClientAttr->idFirstChild = IDW_FIRSTMDICHILD;
  50.   Attr.Param = (LPSTR)ClientAttr;
  51.   SetFlag(wfStreamTop);
  52. }
  53.  
  54. //
  55. // constructor for a TMDIClient which is being used in a DLL as an alias
  56. // for a non-OWL window. This ctor is generally not used by derived
  57. // classes
  58. //
  59. TMDIClient::TMDIClient(HWND hWnd, TModule* module)
  60.   : TWindow(hWnd, module)
  61. {
  62.   ClientAttr = 0;
  63.   SetFlag(wfStreamTop);
  64. }
  65.  
  66. //
  67. // frees the memory associated with ClientAttr
  68. //
  69. TMDIClient::~TMDIClient()
  70. {
  71.   delete ClientAttr;
  72. }
  73.  
  74. char far*
  75. TMDIClient::GetClassName()
  76. {
  77.   return "MDICLIENT";
  78. }
  79.  
  80. TMDIChild*
  81. TMDIClient::GetActiveMDIChild()
  82. {
  83.   HWND hWnd = (HWND)HandleMessage(WM_MDIGETACTIVE);
  84.  
  85.   return TYPESAFE_DOWNCAST(GetWindowPtr(hWnd),TMDIChild);
  86. }
  87.  
  88. void
  89. TMDIClient::ArrangeIcons()
  90. {
  91.   HandleMessage(WM_MDIICONARRANGE);
  92. }
  93.  
  94. void
  95. TMDIClient::CascadeChildren()
  96. {
  97.   HandleMessage(WM_MDICASCADE);
  98. }
  99.  
  100. void
  101. TMDIClient::TileChildren(int tile)
  102. {
  103.   HandleMessage(WM_MDITILE, tile);
  104. }
  105.  
  106. BOOL
  107. TMDIClient::PreProcessMsg(MSG& msg)
  108. {
  109.   if (msg.message == WM_KEYDOWN || msg.message == WM_SYSKEYDOWN)
  110.     return TranslateMDISysAccel(HWindow, &msg);
  111.  
  112.   else
  113.     return FALSE;
  114. }
  115.  
  116. BOOL
  117. TMDIClient::Create()
  118. {
  119.   TMDIFrame*  frame = TYPESAFE_DOWNCAST(Parent,TMDIFrame);
  120.   
  121.   CHECK(frame);
  122.  
  123.   ClientAttr->hWindowMenu = frame->FindChildMenu(frame->GetMenu());
  124.   return TWindow::Create();
  125. }
  126.  
  127. //
  128. // creates a valid new MDI child window after calling InitChild() to construct
  129. // a new MDI child window object
  130. //
  131. TWindow*
  132. TMDIClient::CreateChild()
  133. {
  134.   TMDIChild* child = InitChild();
  135.   CHECK(child);
  136.   if (child->Create())
  137.     return child;
  138.   return 0;
  139. }
  140.  
  141. TMDIChild*
  142. TMDIClient::InitChild()
  143. {
  144.   return new TMDIChild(*this);
  145. }
  146.  
  147. static BOOL
  148. CannotClose(TWindow* win, void*)
  149. {
  150.   return !win->CanClose();
  151. }
  152.  
  153. static void
  154. CloseChild(TWindow* win, void*)
  155. {
  156.   win->Destroy();
  157.   delete win;
  158. }
  159.  
  160. //
  161. // closes each MDI child, after calling the child's CanClose() method to
  162. // ensure that it is Ok to do so
  163. //
  164. // returns TRUE if all children are closed(or there were no children),
  165. // FALSE if any child can't be closed
  166. //
  167. BOOL
  168. TMDIClient::CloseChildren()
  169. {
  170.   if (!FirstThat(CannotClose)) {
  171.     ForEach(CloseChild);
  172.     return TRUE;
  173.   }
  174.   return FALSE;
  175. }
  176.  
  177. //
  178. // fill in default child window styles if they request style 0 since this
  179. // client by default has set allchildstyles
  180. //
  181. LRESULT
  182. TMDIClient::EvMDICreate(MDICREATESTRUCT far& createStruct)
  183. {
  184.   if ((Attr.Style&MDIS_ALLCHILDSTYLES) && !createStruct.style)
  185.     createStruct.style =
  186.                WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
  187.                WS_SYSMENU | WS_CAPTION | WS_THICKFRAME |
  188.                WS_MINIMIZEBOX | WS_MAXIMIZEBOX;
  189.  
  190.   //
  191.   // deal with create maximized child problems
  192.   //
  193.   DWORD origStyle = createStruct.style;
  194.   if (createStruct.style & WS_MAXIMIZE) {
  195.     SetRedraw(FALSE);
  196.     createStruct.style &= ~(WS_MAXIMIZE | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL);
  197.     createStruct.style |= WS_DISABLED;
  198.   }
  199.  
  200.   LRESULT result = DefaultProcessing();
  201.  
  202.   if (HWND(result) && (origStyle & WS_MAXIMIZE)) {
  203.     SetRedraw(TRUE);
  204.  
  205.     if (!(origStyle & WS_DISABLED))
  206.       ::EnableWindow(HWND(result), TRUE);
  207.  
  208.     HandleMessage(WM_MDIMAXIMIZE, WPARAM(result));
  209.  
  210.     ::SetWindowLong(HWND(result), GWL_STYLE, origStyle);
  211.   }
  212.  
  213.   return result;
  214. }
  215.  
  216. //
  217. // When an MDI child is destroyed while other children are hidden or disabled,
  218. // the Windows MDI child management gets confused causing subsequent failure.
  219. // To prevent this, we temporarily unhide and enable siblings during destroy.
  220. //
  221. static void sUnHide(TWindow* win, void* hWnd)
  222. {
  223.   if (*win == (HWND)hWnd)
  224.     return;
  225.   if (!win->IsWindowVisible()) {
  226.     win->SetWindowPos(0,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_SHOWWINDOW|SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOREDRAW);
  227.     win->SetFlag(wfUnHidden);
  228.   }
  229.   if (!win->IsWindowEnabled()) {
  230.     win->EnableWindow(TRUE);
  231.     win->SetFlag(wfUnDisabled);
  232.   }
  233. }
  234.  
  235. static void sReHide(TWindow* win, void*)
  236. {
  237.   if (!*win)
  238.     return;
  239.   if (win->IsFlagSet(wfUnHidden)) {
  240.     win->ClearFlag(wfUnHidden);
  241.     win->ShowWindow(SW_HIDE);
  242.   }
  243.   if (win->IsFlagSet(wfUnDisabled)) {
  244.     win->ClearFlag(wfUnDisabled);
  245.     win->EnableWindow(FALSE);
  246.   }
  247. }
  248.  
  249. void
  250. TMDIClient::EvMDIDestroy(HWND hWnd)
  251. {
  252.   ForEach(sUnHide,(void*)hWnd);
  253.   DefaultProcessing();
  254.   ForEach(sReHide, 0);
  255. #if defined(__WIN32__)
  256.   HandleMessage(WM_MDIREFRESHMENU);
  257. #else
  258.   HandleMessage(WM_MDISETMENU, TRUE);
  259. #endif
  260. }
  261.  
  262. //
  263. // Enables any of the child action menu items if any MDI children exit
  264. //
  265. void
  266. TMDIClient::CmChildActionEnable(TCommandEnabler& commandEnabler)
  267. {
  268.   commandEnabler.Enable(GetFirstChild() != 0);
  269. }
  270.  
  271.  
  272. #endif
  273. #if !defined(SECTION) || SECTION == 2
  274.  
  275. IMPLEMENT_STREAMABLE1(TMDIClient, TWindow);
  276.  
  277. //
  278. // reads an instance of TMDIClient from the passed ipstream
  279. //
  280. void*
  281. TMDIClient::Streamer::Read(ipstream& is, uint32 /*version*/) const
  282. {
  283.   ReadBaseObject((TWindow*)GetObject(), is);
  284.  
  285.   GetObject()->ClientAttr = new CLIENTCREATESTRUCT;  //far
  286.  
  287.   UINT idFirstChild;  // Need temp for near data model since ClientAttr is far
  288.   is >> idFirstChild;
  289.   GetObject()->ClientAttr->idFirstChild = idFirstChild;
  290.   GetObject()->ClientAttr->hWindowMenu = (HMENU) 0;
  291.   GetObject()->Attr.Param = (LPSTR)GetObject()->ClientAttr;
  292.  
  293.   return GetObject();
  294. }
  295.  
  296. //
  297. // writes the TMDIClient to the passed opstream
  298. //
  299. void
  300. TMDIClient::Streamer::Write(opstream& os) const
  301. {
  302.   WriteBaseObject((TWindow*)GetObject(), os);
  303.   os << GetObject()->ClientAttr->idFirstChild;
  304. }
  305.  
  306. #endif
  307.