home *** CD-ROM | disk | FTP | other *** search
/ Prima Shareware 3 / DuCom_Prima-Shareware-3_cd1.bin / PROGRAMO / C / MRCE / SOURCE.ZIP / SIZECONT.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1995-12-28  |  14.0 KB  |  429 lines

  1. // MRCEXT: Micro Focus Extension DLL for MFC 2.1+
  2. // Copyright (C)1994-5    Micro Focus Inc, 2465 East Bayshore Rd, Palo Alto, CA 94303.
  3. // 
  4. //  This program is free software; you can redistribute it and/or modify
  5. //  it under the terms of the GNU General Public License as published by
  6. //  the Free Software Foundation. In addition, you may also charge for any
  7. //  application    using MRCEXT, and are under no obligation to supply source
  8. //  code. You must accredit Micro Focus Inc in the "About Box", or banner
  9. //  of your application. 
  10. //
  11. //  This program is distributed in the hope that it will be useful,
  12. //  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. //  GNU General Public License for more details.
  15. //
  16. //  You should also have received a copy of the GNU General Public License with this
  17. //  software, also indicating additional rights you have when using MRCEXT.  
  18. //
  19. //
  20. // SIZECONT.CPP
  21. // $Date:   28 Dec 1995 18:58:58  $
  22. // $Revision:   1.1  $
  23. // $Author:   MRC  $
  24. // sizecont.cpp : implementation file
  25. // Sizeable Control Bar
  26.  
  27. #include "mrcstafx.h"
  28. #include "mrcext.h"
  29. #include "mrcpriv.h"
  30. #include "mrcresrc.h"
  31.  
  32. extern MRC_AUX_DATA afxData;
  33.  
  34. #ifdef _DEBUG
  35. #undef THIS_FILE
  36. static char BASED_CODE THIS_FILE[] = __FILE__;
  37. #endif
  38.  
  39. IMPLEMENT_DYNAMIC(CMRCSizeControlBar, CControlBar)
  40.  
  41. /////////////////////////////////////////////////////////////////////////////
  42. /////////////////////////////////////////////////////////////////////////////
  43. // CMRCSizeControlBar
  44.  
  45.  
  46. CObArray * CMRCSizeControlBar::m_parrAllocBars;    
  47.  
  48. void CMRCSizeControlBar::TidyUp()
  49. {
  50. // just need to delete the contents of the array - the destructor will remove the element
  51. // from the array. 
  52.     if (m_parrAllocBars != NULL)
  53.     {
  54.         for (int i = m_parrAllocBars->GetUpperBound(); i >= 0; i--)
  55.         {
  56.             ASSERT((*m_parrAllocBars)[i]->IsKindOf(RUNTIME_CLASS(CMRCSizeControlBar)));
  57.             delete ((*m_parrAllocBars)[i]);
  58.         }
  59.         delete m_parrAllocBars;
  60.         m_parrAllocBars = NULL;
  61.     }
  62. }
  63.  
  64.  
  65. CMRCSizeControlBar::CMRCSizeControlBar(int nStyle)
  66. {
  67.     m_Style = nStyle;                        
  68.     m_PrevSize.cx = 0xffff;         // dummy values so WindowPosChanged will respond correctly
  69.     m_bPrevFloating = 3;            // neither TRUE not FALSE;
  70.  
  71.     m_FloatingPosition  = CPoint(0,0);    
  72.     m_dwAllowDockingState = 0;
  73.     if (nStyle & SZBARF_AUTOTIDY)
  74.     {
  75.         if (m_parrAllocBars == NULL)
  76.             m_parrAllocBars = new CObArray;
  77.         
  78.         m_parrAllocBars->Add(this);
  79.     }
  80. }
  81.  
  82.  
  83. CMRCSizeControlBar::~CMRCSizeControlBar()
  84. {
  85.     // if the bar was created with this flag, then ensure it is deleted with it also.
  86.     if (m_Style & SZBARF_AUTOTIDY)
  87.     {
  88.         int i;
  89.         for (i = m_parrAllocBars->GetUpperBound(); i >= 0; i--)
  90.             if ((*m_parrAllocBars)[i] == this)    
  91.             {
  92.                 m_parrAllocBars->RemoveAt(i);
  93.                 break;
  94.             }
  95.         ASSERT(i >= 0);            // means we didn't delete this item from the list
  96.     }
  97.  
  98.     // This loop of debug code checks that we don;t have any other references in the array.
  99.     // This happens if we changed the auto delete flag during the lifetime of the control bar.
  100. #ifdef _DEBUG
  101.     if (m_parrAllocBars != NULL)
  102.     {
  103.         for (int i = m_parrAllocBars->GetUpperBound(); i >= 0; i--)
  104.             ASSERT ((*m_parrAllocBars)[i] != this);    
  105.     }
  106. #endif
  107.  
  108.     // delete the dock context here - in an attempt to call the correct destructor
  109.     delete (CDragDockContext *) m_pDockContext;
  110.     m_pDockContext = NULL;
  111. }
  112.  
  113.  
  114. BEGIN_MESSAGE_MAP(CMRCSizeControlBar, CControlBar)
  115.         //{{AFX_MSG_MAP(CMRCSizeControlBar)
  116.     ON_WM_WINDOWPOSCHANGED()
  117.     ON_WM_ERASEBKGND()
  118.     ON_WM_LBUTTONDBLCLK()
  119.     ON_WM_PAINT()
  120.     ON_WM_SYSCOMMAND()
  121.     ON_WM_CONTEXTMENU()
  122.     //}}AFX_MSG_MAP
  123.     ON_COMMAND(ID_MRC_HIDE, OnHide)
  124.     ON_COMMAND(ID_MRC_ALLOWDOCKING, OnToggleAllowDocking)
  125.     ON_COMMAND(ID_MRC_MDIFLOAT,    OnFloatAsMDI)
  126.     ON_MESSAGE(WM_ADDCONTEXTMENUITEMS, OnAddContextMenuItems)
  127. END_MESSAGE_MAP()
  128.  
  129.  
  130. /////////////////////////////////////////////////////////////////////////////
  131. // CMRCSizeControlBar message handlers
  132. CSize CMRCSizeControlBar::CalcFixedLayout(BOOL bStretch, BOOL bHorz)
  133. {
  134. #ifdef _VERBOSE_TRACE
  135.     CString strTitle;
  136.     GetWindowText(strTitle);
  137.     TRACE("CalcFixedLayout: '%s' Horz(%d,%d)\n", LPCTSTR(strTitle), 
  138.                 m_HorzDockSize.cx, m_HorzDockSize.cy);
  139. #endif    
  140.     CControlBar::CalcFixedLayout(bStretch, bHorz);
  141.     if (IsFloating())
  142.         return m_FloatSize;
  143.  
  144.     if (bHorz)
  145.         return m_HorzDockSize;
  146.     else
  147.         return m_VertDockSize;
  148. }
  149.  
  150.  
  151. //-----------------------------------------------------------------------------------------
  152. void CMRCSizeControlBar::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler)
  153. //-----------------------------------------------------------------------------------------
  154. // need to supply this, or else we can't instantiate the class. Derived classes should
  155. // subclass this if they need to update their gadgets using this interface
  156. {
  157. }
  158.  
  159.  
  160. //-----------------------------------------------------------------------------------------
  161. BOOL CMRCSizeControlBar::Create(CWnd * pParent, LPCTSTR lpszTitle, UINT nID, DWORD dwStyle,
  162.                                                            const RECT & rect)
  163. //-----------------------------------------------------------------------------------------
  164. {
  165.     ASSERT(pParent != NULL);
  166.  
  167.     // have to set the style here
  168.     m_dwStyle = dwStyle;
  169.  
  170.     CRect Rectx;
  171.     Rectx = rect;
  172.  
  173.     // calculate a sensible default rectangle if that's what the user wanted...
  174.     if (memcmp(&rect, &CFrameWnd::rectDefault, sizeof(RECT)) == 0)
  175.     {
  176.         pParent->GetClientRect(&Rectx);
  177.         CSize def;
  178.         def.cx = Rectx.right / 2;
  179.         def.cy = Rectx.bottom  / 4;
  180.         Rectx.left = Rectx.right - def.cx;
  181.         Rectx.top  = Rectx.bottom - def.cy;
  182.     }
  183.  
  184.        // the rectangle specifies the default floating size.
  185.        m_FloatSize = Rectx.Size();
  186.     
  187.     // set default values for the docked sizes, based on this size.
  188.     m_HorzDockSize.cx = m_FloatSize.cx;
  189.     m_HorzDockSize.cy = m_FloatSize.cy / 2;    
  190.  
  191.     m_VertDockSize.cx = m_HorzDockSize.cy * 3 / 2;
  192.     m_VertDockSize.cy = m_HorzDockSize.cx * 2 / 3;
  193.         
  194.     return CControlBar::Create(NULL, lpszTitle, dwStyle, Rectx, pParent, nID);
  195. }
  196.  
  197.  
  198. void CMRCSizeControlBar::SetSizeDockStyle(DWORD dwStyle)
  199. {
  200.     m_Style = dwStyle;
  201. }
  202.  
  203.  
  204. //------------------------------------------------------------------------------------
  205. void CMRCSizeControlBar::EnableDocking(DWORD dwDockStyle)
  206. // Largely a copy of CControlBar::EnableDocking() - but uses a different class for the
  207. // m_pDockContext, to give us different (hopefully you'll think better) dragging 
  208. // behaviour.
  209. //------------------------------------------------------------------------------------
  210. {
  211.     // must be CBRS_ALIGN_XXX or CBRS_FLOAT_MULTI only
  212.     ASSERT((dwDockStyle & ~(CBRS_ALIGN_ANY|CBRS_FLOAT_MULTI)) == 0);
  213.  
  214.     m_dwDockStyle = dwDockStyle;
  215.     if (m_pDockContext == NULL)
  216.         m_pDockContext = new CDragDockContext(this);
  217.     
  218.     // permanently wire the bar's owner to its current parent
  219.     if (m_hWndOwner == NULL)
  220.         m_hWndOwner = ::GetParent(m_hWnd);
  221. }
  222.  
  223.  
  224.  
  225. //--------------------------------------------------------------------------
  226. BOOL CMRCSizeControlBar::OnEraseBkgnd(CDC* pDC)
  227. // paint the background of the window - probably want a style flag to turn this
  228. // off as for many control bars it won't be required.
  229. //--------------------------------------------------------------------------
  230. {
  231.     CRect rect;
  232.     pDC->GetClipBox(&rect);
  233.     pDC->FillSolidRect(&rect, afxData.clrBtnFace); 
  234.     return TRUE;
  235. }
  236.  
  237.  
  238. //--------------------------------------------------------------------------
  239. LRESULT CMRCSizeControlBar::WindowProc(UINT nMsg, WPARAM wParam, LPARAM lParam)
  240. // Normally a CControlBar would just pass most of these messages through to
  241. // the parent. We want to handle them properly though - again may be this should
  242. // be a behviour flag
  243. //--------------------------------------------------------------------------
  244. {
  245.     ASSERT_VALID(this);
  246.  
  247.     // We need to ensure WM_COMMAND and other messages get through to the derived class.
  248.     // Primarily done so we receive notifications from child windows. The default CControlBar
  249.     // code routes messsages through to the parent. This means WM_COMMANDs, etc make their
  250.     // way to a FrameWnd eventually. This is needed for toolbar's, dialog bars, etc, but isn't
  251.     // very useful if we want to put controls on a CMRCSizeControlBar and process them 
  252.     // locally
  253.        
  254.     // In case any of these messages are actually needed by the owner window, we check to see
  255.     // if CWnd would handle them first. If not, then we pass them through to the owner window,
  256.     // as CControlBar would.
  257.  
  258.     switch (nMsg)
  259.     {
  260.     case WM_COMMAND:
  261.         if (OnCommand(wParam, lParam))          // post normal commands....
  262.             return 1L; // command handled
  263.         break;
  264.  
  265.     }
  266.     return CControlBar::WindowProc(nMsg, wParam, lParam);
  267. }
  268.  
  269.  
  270. //------------------------------------------------------------------
  271. void CMRCSizeControlBar::OnWindowPosChanged(WINDOWPOS * lpwndpos)
  272. //------------------------------------------------------------------
  273. {
  274.     CControlBar::OnWindowPosChanged(lpwndpos);
  275.  
  276.     CSize NewSize(lpwndpos->cx, lpwndpos->cy);
  277.     // This is meant to return "floating" if we're not docked yet...
  278.     BOOL bFloating;
  279.     if (m_pDockBar != NULL)
  280.         bFloating = m_pDockBar->m_bFloating;
  281.     else
  282.         bFloating = TRUE;
  283.         
  284.     int Flags = (NewSize == m_PrevSize ? 0 : 1);
  285.     Flags |= (bFloating == m_bPrevFloating ? 0 : 2);
  286.     if (Flags != 0)
  287.     {
  288.         m_PrevSize = NewSize;
  289.         m_bPrevFloating = bFloating;
  290.         OnSizedOrDocked(NewSize.cx, NewSize.cy, bFloating, Flags);
  291.     }
  292. }
  293.  
  294.  
  295. //------------------------------------------------------------------
  296. void CMRCSizeControlBar::OnSizedOrDocked(int cx, int cy, BOOL bFloating, int flags)
  297. // override this function to respond to a redraw as a result of a
  298. // resize or docked/undocked notification
  299. //------------------------------------------------------------------
  300. {
  301. }
  302.  
  303.  
  304. //------------------------------------------------------------------
  305. BOOL CMRCSizeControlBar::IsProbablyFloating()
  306. //------------------------------------------------------------------
  307.     return (m_pDockBar == NULL || m_pDockBar->m_bFloating == TRUE);
  308. }
  309.  
  310.  
  311. //--------------------------------------------------------------------------
  312. LONG CMRCSizeControlBar::OnAddContextMenuItems(WPARAM wParam, LPARAM lParam)
  313. //--------------------------------------------------------------------------
  314. {
  315.     HMENU hMenu = (HMENU)lParam;        // handle of menu.
  316.     CMenu Menu;
  317.     Menu.Attach(hMenu);
  318.  
  319.     DWORD dwDockStyle = m_dwDockStyle & CBRS_ALIGN_ANY;
  320.     DWORD style;
  321.     CString strMenu;
  322.  
  323.     BOOL bMDIFloating = FALSE;
  324.     CFrameWnd *pParentFrame = GetParentFrame();
  325.     if (IsFloating())
  326.     {
  327.         if (pParentFrame != NULL && pParentFrame->IsKindOf(RUNTIME_CLASS(CMRCMDIFloatWnd)))
  328.         {
  329.             bMDIFloating = TRUE;
  330.         }
  331.     }
  332.     style = (bMDIFloating ? MF_STRING | MF_CHECKED : MF_STRING);
  333.     
  334.     // if allowed - add the float as MDI floating window
  335.     if (m_Style & SZBARF_ALLOW_MDI_FLOAT)
  336.     {    
  337.         VERIFY(strMenu.LoadString(ID_MRC_MDIFLOAT));
  338.         Menu.AppendMenu(style, ID_MRC_MDIFLOAT, strMenu);
  339.     }
  340.     
  341.     if (!bMDIFloating && (dwDockStyle != 0 || m_dwAllowDockingState != 0))    // ie docking is actually allowed ...
  342.     {
  343.         DWORD style = (dwDockStyle != 0 ? MF_STRING | MF_CHECKED : MF_STRING);
  344.         VERIFY(strMenu.LoadString(ID_MRC_ALLOWDOCKING));
  345.         Menu.AppendMenu(style, ID_MRC_ALLOWDOCKING, strMenu);
  346.     }
  347.     VERIFY(strMenu.LoadString(ID_MRC_HIDE));
  348.     Menu.AppendMenu(MF_STRING, ID_MRC_HIDE, strMenu);
  349.  
  350.     Menu.Detach();    // detatch MFC object
  351.     return TRUE;
  352. }
  353.  
  354.  
  355. //------------------------------------------------------------------
  356. void CMRCSizeControlBar::OnHide()
  357. //------------------------------------------------------------------
  358. {
  359.     CFrameWnd * pFrameWnd = GetParentFrame();
  360.     pFrameWnd->ShowControlBar(this, FALSE, FALSE);
  361. }
  362.  
  363.  
  364. //------------------------------------------------------------------
  365. void CMRCSizeControlBar::OnToggleAllowDocking()
  366. //------------------------------------------------------------------
  367. {
  368.     CFrameWnd *pParentFrame = GetParentFrame();
  369.     if ((m_dwDockStyle & CBRS_ALIGN_ANY) != 0)
  370.     {                                               // docking currently allowed - disable it
  371.         m_dwAllowDockingState = m_dwDockStyle & CBRS_ALIGN_ANY;    // save previous state
  372.         if (!IsFloating())
  373.         {                    // if docked, then force it to be floating...
  374.             ASSERT(pParentFrame != NULL);
  375.             ASSERT(pParentFrame->IsKindOf(RUNTIME_CLASS(CMRCMDIFrameWndSizeDock)));
  376.             pParentFrame->FloatControlBar(this, m_FloatingPosition);
  377.         }
  378.         EnableDocking(0);                // disable docking
  379.     }
  380.     else
  381.     {
  382.         EnableDocking (m_dwAllowDockingState);    // re-enable docking...
  383.     }
  384. }
  385.  
  386. //------------------------------------------------------------------
  387. void CMRCSizeControlBar::OnFloatAsMDI()
  388. //------------------------------------------------------------------
  389. {
  390.     ASSERT(m_Style & SZBARF_ALLOW_MDI_FLOAT);        // must have specified this
  391.  
  392.     CMRCMDIFrameWndSizeDock * pFrame = (CMRCMDIFrameWndSizeDock *) AfxGetMainWnd();
  393.     ASSERT(pFrame != NULL);
  394.     ASSERT(pFrame->IsKindOf(RUNTIME_CLASS(CMRCMDIFrameWndSizeDock)));
  395.  
  396.     CFrameWnd *pParentFrame = GetParentFrame();
  397.     BOOL bMDIFloating = (IsFloating() && pParentFrame != NULL && pParentFrame->IsKindOf(RUNTIME_CLASS(CMRCMDIFloatWnd)));
  398.     
  399.     if (bMDIFloating)
  400.     {
  401.         pFrame->UnFloatInMDIChild(this, m_FloatingPosition);
  402.     }
  403.     else
  404.     {
  405.         pFrame->FloatControlBarInMDIChild(this, m_FloatingPosition);
  406.     }        
  407. }
  408.  
  409.  
  410. //----------------------------------------------------------------------------------
  411. void CMRCSizeControlBar::OnContextMenu(CWnd* pWnd, CPoint point) 
  412. // Now run off WM_CONTEXTMENU: if user wants standard handling, then let him have it
  413. //----------------------------------------------------------------------------------
  414. {
  415.     if (m_Style & SZBARF_STDMOUSECLICKS)
  416.     {
  417.         CMenu menu;
  418.         if (menu.CreatePopupMenu())
  419.         {
  420.             OnAddContextMenuItems(0, (LPARAM)menu.m_hMenu);
  421.             menu.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this);
  422.  
  423.         }
  424.     } 
  425.     else
  426.         CControlBar::OnContextMenu(pWnd, point);
  427. }
  428.