home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / winfe / edcombtb.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  21.3 KB  |  688 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. // edcombtb.cpp : implementation file
  20. //
  21. #include "stdafx.h"
  22. #ifdef EDITOR
  23. #include "edcombtb.h"
  24. //#include "edres1.h"
  25.  
  26. #ifdef _DEBUG
  27. #undef THIS_FILE
  28. static char BASED_CODE THIS_FILE[] = __FILE__;
  29. #endif
  30.  
  31. #define     HIDDEN_WIDTH        1   // Overlap between buttons, thus width of "removed" item
  32.  
  33. static int iComboRightBorder = 6;
  34.  
  35. /////////////////////////////////////////////////////////////////////////////
  36. // CComboToolBar
  37. CComboToolBar::CComboToolBar()
  38. {
  39.     m_pInfo = NULL;
  40.     m_nComboBoxCount = 0;
  41.     m_nButtonCount = 0;
  42.     m_nComboBoxCount = 0;
  43.     m_nControlCount = 0;
  44.     // This is in CToolBar
  45.     m_nCount = 0;
  46.     
  47.     // This is OK for default small toolbar, 
  48.     //  but we will try to get better estimate when toolbar is created
  49.     m_nComboTop = 3;  
  50.  
  51.     m_pEnableConfig = NULL;
  52.     m_sizeImage.cx = m_sizeImage.cy = 16;
  53.     m_nIDBitmap = 0;
  54.     m_pToolbar = NULL;
  55. #ifdef XP_WIN16
  56.     m_pToolTip = NULL;
  57. #endif
  58. }
  59.  
  60. CComboToolBar::~CComboToolBar()
  61. {
  62.     if ( m_pInfo ) {
  63.         // NOTE: TOOLBAR OWNER MUST DELETE COMBOBOXES!
  64.         delete m_pInfo;
  65.     }
  66.     if ( m_pEnableConfig ) {
  67.         delete m_pEnableConfig;
  68.     }
  69. #ifdef XP_WIN16
  70.     if( m_pToolTip ){
  71.         delete m_pToolTip;
  72.     }
  73. #endif
  74. }
  75.  
  76.  
  77. BEGIN_MESSAGE_MAP(CComboToolBar, CToolBar)
  78.     //{{AFX_MSG_MAP(CComboToolBar)
  79.     ON_WM_LBUTTONDOWN()
  80.     ON_WM_LBUTTONUP()
  81.     ON_WM_RBUTTONDOWN()
  82.     ON_WM_MOUSEMOVE()
  83.     ON_WM_CLOSE()
  84.     ON_WM_SHOWWINDOW()
  85.     ON_WM_DESTROY()
  86.     ON_WM_SIZE()
  87.     //}}AFX_MSG_MAP
  88. END_MESSAGE_MAP()
  89.  
  90.  
  91. /////////////////////////////////////////////////////////////////////////////
  92. BOOL CComboToolBar::Create( BOOL bIsPageComposer, CWnd* pParent, UINT nIDBar, UINT nIDCaption,
  93.                             UINT * pIDArray, int nIDCount,      // Command ID array and count
  94.                             UINT nIDBitmap, SIZE sizeButton, SIZE sizeImage )
  95. {
  96.     ASSERT( pParent );
  97.     ASSERT(nIDCount >= 1);  // must be at least one of them
  98.     ASSERT(pIDArray == NULL ||
  99.         AfxIsValidAddress(pIDArray, sizeof(UINT) * nIDCount, FALSE));
  100.  
  101. #ifdef XP_WIN16
  102.     DWORD dwStyle = WS_CHILD|WS_VISIBLE | CBRS_TOP;
  103.     m_pToolTip = new CNSToolTip();
  104.     if(m_pToolTip && !m_pToolTip->Create(this, TTS_ALWAYSTIP) ){
  105.        TRACE("Unable To create ToolTip\n");
  106.        delete m_pToolTip;
  107.        m_pToolTip = NULL;
  108.     } 
  109.     if( m_pToolTip ){
  110.         m_pToolTip->Activate(TRUE);
  111.         // Lets use speedy tooltips
  112.         m_pToolTip->SetDelayTime(200);
  113.     }
  114. #else
  115.     DWORD dwStyle = WS_CHILD|WS_VISIBLE|CBRS_TOOLTIPS|CBRS_TOP|CBRS_FLYBY;
  116. #endif
  117.  
  118.     // Toolbar is NOT initially visible
  119.     if (!CToolBar::Create(pParent,
  120.                           dwStyle,
  121.                           nIDBar ) )
  122.     {
  123.         TRACE0("Failed to create CToolBar for CComboToolBar\n");
  124.         return FALSE;   
  125.     }
  126.        
  127. #ifdef XP_WIN32      
  128.     if(bIsPageComposer){
  129.         dwStyle = GetBarStyle();
  130.         SetBarStyle(dwStyle & ~CBRS_BORDER_TOP);
  131.     }           
  132. #endif    
  133.  
  134.     if ( nIDBitmap && !LoadBitmap(nIDBitmap) )
  135.     {
  136.         TRACE0("Failed to load bitmap for CComboToolBar\n");
  137.         return FALSE;   
  138.     }
  139.  
  140.     // Allocate space for buttons in base class
  141.     if ( ! SetButtons( NULL, nIDCount ) ){
  142.         return FALSE;
  143.     }
  144.  
  145.     // Allocate memory for our info structues
  146.     m_pInfo = new TB_CONTROLINFO[nIDCount];
  147.     ASSERT( m_pInfo );
  148.     
  149.     // clear out!
  150.       memset( (void*)m_pInfo, 0, nIDCount * sizeof(TB_CONTROLINFO) );
  151.  
  152.     // Allocate memory for config array
  153.     m_pEnableConfig = new BOOL[nIDCount];
  154.     ASSERT( m_pEnableConfig );
  155.       memset( (void*)m_pEnableConfig, 0, nIDCount * sizeof(BOOL) );
  156.  
  157.     // Fill our info array and set each item's info in base class
  158.     UINT * pID = pIDArray;
  159.  
  160.     // Save it
  161.     m_sizeButton = sizeButton;
  162.  
  163.     // Set the size of the toolbar buttons and images
  164.     SetSizes(sizeButton, sizeImage );
  165.  
  166.     // Save stuff
  167.     m_sizeImage = sizeImage;
  168.     m_nIDBitmap = nIDBitmap;    
  169.     
  170.     // Extra margin to try to center any comboboxes (Buttons are at + 5)
  171.     // (Approximate -- probably depends on font etc...)
  172.     // m_nComboTop = 5 + ( (sizeButton.cy - 22 ) / 2);
  173.  
  174.     LPTB_CONTROLINFO pInfo = m_pInfo;    
  175.  
  176.     for ( int i=0; i < nIDCount; i++, pID++, pInfo++ ) {
  177.         pInfo->nID =  *pID;
  178.         if ( pInfo->nID == ID_SEPARATOR ) {
  179.             pInfo->nWidth = SEPARATOR_WIDTH;     // Default separator
  180.             SetButtonInfo( i, pInfo->nID, TBBS_SEPARATOR, pInfo->nWidth );
  181.         }
  182.         else if ( *pID == ID_COMBOBOX ) {
  183.             pInfo->bComboBox = TRUE;
  184.  
  185.             // Set base class info - probably not really needed
  186.             //   since we must fill in ComboBox data later!
  187.             // Last param = width, which we set later with SetComboBox()
  188.             // ***** SetButtonInfo( i, 0, TBBS_SEPARATOR, 0 ); // CAUSES CRASH??
  189.             m_nComboBoxCount++;
  190.             pInfo->pComboBox = NULL;  // Owner of toolbar must set this later!
  191.         }
  192.         else {
  193.             SetButtonInfo( i, pInfo->nID, TBBS_BUTTON, m_nButtonCount );
  194.             pInfo->nImageIndex = m_nButtonCount++;
  195.             pInfo->bIsButton = TRUE;
  196.             pInfo->nWidth = sizeImage.cx;
  197.         }
  198.         pInfo->bShow = TRUE;
  199.  
  200.         // Default is to show allow configuring all items        
  201.         m_pEnableConfig[i] = TRUE;
  202.     }
  203.  
  204.     m_nControlCount = m_nButtonCount + m_nComboBoxCount;
  205.     
  206.     // Upper limit imposed by resource ID allocation range
  207.     //  for configuring which controls show on toolbar
  208.     ASSERT( m_nControlCount<= MAX_TOOLBAR_CONTROLS );
  209.     
  210.     // ASSUME WE WANT DOCKING AND TOOLTIPS!
  211.  
  212. #ifdef WIN32
  213.     if ( m_nComboBoxCount )
  214.         // Ugly! Takes too much room to dock on sides if we have comboboxes
  215.         EnableDocking(CBRS_ALIGN_TOP | CBRS_ALIGN_BOTTOM);
  216.     else
  217.         EnableDocking(CBRS_ALIGN_ANY);
  218. #endif
  219.  
  220.     // Set caption that shows if toolbar is floating
  221.     if ( nIDCaption ) {
  222.         SetWindowText(szLoadString(nIDCaption));
  223.     }
  224.     return TRUE;
  225. }
  226.  
  227. // Get the rect of a button in screen coordinates
  228. // Used primarily with CDropdownToolbar
  229. BOOL CComboToolBar::GetButtonRect( UINT nID, RECT * pRect )
  230. {
  231.     if( pRect ){
  232.         LPTB_CONTROLINFO pInfo = m_pInfo;
  233.  
  234.         for ( int i = 0; i < m_nCount; i++, pInfo++ ) {
  235.             if ( pInfo->nID == nID ) {
  236.                 GetItemRect(i, pRect);
  237.                 ClientToScreen(pRect);
  238.                 return TRUE;
  239.             }
  240.         }
  241.     }
  242.     return FALSE;
  243. }
  244.  
  245. // After creating toobar, call this to enable action on button down
  246. // Used primarily when action is creation of a CDropdownToolbar
  247. void CComboToolBar::SetDoOnButtonDown( UINT nID, BOOL bSet )
  248. {
  249.     BOOL bFound = FALSE;
  250.     if( m_pToolbar && !m_pToolbar->SetDoOnButtonDownByCommand(nID, bSet) )
  251.     {
  252.         // Search for our buttons if no NSToolbar is used or command not found
  253.         LPTB_CONTROLINFO pInfo = m_pInfo;
  254.         ASSERT( pInfo );
  255.         for ( int i = 0; i < m_nCount; i++, pInfo++ ) {
  256.             if ( pInfo->bIsButton && pInfo->nID == nID ) {
  257.                  pInfo->bDoOnButtonDown = bSet;
  258.                  break;
  259.             }
  260.         }
  261.     }
  262. }
  263.  
  264. void CComboToolBar::SetComboBox( UINT nID, CComboBox * pComboBox, 
  265.                                  UINT nWidth, UINT nListWidth, UINT nListHeight )
  266. {
  267.     LPTB_CONTROLINFO pInfo = m_pInfo;
  268.     ASSERT( pInfo );
  269.     ASSERT( pComboBox );
  270.  
  271.     // Assign next available structure predesignated to be a combobox
  272.     if ( m_nComboBoxCount )
  273.     {
  274.         int i;
  275.         for ( i = 0; i < m_nCount; i++, pInfo++ ) {
  276.             // Find the top of any of the buttons to use for
  277.             //   top of combobox (+1 looks better)
  278.             if ( pInfo->bIsButton && !pInfo->bComboBox ) {
  279.                 RECT rect;
  280.                 GetItemRect(i, &rect);
  281.                 m_nComboTop = rect.top + 1;
  282.                 break;
  283.             }
  284.         }
  285.         i = 0;
  286.         pInfo = m_pInfo;
  287.         for ( ; i < m_nCount; i++, pInfo++ ) {
  288.             if ( pInfo->bComboBox && pInfo->pComboBox == 0 )
  289.             {
  290.                 // Calculate full height from number of items,
  291.                 if ( nListHeight == 0 ) {
  292.                     // Need extra amount: 10 pixels above and below edit box?
  293.                     int iEditHeight = pComboBox->GetItemHeight(-1) + 10;
  294.                     int iItemHeight = pComboBox->GetItemHeight(0);   
  295.                     //  but limit size to less than half the screen height
  296.                     //  else single click in combo will immediately select because
  297.                     //  list is drawn on top of closed combobbox
  298.                     nListHeight = min( sysInfo.m_iScreenHeight / 2,
  299.                                        iEditHeight + (pComboBox->GetCount() * iItemHeight) ); 
  300.                 }
  301.                 // Save the pointer for resizing box when controls are hidden
  302.                 pInfo->pComboBox = pComboBox;
  303.                 
  304.                 // Save command ID and width
  305.                 pInfo->nID = nID;
  306.  
  307.                 // Add extra space (built-in separator) after right edge,
  308.                 //   with a little extra for Win16/NT3.51 version (more crowded layout)
  309.                 // Save this as static so GetToolbarWidth can use it
  310.                 iComboRightBorder = (sysInfo.m_bWin4 ? 6 : 8);
  311.                 pInfo->nWidth = nWidth + iComboRightBorder;
  312.  
  313.                 CRect rect;
  314.                 GetItemRect( i, &rect );    // Get the left location from separator
  315.                 
  316.                 // Set size in base class (2 extra pixels at left edge)
  317.                 SetButtonInfo( i, nID, TBBS_SEPARATOR, pInfo->nWidth /*nWidth+2*/ );
  318.  
  319.                 // Change the location and size of combobox window
  320.                 // We always add 2 to left edge to avoid overlap with adjacent buttons
  321.                 pComboBox->SetWindowPos( NULL, rect.left/*+2*/, m_nComboTop,
  322.                                          nWidth, nListHeight,
  323.                                          SWP_NOZORDER | SWP_NOACTIVATE  );
  324. #ifdef _WIN32
  325.                 if( nListWidth && sysInfo.m_bWin4 ){
  326.                     // Set the minimum width of the drop-down list when open                    
  327.                     // TODO:  CAN'T FIGURE OUT HOW TO SET LIST WIDTH IN WIN16
  328.                     pComboBox->SetDroppedWidth(nListWidth);
  329.                 }
  330. #endif // XXX WIN16
  331.                 break; 
  332.             }
  333.         }
  334.     }
  335. }
  336.     
  337.  
  338. // Enable or Disable ALL controls in toolbar at once to same state
  339. void CComboToolBar::EnableAll( BOOL bEnable )
  340. {
  341.     LPTB_CONTROLINFO pInfo = m_pInfo;
  342.     ASSERT( m_pInfo );
  343.  
  344.     for ( int i = 0; i < m_nCount; i++, pInfo++ ) {
  345.         if ( pInfo->nID != ID_SEPARATOR ) {
  346.              _Enable( i, bEnable );
  347.         }
  348.     }
  349. }
  350.  
  351.  
  352. void CComboToolBar::Enable( UINT nID, BOOL bEnable )
  353. {
  354.     LPTB_CONTROLINFO pInfo = m_pInfo;
  355.  
  356.     for ( int i = 0; i < m_nCount; i++, pInfo++ ) {
  357.         if ( pInfo->nID == nID ) {
  358.              _Enable( i, bEnable );
  359.             break;
  360.         }
  361.     }
  362. }
  363.  
  364. void CComboToolBar::_Enable( int iIndex, BOOL bEnable )
  365. {
  366. #ifdef FEATURE_EDCOMBTB
  367. #include "edtcombtb.i00"
  368. #endif    
  369. }
  370.  
  371. void CComboToolBar::EnableConfigure( UINT nID, BOOL bEnable )
  372. {
  373.     ASSERT(m_pEnableConfig == NULL ||
  374.         AfxIsValidAddress(m_pEnableConfig, sizeof(int) * m_nCount, FALSE));
  375.  
  376.     LPTB_CONTROLINFO pInfo = m_pInfo;
  377.     for ( int i = 0; i < m_nCount; i++, pInfo++ ) {
  378.         if ( pInfo->nID == nID ) {
  379.             m_pEnableConfig[i] = bEnable;
  380.             break;
  381.         }
  382.     }
  383. }
  384.  
  385. // iCheck: 0 = no, 1 = checked, 2 = indeterminate 
  386. // Supply an array of check values 
  387. // ARRAY MUST CORRESPOND TO ALL CONTROLS, NOT JUST BUTTONS!
  388. void CComboToolBar::SetCheckAll( int * pCheckArray )
  389. {    
  390.     ASSERT(pCheckArray == NULL ||
  391.            AfxIsValidAddress(pCheckArray, sizeof(int) * m_nCount, FALSE));
  392.  
  393.     LPTB_CONTROLINFO pInfo = m_pInfo;
  394.     ASSERT( m_pInfo);
  395.  
  396.     for ( int i = 0; i < m_nCount; i++, pInfo++ ) {
  397.         if ( pInfo->bIsButton ) {
  398.             _SetCheck( i, pCheckArray[i] );
  399.         }
  400.     }
  401. }
  402.  
  403. void CComboToolBar::SetCheck( UINT nID, int iCheck )
  404. {
  405.     LPTB_CONTROLINFO pInfo = m_pInfo;
  406.     ASSERT( m_pInfo);
  407.  
  408.     for ( int i = 0; i < m_nCount; i++, pInfo++ ) {
  409.         if ( pInfo->bIsButton && pInfo->nID == nID ) {
  410.             _SetCheck( i, iCheck );
  411.             break;
  412.         }
  413.     }
  414. }
  415.  
  416. void CComboToolBar::_SetCheck( int iIndex, int iCheck )
  417. {
  418. #ifdef FEATURE_EDCOMBTB
  419. #include "edtcombtb.i01"
  420. #endif
  421.  
  422.     
  423. }
  424.  
  425.  
  426. void CComboToolBar::Show( UINT nID, BOOL bShow )
  427. {
  428.     LPTB_CONTROLINFO pInfo = m_pInfo;
  429.  
  430.     for ( int i = 0; i < m_nCount; i++, pInfo++ ) {
  431.         if ( pInfo->nID == nID && pInfo->bShow != bShow ) {
  432.             ShowByIndex( i, bShow );
  433.             break;
  434.         }
  435.     }
  436.     RecalcLayout();
  437. }
  438.  
  439. // Sets all values at once with an array of BOOLs: one for each control including separators
  440. void CComboToolBar::ShowAll( BOOL * pShowArray )
  441. {
  442.     LPTB_CONTROLINFO pInfo = m_pInfo;
  443.     ASSERT(pShowArray == NULL ||
  444.         AfxIsValidAddress(pShowArray, sizeof(BOOL) * m_nCount, FALSE));
  445.  
  446.     for ( int i = 0; i < m_nCount; i++, pInfo++ ) {
  447.         if ( pInfo->bShow != pShowArray[i] ) {
  448.             ShowByIndex( i, pShowArray[i] );
  449.         }
  450.     }
  451.     RecalcLayout();
  452. }
  453.  
  454. // Note: Always call RecalcLayout after using this
  455. //       adjust width of Separators and hidden items
  456. void CComboToolBar::ShowByIndex( int iIndex, BOOL bShow )
  457. {
  458.     ASSERT( iIndex >=0 && iIndex < m_nCount );
  459.     LPTB_CONTROLINFO pInfo = m_pInfo + iIndex;
  460.     ASSERT( pInfo );
  461.     pInfo->bShow = bShow;
  462.  
  463.     if ( bShow )
  464.     {
  465.         if (pInfo->nID == ID_SEPARATOR )
  466.             SetButtonInfo( iIndex, ID_SEPARATOR, TBBS_SEPARATOR, SEPARATOR_WIDTH);
  467.         else if ( pInfo->pComboBox )
  468.             SetButtonInfo( iIndex, ID_SEPARATOR, TBBS_SEPARATOR, pInfo->nWidth );
  469.         else    // Button
  470.             SetButtonInfo( iIndex, pInfo->nID, TBBS_BUTTON, pInfo->nImageIndex );
  471.     }
  472.     else {  // Hide an item by turning it into a separator
  473.         SetButtonInfo( iIndex, ID_SEPARATOR, TBBS_SEPARATOR, HIDDEN_WIDTH);
  474.     }
  475. }
  476.  
  477. // GetWindowRect() never reports the width of a toolbar,
  478. //   but gives CFrame's client width, so we need to 
  479. //   calculate it.  If bCNSToolbar is true then include the CNSToolbar's width
  480. int CComboToolBar::GetToolbarWidth(BOOL bCNSToolbar)
  481. {
  482.     RecalcLayout();
  483.     int nToolbarWidth = 0;
  484.  
  485.     // Include width of embedded custom toolbar if requested
  486.     if(bCNSToolbar && m_pToolbar)
  487.         nToolbarWidth = m_pToolbar->GetWidth();
  488.  
  489.     // Get last toolbar item (relative to toolbar window)
  490.     RECT rectLast;
  491.     LPTB_CONTROLINFO pInfo;
  492.     // Scan from end of items to find last non-separator
  493.     // Use its right edge as width of the "old" toolbar region
  494.     for ( int i = GetCount() - 1; i >= 0; i-- ) {
  495.         pInfo = m_pInfo+i;
  496.         if ( pInfo->nID != ID_SEPARATOR ) {
  497.             GetItemRect(i, &rectLast);
  498.             // Combobox has a built-in border - don't include it
  499.             if( pInfo->pComboBox ){
  500.                 return( rectLast.right -  iComboRightBorder + nToolbarWidth);
  501.             }
  502.             return( rectLast.right + nToolbarWidth );
  503.         }
  504.     }
  505.     return nToolbarWidth;
  506. }
  507.  
  508. void CComboToolBar::RecalcLayout( int iStart )
  509. {
  510.     // The separators and buttons get calculated by CToolBar,
  511.     //   but we must move the ComboBox windows
  512.     LPTB_CONTROLINFO pInfo = m_pInfo;
  513.     ASSERT(iStart < GetCount());
  514.     BOOL bPrevShownIsSeparator = FALSE;
  515.     UINT nWidth = 0;
  516.  
  517.     for ( int i = iStart; i < GetCount(); i++, pInfo++ ) {
  518.         if ( pInfo->nID == ID_SEPARATOR ) {
  519.             nWidth = bPrevShownIsSeparator ? 1 : SEPARATOR_WIDTH;                   
  520.             SetButtonInfo( i, ID_SEPARATOR, TBBS_SEPARATOR, nWidth );
  521.             bPrevShownIsSeparator = TRUE;
  522.         } else {    // Button or Combobox
  523.             if ( pInfo->bShow ) {
  524.                 bPrevShownIsSeparator = FALSE;
  525.                 nWidth = pInfo->nWidth;
  526.             }
  527.             else {   // We have a hidden button or combo
  528.                 // Very funky algorithm to cope with multiple hidden items in
  529.                 //   a row. Trying to deal with the 1-pixel overlap when items are drawn
  530.                 nWidth = (nWidth == 1 ) ? 2 : 1;
  531.                 
  532.                 SetButtonInfo( i, ID_SEPARATOR, TBBS_SEPARATOR, nWidth );
  533.             }                    
  534.  
  535.             if ( pInfo->pComboBox ) {
  536.                 CRect rect;
  537.                 // New Rect.left for combo is calculated by GetItemRect
  538.                 GetItemRect( i, &rect );
  539.                 UINT nFlags = SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE;
  540.  
  541.                 // Set flag to show or hide ComboBox window
  542.                 if ( pInfo->bShow )
  543.                     nFlags |= SWP_SHOWWINDOW;
  544.                 else
  545.                     nFlags |= SWP_HIDEWINDOW;
  546.  
  547.                 // Change the location, but not its size
  548.                 // We always add 2 to left edge to avoid overlap with adjacent buttons
  549.                 pInfo->pComboBox->SetWindowPos( NULL, rect.left/*+2*/, 
  550.                                                 m_nComboTop, 0, 0, nFlags );
  551.             }
  552. #ifdef XP_WIN16
  553.             if( m_pToolTip ){
  554.                 RECT rect;
  555.                 GetItemRect( i, &rect );
  556.                 // Remove any previously-assigned tip, then add new one
  557.                 //m_pToolTip->DelTool(this->m_hWnd, pInfo->nID);
  558.                 m_pToolTip->AddTool(this, pInfo->nID, &rect, pInfo->nID);
  559.                 m_pToolTip->Activate(TRUE);
  560.             }
  561. #endif
  562.         }
  563.     }
  564.  
  565.     Invalidate( TRUE ); // Redraw toolbar and erase background
  566.     GetParentFrame()->RecalcLayout(); // Tell parent frame to adjust for changes
  567. }
  568.  
  569. void CComboToolBar::SetCNSToolbar(CNSToolbar2 *pToolbar)
  570. {
  571.     m_pToolbar = pToolbar;
  572.     if(m_pToolbar)
  573.     {
  574.         m_pToolbar->SetParent(this);
  575.         m_pToolbar->SetOwner(this);
  576.     }
  577.  
  578. }
  579.  
  580. void CComboToolBar::OnUpdateCmdUI( CFrameWnd* pTarget, BOOL bDisableIfNoHndler )
  581. {
  582.     m_pToolbar->OnUpdateCmdUI(pTarget, bDisableIfNoHndler);
  583.  
  584.     CToolBar::OnUpdateCmdUI(pTarget, bDisableIfNoHndler);
  585. }
  586.  
  587. CSize CComboToolBar::CalcDynamicLayout(int nLength, DWORD dwMode )
  588. {     
  589.     CSize size(0,0);
  590.     
  591. #ifdef XP_WIN32
  592.     size = CToolBar::CalcDynamicLayout(nLength, dwMode);
  593. #endif
  594.     
  595.     int nHeight = m_pToolbar->GetHeight();
  596.  
  597.     if(size.cy < nHeight)
  598.     {
  599.         // 6 is what a CToolbar starts off as without any buttons
  600.         size.cy = nHeight + 8;
  601.     }
  602.  
  603.     return size;
  604.  
  605. }
  606.  
  607. /////////////////////////////////////////////////////////////////////////////
  608. // CComboToolBar message handlers
  609.  
  610. #ifdef XP_WIN16
  611. BOOL CComboToolBar::PreTranslateMessage(MSG* pMsg)
  612. {
  613.     if( m_pToolTip && pMsg->message >= WM_MOUSEFIRST && pMsg->message <= WM_MOUSELAST)
  614.     {
  615.         m_pToolTip->RelayEvent(pMsg);
  616.     }
  617.     return CToolBar::PreTranslateMessage(pMsg);
  618. }
  619. #endif
  620.  
  621. void CComboToolBar::OnLButtonDown(UINT nFlags, CPoint point)
  622. {
  623.     CToolBar::OnLButtonDown(nFlags, point);
  624.  
  625.     LPTB_CONTROLINFO pInfo = m_pInfo;
  626.  
  627.     for ( int i = 0; i < m_nCount; i++, pInfo++ ) {
  628.         // Test if we clicked inside a button
  629.         if ( pInfo->bIsButton ) {
  630.             CRect rect;
  631.             GetItemRect( i, &rect );
  632.             if ( rect.PtInRect(point) && pInfo->bDoOnButtonDown ) {
  633.                 // Trigger command by simulating button up
  634.                 PostMessage(WM_LBUTTONUP, (WPARAM)nFlags, MAKELONG(point.x, point.y) );
  635.                 return;
  636.             }
  637.         }
  638.     }
  639.  
  640.     // Send this message to the customizable toolbar for dragging
  641.     MapWindowPoints(GetParent(), &point, 1);
  642.     GetParent()->SendMessage(WM_LBUTTONDOWN, nFlags, MAKELPARAM(point.x, point.y));
  643.  
  644. }
  645.  
  646. void CComboToolBar::OnLButtonUp(UINT nFlags, CPoint point)
  647. {
  648.     CToolBar::OnLButtonUp(nFlags, point);
  649.  
  650.     // Send this message to the customizable toolbar for dragging
  651.     MapWindowPoints(GetParent(), &point, 1);
  652.     GetParent()->SendMessage(WM_LBUTTONUP, nFlags, MAKELPARAM(point.x, point.y));
  653.  
  654.  
  655. }
  656.  
  657. void CComboToolBar::OnMouseMove(UINT nFlags, CPoint point)
  658. {
  659.     CToolBar::OnMouseMove(nFlags, point);
  660.  
  661.     // Send this message to the customizable toolbar for dragging
  662.     MapWindowPoints(GetParent(), &point, 1);
  663.     GetParent()->SendMessage(WM_MOUSEMOVE, nFlags, MAKELPARAM(point.x, point.y));
  664.  
  665. }
  666.  
  667. void CComboToolBar::OnSize( UINT nType, int cx, int cy )
  668. {
  669.  
  670.     if(m_pToolbar)    {
  671.  
  672.         m_pToolbar->ShowWindow(SW_SHOW);
  673.         // Use the combox top and height to size ourselves
  674.         RECT rect;
  675.         GetItemRect(0,&rect);
  676.  
  677.         // Get width without the CNSToolbar (just combobox region)
  678.         int nPreviousWidth = GetToolbarWidth(FALSE);
  679.         int nHeight = m_pToolbar->GetHeight();
  680.         m_pToolbar->MoveWindow(nPreviousWidth, rect.top, cx - nPreviousWidth+4,
  681.                                (rect.bottom-rect.top)+2*rect.top);
  682.     }
  683.     CToolBar::OnSize(nType, cx, cy);
  684. }
  685.  
  686. #endif // EDITOR
  687.  
  688.