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

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows
  3. // Copyright (c) 1992, 1997 by Borland International, All Rights Reserved
  4. //
  5. //$Revision:   10.15  $
  6. //
  7. // Implementation of class TFloatingFrame, a popup frame window that has a
  8. // small title bar
  9. //----------------------------------------------------------------------------
  10. #pragma hdrignore SECTION
  11. #include <owl/pch.h>
  12. #if !defined(OWL_FLOATFRA_H)
  13. # include <owl/floatfra.h>
  14. #endif
  15. #if !defined(WINSYS_UIMETRIC_H)
  16. # include <winsys/uimetric.h>
  17. #endif
  18.  
  19. OWL_DIAGINFO;
  20. DIAG_DECLARE_GROUP(OwlCmd);
  21.  
  22. #if !defined(SECTION) || SECTION == 1
  23.  
  24. //
  25. // Order is very important.  Must make sure that TTinyCaption gets 1st crack
  26. // after us
  27. //
  28. DEFINE_RESPONSE_TABLE2(TFloatingFrame, TTinyCaption, TFrameWindow)
  29.   EV_WM_SYSCOMMAND,
  30.   EV_WM_NCCALCSIZE,
  31.   EV_WM_NCPAINT,
  32.   EV_WM_NCHITTEST,
  33.   EV_WM_MOUSEACTIVATE,
  34.   EV_WM_NCACTIVATE,
  35.   EV_WM_ACTIVATEAPP,
  36. END_RESPONSE_TABLE;
  37.  
  38. //
  39. //
  40. //
  41. TFloatingFrame::TFloatingFrame(TWindow* owner, const char far* title,
  42.                                TWindow* client,
  43.                                bool shrinkToClient, int captionHeight,
  44.                                bool popupPalette, TModule* module)
  45. :
  46.   TFrameWindow(owner, title, client, shrinkToClient, module),
  47.   TTinyCaption(),
  48.   Margin(2, 2),
  49.   DragFrame(popupPalette)
  50. {
  51.   if (popupPalette) {
  52.     Attr.Style = WS_POPUP | WS_BORDER | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
  53.  
  54.     // Use close box (true) for palettes, & calc dimensions w/ new styles
  55.     //
  56.     EnableTinyCaption(captionHeight, true);
  57.  
  58.     // Windows with a popup style ignore CW_USEDEFAULT style, so we will
  59.     // specify a default size
  60.     //
  61.     // Normal use will be to specify a client and allow frame to sizeToClient
  62.     // so this size will rarely be used.
  63.     //
  64.     Attr.X = Attr.Y = 0;
  65.     Attr.W = 100;
  66.     Attr.H = 50;
  67.   }
  68.   else
  69.     // No close box for this non-popupPalette style
  70.     //
  71.     EnableTinyCaption(captionHeight, false);
  72.  
  73.   // Assume we should look active since our app just created us.
  74.   //
  75.   AppearActive = true;
  76.  
  77.   // The only area exposed when erasing will be the caption, so use an
  78.   // inactive-caption color so that full-drag over paints the right color
  79.   //
  80.   SetBkgndColor(TColor::SysInactiveCaption);
  81. }
  82.  
  83. //
  84. // Floating frames never route commands down to their children--just bubble it
  85. // up to the parent.
  86. //
  87. HWND
  88. TFloatingFrame::GetCommandTarget()
  89. {
  90.   TRACEX(OwlCmd, 1, "TFloatingFrame::GetCommandTarget - returns " << hex << \
  91.                     (GetParentO() ? uint(HWND(*GetParentO())) : uint(0)));
  92.   return GetParentO() ? HWND(*GetParentO()) : HWND(0);
  93. }
  94.  
  95. //
  96. // Change the receiver to be the framewindow not the floating frame window. 
  97. //
  98. void
  99. TFloatingFrame::EvCommandEnable(TCommandEnabler& commandEnabler)
  100. {
  101.   if (Parent) {
  102.     // Already being processed?
  103.     //
  104.     if (!commandEnabler.IsReceiver(Parent->GetHandle())) {
  105.       // No, so forward it up to our parent
  106.       //
  107.       commandEnabler.SetReceiver(Parent->GetHandle());
  108.       Parent->EvCommandEnable(commandEnabler);
  109.     }
  110.   }
  111. }
  112.  
  113. //
  114. // Resolve ambiguous mixin reference by passing EvCommand first to the tiny
  115. // caption and then to the frame bases.
  116. //
  117. TResult
  118. TFloatingFrame::EvCommand(uint id, THandle hWndCtl, uint notifyCode)
  119. {
  120.   TResult er;
  121.   if (TTinyCaption::DoCommand(id, hWndCtl, notifyCode, er) == esComplete)
  122.     return er;
  123.   if (Parent)
  124.     return Parent->EvCommand(id, hWndCtl, notifyCode);
  125.   return TFrameWindow::EvCommand(id, hWndCtl, notifyCode);
  126. }
  127.  
  128. //
  129. // This is an example of a mix-in that does partial event handling
  130. // We need to call the 'do' function for the mixin instead of the 'Ev' function
  131. // to avoid duplicate default processing
  132. //
  133. void
  134. TFloatingFrame::EvSysCommand(uint cmdType, TPoint& p)
  135. {
  136.   if (TTinyCaption::DoSysCommand(cmdType, p) == esComplete)
  137.     return;
  138.   TFrameWindow::EvSysCommand(cmdType,p);
  139.  
  140.   // Now we need to undo the activation that SysCommand/Size or Move has done
  141.   // to us. This does result in some flicker since we've already painted, but
  142.   // it would require more work to simulate the size/move to avoid the
  143.   // activation.
  144.   //
  145.   if ((cmdType & 0xFFF0) == SC_SIZE || (cmdType & 0xFFF0) == SC_MOVE)
  146.     GetApplication()->GetMainWindow()->SetActiveWindow();
  147. }
  148.  
  149. //
  150. // Handle WM_NCCALCSIZE to possibly add in the drag frame margins
  151. //
  152. uint
  153. TFloatingFrame::EvNCCalcSize(bool calcValidRects, NCCALCSIZE_PARAMS far& calcSize)
  154. {
  155.   uint er = TFrameWindow::EvNCCalcSize(calcValidRects, calcSize);
  156.  
  157.   // Adjust margins for extra edge around palette
  158.   //
  159.   if (DragFrame && !IsIconic()) {
  160.     calcSize.rgrc[0].left +=   Margin.cx * TUIMetric::CxBorder;
  161.     calcSize.rgrc[0].top +=    Margin.cy * TUIMetric::CyBorder;
  162.     calcSize.rgrc[0].right -=  Margin.cx * TUIMetric::CxBorder;
  163.     calcSize.rgrc[0].bottom -= Margin.cy * TUIMetric::CyBorder;
  164.   }
  165.  
  166.   // Now invoke the TTinyCaption worker method to do the rest of the
  167.   // calculations
  168.   //
  169.   DoNCCalcSize(calcValidRects, calcSize, er);
  170.  
  171.   return er;
  172. }
  173.  
  174. //
  175. // Handle WM_NCPAINT to paint the non-client areas of this window
  176. //
  177. // We only need to paint the drag frame margins. TWindow (via DefWindowProc)
  178. // will paint the borders, & TTinyCaption will paint the caption
  179. //
  180. #if defined(BI_PLAT_WIN32)
  181. void TFloatingFrame::EvNCPaint(HRGN)
  182. #else
  183. void TFloatingFrame::EvNCPaint()
  184. #endif
  185. {
  186.   DefaultProcessing();       // Default border painting--no caption
  187.  
  188.   // Paint our caption below with possible fake active look. arg is ignored.
  189.   //
  190.   EvNCActivate(true);
  191.  
  192.   // If enabled, paint drag frame margins in 3d face color
  193.   //
  194.   if (DragFrame) {
  195.     TWindowDC dc(*(TWindow*)this);  // Cast is an MSVC bug workaround
  196.     TRect     wr = GetWindowRect().InflatedBy(-Frame);
  197.     wr -= wr.TopLeft();
  198.     wr += Border;
  199.     wr.top = GetCaptionRect().bottom;
  200.     int mx = Margin.cx * Border.cx;
  201.     int my = Margin.cy * Border.cy;
  202.  
  203.     dc.SetBkColor(TColor::Sys3dFace);
  204.     dc.TextRect(wr.left, wr.top, wr.left+mx, wr.bottom);           // left
  205.     dc.TextRect(wr.left+mx, wr.top, wr.right-mx, wr.top+my);       // top
  206.     dc.TextRect(wr.right-mx, wr.top, wr.right, wr.bottom);         // right
  207.     dc.TextRect(wr.left+mx, wr.bottom-my, wr.right-mx, wr.bottom); // bottom
  208.   }
  209. }
  210.  
  211. //
  212. // Return where in the non client area the mouse is. We delegate to tiny
  213. // caption for caption bar area, and when in DragFrame mode, make our frame
  214. // act like a caption for dragging.
  215. //
  216. uint
  217. TFloatingFrame::EvNCHitTest(TPoint& screenPt)
  218. {
  219.   uint er;
  220.   if (TTinyCaption::DoNCHitTest(screenPt, er) == esComplete ||
  221.       DoNCHitTest(screenPt, er) == esComplete)
  222.     return er;
  223.   return TWindow::EvNCHitTest(screenPt);
  224. }
  225.  
  226. //
  227. //
  228. //
  229. TEventStatus
  230. TFloatingFrame::DoNCHitTest(TPoint& screenPt, uint& evRes)
  231. {
  232.   if (DragFrame) {
  233.     TPoint clientOffs(0,0);
  234.     ClientToScreen(clientOffs);
  235.     if (!GetClientRect().Contains(screenPt-clientOffs)) {
  236.       evRes = HTCAPTION;
  237.       return esComplete;
  238.     }
  239.   }
  240.   return esPartial;
  241. }
  242.  
  243. //
  244. // Handle WM_NCMOUSEACTIVATE in order to decline activation. Also, in order to'
  245. // take care of the user trying to activate this app, we activate the main
  246. // window.
  247. //
  248. uint
  249. TFloatingFrame::EvMouseActivate(THandle /*hWndTopLevel*/, uint /*hitTestCode*/,
  250.                                 uint /*msg*/)
  251. {
  252.   // Make our main window active if the current active is not in this
  253.   // process
  254.   //
  255. #if defined(BI_PLAT_WIN16)
  256.   HWND active = GetActiveWindow();
  257.   if (!active || ::GetWindowTask(active) != GetCurrentTask())
  258. #else
  259.   if (!GetActiveWindow())
  260. #endif
  261.     GetApplication()->GetMainWindow()->SetActiveWindow();
  262.  
  263.   EvNCActivate(true);   // Make sure we look active
  264.   return MA_NOACTIVATE;
  265. }
  266.  
  267. //
  268. // Handle WM_NCACTIVATE to paint the caption with our notion of active
  269. // appearance--either with our own caption paint routine, or with underlying
  270. // classes routine.
  271. //
  272. // The caption will apear active as long as this app is active.
  273. //
  274. bool
  275. TFloatingFrame::EvNCActivate(bool /*active*/)
  276. {
  277.   if (!IsIconic()) {
  278.     if (TCEnabled)
  279.       PaintCaption(AppearActive);
  280.     else
  281.       DefWindowProc(WM_NCACTIVATE, AppearActive, 0);
  282.   }
  283.   return true;
  284. }
  285.  
  286. //
  287. // Handle WM_ACTIVATEAPP to know & track when to appear active--that is
  288. // whenever this app is activated
  289. //
  290. void
  291. TFloatingFrame::EvActivateApp(bool active, HTASK /*threadId*/)
  292. {
  293.   AppearActive = active;
  294.  
  295.   EvNCActivate(AppearActive);
  296.   DefaultProcessing();
  297. }
  298.  
  299. #endif
  300. #if !defined(SECTION) || SECTION == 2
  301.  
  302. IMPLEMENT_STREAMABLE2(TFloatingFrame, TTinyCaption, TFrameWindow);
  303.  
  304. #if !defined(BI_NO_OBJ_STREAMING)
  305.  
  306. //
  307. //
  308. //
  309. void*
  310. TFloatingFrame::Streamer::Read(ipstream& is, uint32 /*version*/) const
  311. {
  312.   TFloatingFrame* o = GetObject();
  313.   ReadBaseObject((TFrameWindow*)o, is);
  314.   ReadBaseObject((TTinyCaption*)o, is);
  315.   is >> o->Margin;
  316.   return o;
  317. }
  318.  
  319. //
  320. //
  321. //
  322. void
  323. TFloatingFrame::Streamer::Write(opstream& os) const
  324. {
  325.   TFloatingFrame* o = GetObject();
  326.   WriteBaseObject((TFrameWindow*)o, os);
  327.   WriteBaseObject((TTinyCaption*)o, os);
  328.   os << o->Margin;
  329. }
  330.  
  331. #endif  // if !defined(BI_NO_OBJ_STREAMING)
  332.  
  333. #endif
  334.