home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / winfe / tlbutton.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  53.4 KB  |  2,291 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. // Created August 19, 1996 by Scott Putterman
  20.  
  21. #include "stdafx.h"
  22. #include "tlbutton.h"
  23. #include "mainfrm.h"
  24. #include "ipframe.h"
  25.  
  26. #define TEXT_CHARACTERS_SHOWN 9
  27. #define BORDERSIZE 2
  28. #define TEXTVERTMARGIN 1
  29. #define TEXTONLYVERTMARGIN 2
  30. #define BITMAPVERTMARGIN 2
  31. #define TEXT_BITMAPVERTMARGIN 1
  32. #define HORIZMARGINSIZE 4
  33.  
  34. #define IDT_MENU        16383
  35. #define MENU_DELAY_MS    500
  36.  
  37. #define IDT_BUTTONFOCUS 16410
  38. #define BUTTONFOCUS_DELAY_MS 10
  39.  
  40. static CToolbarButton *pCurrentButton = NULL;
  41.  
  42. void WFE_ParseButtonString(UINT nID, CString &statusStr, CString &toolTipStr, CString &textStr)
  43. {
  44.  
  45.         CString str1;
  46.  
  47.         str1.LoadString(nID);
  48.  
  49.         int nNewLineIndex = str1.Find('\n');
  50.     
  51.         if(nNewLineIndex == -1)
  52.         {
  53.             statusStr = str1;
  54.             toolTipStr = statusStr;
  55.             textStr = statusStr;
  56.         }
  57.         else
  58.         {
  59.             statusStr = str1.Left(nNewLineIndex);
  60.             str1 = str1.Right( str1.GetLength() - (nNewLineIndex + 1));
  61.  
  62.             nNewLineIndex = str1.Find('\n');
  63.             if( nNewLineIndex == -1)
  64.             {
  65.                 toolTipStr = str1;
  66.                 textStr = toolTipStr;
  67.             }
  68.             else
  69.             {
  70.                 toolTipStr = str1.Left(nNewLineIndex);
  71.                 textStr = str1.Right(str1.GetLength() - (nNewLineIndex + 1));
  72.             }
  73.         }
  74.  
  75.  
  76.  
  77. }
  78.  
  79. CButtonEditWnd::~CButtonEditWnd()
  80. {
  81.  
  82. }
  83.  
  84.  
  85. void CButtonEditWnd::SetToolbarButtonOwner(CToolbarButton *pOwner)
  86. {
  87.     m_pOwner = pOwner;
  88. }
  89.  
  90. BOOL CButtonEditWnd::PreTranslateMessage ( MSG * msg )
  91. {
  92.    if ( msg->message == WM_KEYDOWN)
  93.    {
  94.       switch(msg->wParam)
  95.       {
  96.          case VK_RETURN:
  97.          {
  98.             m_pOwner->EditTextChanged(m_pOwner->GetTextEditText());
  99.             return TRUE; // Bail out, since m_pOwner has been deleted.
  100.  
  101.          }
  102.          case VK_ESCAPE:
  103.              m_pOwner->RemoveTextEdit();
  104.              break;
  105.       }
  106.    }
  107.    
  108.    return CEdit::PreTranslateMessage ( msg );
  109. }
  110.  
  111. //////////////////////////////////////////////////////////////////////////
  112. //                    Messages for CButtonEditWnd
  113. //////////////////////////////////////////////////////////////////////////
  114.  
  115. BEGIN_MESSAGE_MAP(CButtonEditWnd, CEdit)
  116.     //{{AFX_MSG_MAP(CWnd)
  117.      ON_WM_DESTROY()
  118.     ON_WM_KILLFOCUS()
  119.     //}}AFX_MSG_MAP
  120. END_MESSAGE_MAP()
  121.  
  122. void CButtonEditWnd::OnDestroy( )
  123. {
  124.     delete this;
  125.  
  126. }
  127.   
  128. void CButtonEditWnd::OnKillFocus( CWnd* pNewWnd )
  129. {
  130.      m_pOwner->RemoveTextEdit();
  131. }
  132.  
  133. ////////////////////////////////////////////////////
  134.  
  135. void CALLBACK EXPORT NSButtonMenuTimerProc(
  136.     HWND hwnd,    // handle of window for timer messages 
  137.     UINT uMsg,    // WM_TIMER message
  138.     UINT idEvent,    // timer identifier
  139.     ULONG dwTime     // current system time
  140.     );
  141.  
  142. void CToolbarButtonCmdUI::Enable(BOOL bOn)
  143. {
  144.  
  145.     if(bOn != ((CToolbarButton*)m_pOther)->IsEnabled())
  146.     {
  147.  
  148.         ((CToolbarButton*)m_pOther)->Enable(bOn);
  149.  
  150.         m_pOther->Invalidate();
  151.     }
  152.  
  153.     m_bEnableChanged = TRUE;
  154. }
  155.  
  156. void CToolbarButtonCmdUI::SetCheck( int nCheck)
  157. {
  158.  
  159.  
  160.     if( nCheck != ((CToolbarButton*)m_pOther)->GetCheck())
  161.     {
  162.         ((CToolbarButton*)m_pOther)->SetCheck(nCheck);
  163.         m_pOther->Invalidate();
  164.  
  165.     }
  166.  
  167.  
  168. }
  169.  
  170.  
  171. DROPEFFECT CToolbarButtonDropTarget::OnDragEnter(CWnd * pWnd,
  172.     COleDataObject * pDataObject, DWORD dwKeyState, CPoint point)
  173. {
  174.     DROPEFFECT deReturn;
  175.  
  176.     // Only interested in bookmarks
  177.     deReturn = ProcessDragEnter(pWnd, pDataObject, dwKeyState, point);
  178.     if(deReturn != DROPEFFECT_NONE)
  179.         pWnd->SendMessage(NSDRAGGINGONBUTTON, 0, 0);
  180.  
  181.     return(deReturn);
  182.  
  183.  
  184.  
  185. DROPEFFECT CToolbarButtonDropTarget::OnDragOver(CWnd * pWnd,
  186.     COleDataObject * pDataObject, DWORD dwKeyState, CPoint point)
  187. {
  188.     
  189.     return ProcessDragOver(pWnd, pDataObject, dwKeyState, point);
  190.  
  191.  
  192. BOOL CToolbarButtonDropTarget::OnDrop(CWnd * pWnd,
  193.     COleDataObject * pDataObject, DROPEFFECT dropEffect, CPoint point)
  194. {
  195.  
  196.     return ProcessDrop(pWnd, pDataObject, dropEffect, point);
  197.     
  198.  
  199. CToolbarButton::CToolbarButton()
  200. {
  201.     m_nIconType = BUILTIN_BITMAP;
  202.     m_pBitmapFile = NULL;
  203.     m_pButtonText = NULL;
  204.     m_pToolTipText = NULL;
  205.     m_pStatusText = NULL;
  206.     m_bMenuShowing =FALSE;
  207.     m_bButtonDown = FALSE;
  208.     m_bHaveFocus = FALSE;
  209.     m_bIsResourceID = TRUE;
  210.     m_hFocusTimer = 0;
  211.     m_pDropMenu = NULL;
  212.     m_pDropTarget = NULL;
  213.     m_bDraggingOnButton = FALSE;
  214.     m_hBmpImg = NULL;
  215.     m_nChecked = 0;
  216.     m_bPicturesOnly = FALSE;
  217.     m_bDoOnButtonDown = FALSE;
  218.     m_dwButtonStyle = 0;
  219.     m_bDepressed = FALSE;
  220.     hasCustomTextColor = FALSE;
  221.     hasCustomBGColor = FALSE;
  222. }
  223.  
  224.  
  225. CToolbarButton::~CToolbarButton()
  226. {
  227.     if(m_pButtonText != NULL)
  228.     {
  229.         XP_FREE(m_pButtonText);
  230.     }
  231.  
  232.     if(m_pToolTipText != NULL)
  233.     {
  234.         XP_FREE(m_pToolTipText);
  235.     }
  236.  
  237.     if(m_pStatusText != NULL)
  238.     {
  239.         XP_FREE(m_pStatusText);
  240.     }
  241.  
  242.     if(m_pBitmapFile != NULL)
  243.     {
  244.         XP_FREE(m_pBitmapFile);
  245.     }
  246.  
  247.     if(m_pDropMenu != NULL)
  248.     {
  249.         delete m_pDropMenu;
  250.     }
  251.  
  252.     if(m_pDropTarget != NULL)
  253.     {
  254.         delete m_pDropTarget;
  255.     }
  256.  
  257.     if(m_hBmpImg != NULL && !m_bBitmapFromParent)
  258.         DeleteObject(m_hBmpImg);
  259.  
  260.     if(pCurrentButton == this)
  261.         pCurrentButton = NULL;
  262. }
  263.  
  264. int CToolbarButton::Create(CWnd *pParent, int nToolbarStyle, CSize noviceButtonSize,
  265.                            CSize advancedButtonSize,  LPCTSTR pButtonText, LPCTSTR pToolTipText,
  266.                            LPCTSTR pStatusText, UINT nBitmapID, UINT nBitmapIndex, CSize bitmapSize, 
  267.                            BOOL bNeedsUpdate, UINT nCommand, int nMaxTextChars, int nMinTextChars,
  268.                            DWORD dwButtonStyle)
  269. {
  270.     
  271.  
  272.  
  273.     m_nBitmapID = nBitmapID;
  274.     m_nBitmapIndex = nBitmapIndex;
  275.     m_nToolbarStyle = nToolbarStyle;
  276.     m_noviceButtonSize = noviceButtonSize;
  277.     m_advancedButtonSize = advancedButtonSize;
  278.     m_bitmapSize = bitmapSize;
  279.     m_bEnabled = TRUE;
  280.     m_bNeedsUpdate = bNeedsUpdate;
  281.     m_nCommand = nCommand;
  282.     m_nMaxTextChars = nMaxTextChars;
  283.     m_nMinTextChars = nMinTextChars;
  284.     m_dwButtonStyle = dwButtonStyle;
  285.     m_pTextEdit = NULL;
  286.  
  287.     CSize size = GetButtonSize();
  288.  
  289.     CRect rect(100, 100, size.cx, size.cy);
  290.     CBrush brush;
  291.  
  292.     int bRtn = CWnd::Create( theApp.NSToolBarClass, NULL, 
  293.                     WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CS_PARENTDC,
  294.                     rect, pParent, nCommand, NULL);
  295.  
  296.     HINSTANCE hInst = AfxGetResourceHandle();
  297.  
  298.     CDC * pDC=GetDC();
  299.     if(m_bIsResourceID)
  300.     {
  301.         // if we haven't been given a bitmap yet, we don't want to load this
  302.         if(m_nBitmapID != 0)
  303.         {
  304.             WFE_InitializeUIPalette(pDC->m_hDC);
  305.             HPALETTE hPalette= WFE_GetUIPalette(GetParentFrame());
  306.             HPALETTE hOldPalette = SelectPalette(pDC->m_hDC, hPalette, FALSE);
  307.             m_hBmpImg = WFE_LoadTransparentBitmap(hInst, pDC->m_hDC, sysInfo.m_clrBtnFace, RGB(255, 0, 255), hPalette, m_nBitmapID);
  308.             SelectPalette(pDC->m_hDC, hOldPalette, TRUE);
  309.         }
  310.     }
  311.     else
  312.         m_hBmpImg = WFE_LoadBitmapFromFile(m_pBitmapFile);
  313.  
  314.     ReleaseDC(pDC);
  315.  
  316.     m_bBitmapFromParent = FALSE;
  317.  
  318.     SetText(pButtonText);
  319.  
  320.     if(pToolTipText != NULL)
  321.     {
  322.         m_pToolTipText = (LPTSTR)XP_ALLOC(XP_STRLEN(pToolTipText) + 1);
  323.         XP_STRCPY(m_pToolTipText, pToolTipText);
  324.     }
  325.  
  326.  
  327.     m_pStatusText = (LPTSTR) XP_ALLOC(XP_STRLEN(pStatusText) + 1);
  328.     XP_STRCPY(m_pStatusText, pStatusText);
  329.  
  330.     // Force initialization in SetStyle()
  331.     m_dwButtonStyle = DWORD(-1);
  332.     
  333.     //Code moved to function so style can be set separately
  334.     SetStyle(dwButtonStyle);
  335.  
  336.     m_eState = eNORMAL;
  337.  
  338.     return bRtn;
  339. }
  340.  
  341. void CToolbarButton::SetStyle(DWORD dwButtonStyle)
  342. {
  343.     // If no change from current style, then do nothing
  344.     if( m_dwButtonStyle == dwButtonStyle ){
  345.         return;
  346.     }
  347.     m_dwButtonStyle = dwButtonStyle;
  348.     CSize size = GetButtonSize();
  349.     
  350.     if(dwButtonStyle & TB_HAS_TIMED_MENU || dwButtonStyle & TB_HAS_IMMEDIATE_MENU)
  351.     {
  352.         // Create menu if not already done
  353.         // Menu contents are appended and removed every time its used,
  354.         //  so we don't need to delete items here
  355.         if(!(dwButtonStyle & TB_HAS_DRAGABLE_MENU 
  356.             && m_menu.m_hMenu != NULL
  357.             && !IsMenu(m_menu.m_hMenu)))
  358.             m_menu.CreatePopupMenu();
  359.     }
  360.     else if(dwButtonStyle & TB_HAS_DROPDOWN_TOOLBAR){
  361.         // Even though the styles are bit flags,
  362.         //    DROPDOWN_TOOLBAR style cannot be used with the MENU STYLES
  363.         SetDoOnButtonDown(TRUE);   
  364.     }
  365.  
  366.     // Create tooltip only if we have text and it wasn't created before
  367.     if(m_pToolTipText != NULL && !IsWindow(m_ToolTip.m_hWnd))
  368.     {
  369. #ifdef WIN32
  370.         m_ToolTip.Create(this, TTS_ALWAYSTIP);
  371. #else
  372.         m_ToolTip.Create(this);
  373. #endif
  374.  
  375.         if(dwButtonStyle & TB_DYNAMIC_TOOLTIP)
  376.         {
  377.             CRect tipRect(0, 0, size.cx, size.cy);
  378.             m_ToolTip.AddTool(this, LPSTR_TEXTCALLBACK, (m_nCommand == 0) ? NULL : &tipRect,
  379.                               m_nCommand);
  380.         }
  381.         else
  382.         {
  383.             m_ToolTip.AddTool(this, m_pToolTipText);
  384.         }
  385.  
  386.         m_ToolTip.Activate(TRUE);
  387.         m_ToolTip.SetDelayTime(250);
  388.     }
  389. }
  390.  
  391. int CToolbarButton::Create(CWnd *pParent, int nToolbarStyle, CSize noviceButtonSize, CSize advancedButtonSize,
  392.                LPCTSTR pButtonText, LPCTSTR pToolTipText, 
  393.                LPCTSTR pStatusText, LPCTSTR pBitmapFile,
  394.                CSize m_bitmapSize, BOOL bNeedsUpdate, UINT nCommand, int nMaxTextChars, int nMinTextChars,
  395.                DWORD dwButtonStyle)
  396. {
  397.  
  398.     m_bIsResourceID = FALSE;
  399.  
  400.     m_pBitmapFile = (LPTSTR) XP_ALLOC(XP_STRLEN(pBitmapFile) + 1);
  401.     XP_STRCPY(m_pBitmapFile, pBitmapFile);
  402.  
  403.     return Create(pParent, nToolbarStyle, noviceButtonSize, advancedButtonSize, pButtonText, pToolTipText,
  404.                   pStatusText, 0, 0, m_bitmapSize, bNeedsUpdate, nCommand, nMaxTextChars, nMinTextChars,
  405.                   dwButtonStyle);
  406.  
  407.  
  408. }
  409.  
  410. void CToolbarButton::SetText(LPCTSTR pButtonText)
  411. {
  412.     CSize oldSize = GetRequiredButtonSize();
  413.  
  414.     if(m_pButtonText != NULL)
  415.     {
  416.         XP_FREE(m_pButtonText);
  417.     }
  418.  
  419.     m_pButtonText = (LPTSTR)XP_ALLOC(XP_STRLEN(pButtonText) +1);
  420.     XP_STRCPY(m_pButtonText, pButtonText);
  421.  
  422.     CSize newSize = GetRequiredButtonSize();
  423.  
  424.     if((m_nToolbarStyle == TB_PICTURESANDTEXT || m_nToolbarStyle == TB_TEXT) && ::IsWindow(m_hWnd))
  425.     {
  426.         RedrawWindow();
  427.     }
  428.  
  429.     if(oldSize != newSize)
  430.         GetParent()->SendMessage(TB_SIZECHANGED, 0, (LPARAM)m_hWnd);
  431.  
  432. }
  433.  
  434. void CToolbarButton::SetButtonCommand(UINT nCommand)
  435. {
  436. #ifdef XP_WIN32
  437.     CToolInfo ToolInfo;
  438.     UINT nID =  (m_dwButtonStyle & TB_DYNAMIC_TOOLTIP) ? m_nCommand: 0;
  439.     
  440.     m_ToolTip.GetToolInfo(ToolInfo,this,nID);
  441.     ToolInfo.uId =   (m_dwButtonStyle & TB_DYNAMIC_TOOLTIP) ? nCommand: 0;
  442.     m_ToolTip.SetToolInfo(&ToolInfo);
  443.     m_nCommand = nCommand;
  444. #else
  445.     TOOLINFO ToolInfo;
  446.     UINT nID =  (m_dwButtonStyle & TB_DYNAMIC_TOOLTIP) ? m_nCommand: 0;
  447.     
  448.     m_ToolTip.GetToolInfo(&ToolInfo);
  449.     ToolInfo.uId =   (m_dwButtonStyle & TB_DYNAMIC_TOOLTIP) ? nCommand: 0;
  450.     m_ToolTip.SetToolInfo(&ToolInfo);
  451.     m_nCommand = nCommand;
  452. #endif
  453. }
  454.  
  455. void CToolbarButton::SetToolTipText(LPCSTR pToolTipText)
  456.  
  457. {
  458.     if (pToolTipText == NULL) 
  459.         return;
  460.  
  461.     if(m_pToolTipText != NULL)
  462.     {
  463.         XP_FREE(m_pToolTipText);
  464.     }
  465.     m_pToolTipText = (LPTSTR)XP_ALLOC(XP_STRLEN(pToolTipText) +1);
  466.     XP_STRCPY(m_pToolTipText, pToolTipText);
  467.     UINT nID = (m_dwButtonStyle & TB_DYNAMIC_TOOLTIP) ? m_nCommand: 0;
  468.     m_ToolTip.UpdateTipText(m_pToolTipText, this, nID);
  469. }
  470.  
  471. void CToolbarButton::SetStatusText(LPCSTR pStatusText)
  472. {
  473.     if (pStatusText == NULL)
  474.         return;
  475.  
  476.     if(m_pStatusText != NULL)
  477.     {
  478.         XP_FREE(m_pStatusText);
  479.     }
  480.     m_pStatusText = (LPTSTR)XP_ALLOC(XP_STRLEN(pStatusText) +1);
  481.     XP_STRCPY(m_pStatusText, pStatusText);
  482. }
  483.  
  484. void CToolbarButton::SetBitmap(HBITMAP hBmpImg, BOOL bParentOwns)
  485. {
  486.     if(m_hBmpImg != NULL && !m_bBitmapFromParent)
  487.         ::DeleteObject(m_hBmpImg);
  488.  
  489.     m_hBmpImg = hBmpImg;
  490.     m_bBitmapFromParent = bParentOwns;
  491. }
  492.  
  493. void CToolbarButton::ReplaceBitmap(UINT nBitmapID, UINT nBitmapIndex)
  494. {
  495.     m_nBitmapID = nBitmapID;
  496.     m_nBitmapIndex = nBitmapIndex;
  497.  
  498.     m_bIsResourceID = TRUE;
  499.     RedrawWindow();
  500. }
  501.  
  502. void CToolbarButton::ReplaceBitmap(LPCTSTR pBitmapFile)
  503. {
  504.  
  505.     if(m_pBitmapFile != NULL)
  506.     {
  507.         XP_FREE(m_pBitmapFile);
  508.     }
  509.  
  510.     m_pBitmapFile = (LPTSTR)XP_ALLOC(XP_STRLEN(pBitmapFile) +1);
  511.     XP_STRCPY(m_pBitmapFile, pBitmapFile);
  512.  
  513.     m_bIsResourceID = FALSE;
  514.     RedrawWindow();
  515. }
  516.  
  517. void CToolbarButton::ReplaceBitmap(HBITMAP hBmpImg, UINT nBitmapIndex, BOOL bParentOwns)
  518. {
  519.     SetBitmap(hBmpImg, bParentOwns);
  520.     ReplaceBitmap(0, nBitmapIndex);
  521. }
  522.  
  523. void CToolbarButton::ReplaceBitmapIndex(UINT nBitmapIndex)
  524. {
  525.     if(m_nBitmapIndex != nBitmapIndex)
  526.     {
  527.         m_nBitmapIndex = nBitmapIndex;
  528.         RedrawWindow();
  529.     }
  530. }
  531.  
  532. CSize CToolbarButton::GetButtonSize(void)
  533. {
  534.     return(m_nToolbarStyle == TB_PICTURESANDTEXT ? m_noviceButtonSize : m_advancedButtonSize);
  535. }
  536.  
  537. CSize CToolbarButton::GetRequiredButtonSize(void)
  538. {
  539.     return GetButtonSizeFromChars(m_pButtonText, m_nMaxTextChars);
  540. }
  541.  
  542. CSize CToolbarButton::GetButtonSizeFromChars(CString s, int c)
  543. {
  544.     CSize size;
  545.  
  546.     if(m_nToolbarStyle == TB_PICTURESANDTEXT)
  547.     {
  548.         size = GetBitmapOnTopSize(s, c);
  549.     }
  550.     else if (m_nToolbarStyle == TB_PICTURES)
  551.     {
  552.         size = GetBitmapOnlySize();
  553.     }
  554.     else if(m_nToolbarStyle == TB_TEXT)
  555.     {
  556.         size = GetTextOnlySize(s, c);
  557.     }
  558.  
  559.     return size;
  560. }
  561.  
  562. CSize CToolbarButton::GetMinimalButtonSize(void)
  563. {
  564.     return GetButtonSizeFromChars(m_pButtonText, m_nMinTextChars);
  565. }
  566.  
  567. CSize CToolbarButton::GetMaximalButtonSize(void)
  568. {
  569.     return GetButtonSizeFromChars(m_pButtonText, m_nMaxTextChars);
  570. }
  571.  
  572. void CToolbarButton::CheckForMinimalSize(void)
  573. {
  574.     // A button is at its minimal size if its
  575.     // current horizontal extent is <= its minimal horizontal extent.
  576.     atMinimalSize = (GetButtonSize().cx <= GetMinimalButtonSize().cx);
  577. }
  578.  
  579. void CToolbarButton::CheckForMaximalSize(void)
  580. {
  581.     // A button is at its maximal size if its
  582.     // current horizontal extent is >= its maximal horizontal extent.
  583.     atMaximalSize = (GetButtonSize().cx >= GetMaximalButtonSize().cx);
  584. }
  585.  
  586. BOOL CToolbarButton::AtMinimalSize(void)
  587. {
  588.     CheckForMinimalSize();
  589.     return atMinimalSize;
  590. }
  591.  
  592. BOOL CToolbarButton::AtMaximalSize(void)
  593. {
  594.     CheckForMaximalSize();
  595.     return atMaximalSize;
  596. }
  597.  
  598. void CToolbarButton::SetBitmapSize(CSize sizeImage)
  599. {
  600.     m_bitmapSize = sizeImage;
  601.     RedrawWindow();
  602. }
  603.  
  604. void CToolbarButton::SetButtonSize(CSize buttonSize)
  605. {
  606.     if(m_nToolbarStyle == TB_PICTURESANDTEXT)
  607.     {
  608.         m_noviceButtonSize  = buttonSize;
  609.     }
  610.     else
  611.     {
  612.         m_advancedButtonSize = buttonSize;
  613.     }
  614. }
  615.  
  616. void CToolbarButton::SetDropTarget(CToolbarButtonDropTarget *pDropTarget)
  617. {
  618.  
  619.     m_pDropTarget = pDropTarget;
  620.  
  621.     m_pDropTarget->Register(this);
  622.     m_pDropTarget->SetButton(this);
  623. }
  624.  
  625. void CToolbarButton::SetCheck(int nCheck)
  626. {
  627.     m_nChecked = nCheck;
  628.     switch(nCheck)
  629.     {
  630.         case 0: m_eState = eNORMAL;
  631.                 break;
  632.         case 1: m_eState = eBUTTON_CHECKED; //eBUTTON_DOWN;
  633.                 break;
  634.         case 2: m_eState = eDISABLED;
  635.                 break;
  636.     }
  637.  
  638. }
  639.  
  640. int CToolbarButton::GetCheck(void)
  641. {
  642.     return m_nChecked;
  643. }
  644.  
  645. void CToolbarButton::SetPicturesOnly(int bPicturesOnly)
  646. {
  647.     m_bPicturesOnly = bPicturesOnly;
  648.     SetButtonMode(TB_PICTURES);
  649. }
  650.  
  651. void CToolbarButton::SetButtonMode(int nToolbarStyle)
  652. {
  653.     if(m_bPicturesOnly)
  654.         m_nToolbarStyle = TB_PICTURES;
  655.     else
  656.         m_nToolbarStyle = nToolbarStyle;
  657. }
  658.  
  659. void CToolbarButton::FillInButtonData(LPBUTTONITEM pButton)
  660. {
  661.     pButton->button = m_hWnd;
  662.     
  663. }
  664.  
  665. void CToolbarButton::ButtonDragged(void)
  666. {
  667.     KillTimer(m_hMenuTimer);
  668.     m_eState = eNORMAL;
  669.     RedrawWindow();
  670. }
  671.  
  672. void CToolbarButton::AddTextEdit(void)
  673. {
  674.     if(!m_pTextEdit)
  675.     {
  676.         m_pTextEdit = new CButtonEditWnd;
  677.  
  678.         if(m_pTextEdit)
  679.         {
  680.             CRect rect;
  681.             HDC hDC = ::GetDC(m_hWnd);
  682.             HFONT hFont = WFE_GetUIFont(hDC);
  683.             HFONT hOldFont = (HFONT)::SelectObject(hDC, hFont);
  684.             TEXTMETRIC tm;
  685.  
  686.             GetTextMetrics(hDC, &tm);
  687.             int height = tm.tmHeight;
  688.  
  689.             ::SelectObject(hDC, hOldFont);
  690.             ::ReleaseDC(m_hWnd, hDC);
  691.  
  692.             GetTextRect(rect);
  693.             if(rect.Height() > height)
  694.             {
  695.                 rect.top += (rect.Height() - height) / 2;
  696.                 rect.bottom -= (rect.Height() - height) / 2;
  697.             }
  698.  
  699.             BOOL bRtn = m_pTextEdit->Create(ES_AUTOHSCROLL, rect, this, 0);
  700.  
  701.             if(!bRtn)
  702.             {
  703.                 delete m_pTextEdit;
  704.                 m_pTextEdit = NULL;
  705.             }
  706.             else
  707.             {
  708.                 m_pTextEdit->ShowWindow(SW_SHOW);
  709.                 HDC hDC = ::GetDC(m_hWnd);
  710.  
  711.                 HFONT hFont = WFE_GetUIFont(hDC);
  712.                 CFont *font = (CFont*) CFont::FromHandle(hFont);
  713.                 m_pTextEdit->SetFont(font);
  714.                 ::ReleaseDC(m_hWnd, hDC);
  715.                 m_pTextEdit->SetFocus();
  716.                 m_pTextEdit->SetToolbarButtonOwner(this);
  717.             }
  718.  
  719.         }
  720.  
  721.     }
  722. }
  723.  
  724. void CToolbarButton::RemoveTextEdit(void)
  725. {
  726.     if(m_pTextEdit)
  727.     {
  728.         m_pTextEdit->PostMessage(WM_DESTROY, 0, 0);
  729.         m_pTextEdit = NULL;
  730.  
  731.     }
  732.  
  733. }
  734.  
  735. void CToolbarButton::SetTextEditText(char *pText)
  736. {
  737.     if(m_pTextEdit)
  738.     {
  739.         m_pTextEdit->ReplaceSel(pText);
  740.         m_pTextEdit->SetSel(0, strlen(pText), TRUE);
  741.     }
  742.  
  743. }
  744.  
  745. // the string returned must be deleted
  746. char * CToolbarButton::GetTextEditText(void)
  747. {
  748.     char str[1000];
  749.  
  750.     if(m_pTextEdit)
  751.     {
  752.         int size = m_pTextEdit->GetWindowText(str, 1000);
  753.         if(size > 0)
  754.         {
  755.             char *newStr = new char[size + 1];
  756.             strcpy(newStr, str);
  757.             return newStr;
  758.         }
  759.     }
  760.  
  761.     return NULL;
  762.  
  763. }
  764.  
  765. void CToolbarButton::EditTextChanged(char *pText)
  766. {
  767.     SetText(pText);
  768. }
  769.  
  770.  
  771. //////////////////////////////////////////////////////////////////////////
  772. //                    Messages for CToolbarButton
  773. //////////////////////////////////////////////////////////////////////////
  774.  
  775. BEGIN_MESSAGE_MAP(CToolbarButton, CWnd)
  776.     //{{AFX_MSG_MAP(CWnd)
  777.      ON_WM_PAINT()
  778.     ON_WM_LBUTTONDOWN()
  779.     ON_WM_LBUTTONUP()
  780.     ON_WM_RBUTTONDOWN()
  781.     ON_WM_MOUSEMOVE()
  782.     ON_WM_SHOWWINDOW()
  783.     ON_WM_ERASEBKGND()
  784. #ifdef _WIN32
  785.     ON_WM_CAPTURECHANGED()
  786. #endif
  787.     ON_WM_GETDLGCODE()
  788.     ON_WM_KEYDOWN()
  789.     ON_MESSAGE(TTN_NEEDTEXT, OnToolTipNeedText) 
  790.     ON_WM_TIMER()
  791.     ON_MESSAGE(NSDRAGMENUOPEN, OnDragMenuOpen)
  792.     ON_MESSAGE(NSDRAGGINGONBUTTON, OnDraggingOnButton)
  793.     ON_WM_PALETTECHANGED()
  794.     ON_WM_SYSCOLORCHANGE()
  795.     ON_WM_CTLCOLOR()
  796.     //}}AFX_MSG_MAP
  797.  
  798. END_MESSAGE_MAP()
  799.  
  800. void CToolbarButton::OnLButtonDown(UINT nFlags, CPoint point)
  801. {
  802.     if(m_bEnabled)
  803.     {
  804.         // Show the button down look
  805.         m_eState = eBUTTON_DOWN;
  806.         m_bDraggingOnButton = FALSE;
  807.         if(m_dwButtonStyle & TB_HAS_TIMED_MENU)
  808.         {
  809.             m_hMenuTimer = SetTimer(IDT_MENU, MENU_DELAY_MS, NULL);
  810.         }
  811.         else if(m_dwButtonStyle & TB_HAS_IMMEDIATE_MENU)
  812.         {
  813.             m_hMenuTimer = SetTimer(IDT_MENU, 0, NULL);
  814.         }
  815.  
  816.         RedrawWindow();
  817.     }
  818.     if(m_pToolTipText != NULL)
  819.     {
  820.         MSG msg = *(GetCurrentMessage());
  821.         m_ToolTip.RelayEvent(&msg);
  822.     }
  823.  
  824.     // Do action immediately if this is set
  825.     if( m_bDoOnButtonDown )
  826.         OnAction();
  827.     else 
  828.         m_bButtonDown = TRUE;
  829. }
  830.  
  831. void CToolbarButton::OnMouseMove(UINT nFlags, CPoint point)
  832. {
  833.     // Make sure we're activated (button look)
  834.     if (!m_bHaveFocus)
  835.     {
  836.             if(GetTopLevelFrame() == GetActiveWindow() || GetTopLevelFrame() == AfxGetMainWnd())
  837.             {
  838.                 m_bHaveFocus = TRUE;
  839.                 if(m_hFocusTimer == 0)
  840.                 {
  841.                     if(pCurrentButton)
  842.                         pCurrentButton->RemoveButtonFocus();
  843.                     pCurrentButton = this;
  844.                     m_hFocusTimer = SetTimer(IDT_BUTTONFOCUS, BUTTONFOCUS_DELAY_MS, NULL);
  845.  
  846.                     BOOL bStatusText = (strcmp(m_pStatusText, "") != 0);
  847.                     char status[1000];
  848.  
  849.                     if(m_dwButtonStyle & TB_DYNAMIC_STATUS){
  850.                         WFE_GetOwnerFrame(this)->SendMessage(TB_FILLINSTATUS, (WPARAM)m_nCommand, (LPARAM) status);
  851.                         WFE_GetOwnerFrame(this)->SendMessage( WM_SETMESSAGESTRING,
  852.                                                            (WPARAM) 0, (LPARAM) status );
  853.                     }
  854.                     else if ( bStatusText) {
  855.                         WFE_GetOwnerFrame(this)->SendMessage( WM_SETMESSAGESTRING,
  856.                                                            (WPARAM)0, (LPARAM) m_pStatusText );
  857.                     }
  858.  
  859.                 }
  860.  
  861.                 if(m_pToolTipText != NULL)
  862.                 {
  863.                     m_ToolTip.Activate(TRUE);
  864.                     MSG msg = *(GetCurrentMessage());
  865.                     m_ToolTip.RelayEvent(&msg);
  866.                 }
  867.  
  868.                 if(m_bEnabled)
  869.                 {
  870.                     m_eState = (nFlags & MK_LBUTTON) ? eBUTTON_DOWN : eBUTTON_UP;
  871.                     RedrawWindow();
  872.                     UpdateWindow();
  873.                 }
  874.             }
  875.     }
  876.  
  877.     if(GetTopLevelFrame() == GetActiveWindow() || GetTopLevelFrame() == AfxGetMainWnd())
  878.     {
  879.         if(m_pToolTipText!= NULL)
  880.         {
  881.             MSG msg = *(GetCurrentMessage());
  882.             m_ToolTip.RelayEvent(&msg);
  883.         }
  884.     }
  885.  
  886.  
  887.  
  888. }
  889.  
  890. void CToolbarButton::OnLButtonUp(UINT nFlags, CPoint point)
  891. {
  892.     if(m_bEnabled)
  893.     {
  894.         if (m_bHaveFocus)
  895.         {
  896.             // Do action only if not done on button down
  897.             if(!m_bDoOnButtonDown)
  898.             {
  899.                 // Cursor is still over the button, so back to button up look
  900.                 m_eState = eBUTTON_UP;
  901.                 if(m_bButtonDown)
  902.                     OnAction();
  903.             }
  904.         }
  905.         else
  906.         {
  907.             // Restore borderless look
  908.             if(m_nChecked == 0)
  909.                 m_eState = eNORMAL;
  910.         }
  911.         
  912.         RedrawWindow();
  913.     }
  914.     if(m_dwButtonStyle & TB_HAS_TIMED_MENU)
  915.     {
  916.         KillTimer(m_hMenuTimer);
  917.     }
  918.     if(m_pToolTipText != NULL)
  919.     {
  920.         MSG msg = *(GetCurrentMessage());
  921.         m_ToolTip.RelayEvent(&msg);
  922.     }
  923.     m_bButtonDown = FALSE;
  924.  
  925. }
  926.  
  927. void CToolbarButton::OnRButtonDown(UINT nFlags, CPoint point)
  928. {
  929.     if (CreateRightMouseMenu())
  930.     {
  931.         DisplayAndTrackMenu();
  932.     }
  933.  
  934.     if(m_pToolTipText != NULL)
  935.     {
  936.         MSG msg = *(GetCurrentMessage());
  937.         m_ToolTip.RelayEvent(&msg);
  938.     }
  939.  
  940.  
  941. }
  942.  
  943. void CToolbarButton::OnKeyDown( UINT nChar, UINT nRepCnt, UINT nFlags )
  944. {
  945.     int i = 0;
  946.     i++;
  947.  
  948. }
  949.   
  950.  
  951. BOOL CToolbarButton::OnCommand(UINT wParam,LONG lParam)
  952. {
  953.     return((BOOL)GetParentFrame()->SendMessage(WM_COMMAND, wParam, lParam));
  954. }
  955.  
  956.  
  957. BOOL CToolbarButton::OnNotify( WPARAM wParam, LPARAM lParam, LRESULT* pResult )
  958. {
  959.     NMHDR *hdr = (NMHDR*)lParam;
  960.     if(hdr->code == TTN_NEEDTEXT)
  961.     {
  962.         int command = (int) wParam;
  963.         LPTOOLTIPTEXT lpttt = (LPTOOLTIPTEXT) lParam; 
  964.  
  965.         GetParentFrame()->SendMessage(TB_FILLINTOOLTIP, WPARAM(m_hWnd), lParam);
  966.         return TRUE;
  967.     }
  968. #ifdef _WIN32
  969.     else
  970.         return (CWnd::OnNotify(wParam, lParam, pResult));
  971. #else
  972.     return FALSE;
  973. #endif
  974. }
  975.  
  976. void CToolbarButton::OnPaint()
  977. {
  978.     CRect updateRect;
  979.  
  980.     GetUpdateRect(&updateRect);
  981.  
  982.     CPaintDC dcPaint(this);    // device context for painting
  983.     CRect rcClient;
  984.     GetClientRect(&rcClient);
  985.     
  986.     HDC hSrcDC = dcPaint.m_hDC;
  987.  
  988.     HPALETTE hPalette;
  989.     HPALETTE hOldPalette;
  990.     CFrameWnd* pParent = WFE_GetOwnerFrame(this); 
  991.     hPalette = WFE_GetUIPalette(pParent);
  992.     hOldPalette= ::SelectPalette(hSrcDC, hPalette, FALSE);
  993.     
  994.     CFrameGlue *pGlue = CFrameGlue::GetFrameGlue(pParent);
  995.     if (pParent && pGlue && (pParent->IsKindOf(RUNTIME_CLASS(CGenericFrame)) ||
  996.         pParent->IsKindOf(RUNTIME_CLASS(CInPlaceFrame)))) {
  997.         CFrameGlue *pGlue = CFrameGlue::GetFrameGlue(pParent);
  998.         if (pGlue && !pGlue->IsBackGroundPalette()) {
  999.             hOldPalette= ::SelectPalette(hSrcDC, hPalette, TRUE);
  1000.             ::RealizePalette(hSrcDC);
  1001.         }
  1002.         else {
  1003.             hOldPalette= ::SelectPalette(hSrcDC, hPalette, FALSE);
  1004.         }
  1005.     }
  1006.     else {
  1007.         hOldPalette= ::SelectPalette(hSrcDC, hPalette, TRUE);
  1008.         ::RealizePalette(hSrcDC);
  1009.     }
  1010.     HDC hMemDC = ::CreateCompatibleDC(hSrcDC);
  1011.     if(hMemDC)
  1012.     {
  1013.         HPALETTE hOldMemPalette = ::SelectPalette(hMemDC, hPalette, FALSE);
  1014.  
  1015.         HBITMAP hbmMem = CreateCompatibleBitmap(hSrcDC,
  1016.                                         rcClient.Width(),
  1017.                                         rcClient.Height());
  1018.  
  1019.         //
  1020.         // Select the bitmap into the off-screen DC.
  1021.         //
  1022.  
  1023.         HBITMAP hbmOld = (HBITMAP)::SelectObject(hMemDC, hbmMem);
  1024.  
  1025.         COLORREF rgbOldBk;
  1026.         
  1027.         // Use the button face color as our background
  1028.         HBRUSH brFace = sysInfo.m_hbrBtnFace;
  1029.         
  1030.         if (m_bDepressed)
  1031.         {
  1032.             // Use the button shadow color as our background instead.
  1033.             brFace = ::CreateSolidBrush(sysInfo.m_clrBtnShadow);
  1034.             ::SetBkColor(hMemDC, sysInfo.m_clrBtnShadow);
  1035.         }
  1036.         else if (hasCustomBGColor)
  1037.         {
  1038.             // Use the button's custom background
  1039.             brFace = ::CreateSolidBrush(customBGColor);
  1040.         }
  1041.         else ::SetBkColor(hMemDC, sysInfo.m_clrBtnFace); // Use button face color.
  1042.  
  1043.         ::FillRect(hMemDC, rcClient, brFace);
  1044.         
  1045.         if (m_bDepressed)
  1046.         {
  1047.             ::DeleteObject(brFace);
  1048.         }
  1049.  
  1050.         // if we are not enabled then must make sure that button state is normal
  1051.         if(!m_bEnabled)
  1052.         {
  1053.             m_eState = eNORMAL;
  1054.         }
  1055.  
  1056.         CRect innerRect = rcClient;
  1057.  
  1058.         innerRect.InflateRect(-BORDERSIZE, -BORDERSIZE);
  1059.  
  1060.         if(m_nToolbarStyle == TB_PICTURESANDTEXT)
  1061.         {
  1062.             DrawPicturesAndTextMode(hMemDC, innerRect);
  1063.         }
  1064.         else if(m_nToolbarStyle == TB_PICTURES)
  1065.         {
  1066.             DrawPicturesMode(hMemDC, innerRect);
  1067.         }
  1068.         else
  1069.         {
  1070.             DrawTextMode(hMemDC, innerRect);
  1071.         }
  1072.  
  1073.         // Now, draw 3d visual button effects, depending on our state
  1074.         switch (m_eState)
  1075.         {
  1076.             case eBUTTON_UP:
  1077.             {
  1078.                 if( m_nChecked == 0 )
  1079.                     DrawUpButton(hMemDC, rcClient);
  1080.                 else
  1081.                     DrawDownButton(hMemDC, rcClient);
  1082.             }
  1083.             break;
  1084.             
  1085.             case eBUTTON_CHECKED:
  1086.             {
  1087.                 // A checked button but NOT mousing over - no black border
  1088.                 DrawCheckedButton(hMemDC, rcClient);
  1089.             }
  1090.             break;
  1091.  
  1092.             case eBUTTON_DOWN:
  1093.             {
  1094.                 DrawDownButton(hMemDC, rcClient);
  1095.             }
  1096.             break;
  1097.  
  1098.             case eDISABLED:
  1099.             {
  1100.                 if(m_nChecked == 2)
  1101.                     DrawCheckedButton(hMemDC, rcClient);
  1102.  
  1103.             }
  1104.             break;
  1105.  
  1106.             case eNORMAL:
  1107.             {
  1108.                 if (m_bDepressed)
  1109.                     DrawDownButton(hMemDC, rcClient); // Looks like it's locked down.
  1110.             }
  1111.         }
  1112.  
  1113.         ::SetBkColor(hMemDC, rgbOldBk);
  1114.  
  1115.         ::BitBlt(hSrcDC, 0, 0, rcClient.Width(), rcClient.Height(), hMemDC, 0, 0,
  1116.                         SRCCOPY);
  1117.  
  1118.         ::SelectPalette(hMemDC, hOldMemPalette, FALSE);
  1119.         ::SelectPalette(hSrcDC, hOldPalette, FALSE);
  1120.  
  1121.         ::SelectObject(hMemDC, hbmOld);
  1122.         ::DeleteObject(hbmMem);
  1123.  
  1124.         ::DeleteDC(hMemDC);
  1125.     }
  1126. }
  1127.  
  1128. void CToolbarButton::OnShowWindow( BOOL bShow, UINT nStatus )
  1129. {
  1130.     m_bEraseBackground = bShow;
  1131. }
  1132.  
  1133. BOOL CToolbarButton::OnEraseBkgnd( CDC* pDC )
  1134. {
  1135.     if ( m_bEraseBackground ) {
  1136.         m_bEraseBackground = FALSE;
  1137.         return (BOOL) Default();
  1138.     } else {
  1139.         return TRUE;
  1140.     }
  1141. }
  1142.  
  1143. void CToolbarButton::OnCaptureChanged( CWnd* pWnd )
  1144. {
  1145. }
  1146.  
  1147. UINT CToolbarButton::OnGetDlgCode(void )
  1148. {
  1149.     return DLGC_WANTALLKEYS;
  1150.  
  1151. }
  1152.  
  1153. LRESULT CToolbarButton::OnToolTipNeedText(WPARAM wParam, LPARAM lParam)
  1154. {
  1155.     LPTOOLTIPTEXT lpttt = (LPTOOLTIPTEXT) lParam;
  1156.     GetParentFrame()->SendMessage(TB_FILLINTOOLTIP, WPARAM(m_hWnd), lParam);
  1157.  
  1158.     return 1;
  1159. }
  1160.  
  1161. void CToolbarButton::OnTimer( UINT  nIDEvent )
  1162. {
  1163.     if(nIDEvent == IDT_MENU)
  1164.     {
  1165.         KillTimer( IDT_MENU );
  1166.  
  1167.         SetState(eBUTTON_DOWN);
  1168.  
  1169.         RedrawWindow();
  1170.  
  1171.  
  1172.         if(m_dwButtonStyle & TB_HAS_DRAGABLE_MENU)
  1173.         {
  1174.             CPoint point = RequestMenuPlacement();
  1175.  
  1176.             if(m_pDropMenu == NULL || !m_pDropMenu->IsOpen())
  1177.             {
  1178.                 int nCount;
  1179.                 if(m_pDropMenu != NULL)
  1180.                 {
  1181.                     nCount = m_pDropMenu->GetMenuItemCount();
  1182.  
  1183.                     // clean out the menu before adding to it
  1184.                     for(int i = nCount - 1; i >= 0; i--)
  1185.                     {
  1186.                         m_pDropMenu->DeleteMenu(i, MF_BYPOSITION);
  1187.                     }
  1188.                     m_pDropMenu->DestroyDropMenu();
  1189.                     delete m_pDropMenu;
  1190.                 }
  1191.  
  1192.                 m_pDropMenu = new CDropMenu;
  1193.  
  1194.                 SendMessage(NSDRAGMENUOPEN, (WPARAM)GetButtonCommand(), (LPARAM)m_pDropMenu);
  1195.  
  1196.                 nCount = m_pDropMenu->GetMenuItemCount();
  1197.  
  1198.                 if(nCount > 0)
  1199.                 {
  1200.                     CDropMenuDropTarget *dropTarget = new CDropMenuDropTarget(m_pDropMenu);
  1201.  
  1202.                     m_pDropMenu->TrackDropMenu(this, point.x, point.y, m_bDraggingOnButton, dropTarget, m_bDraggingOnButton);
  1203.                 }
  1204.             }
  1205.             
  1206.         }
  1207.         else
  1208.         {
  1209.  
  1210.             CPoint point(0, GetButtonSize().cy);
  1211.             ClientToScreen(&point);
  1212.  
  1213.             CMenu &pMenu = GetButtonMenu();
  1214.  
  1215. #ifdef _WIN32
  1216.             WFE_GetOwnerFrame(this)->SendMessage(NSBUTTONMENUOPEN, MAKEWPARAM(GetButtonCommand(), 0 ),(LPARAM)pMenu.m_hMenu);
  1217. #else
  1218.             WFE_GetOwnerFrame(this)->SendMessage(NSBUTTONMENUOPEN, (WPARAM) GetButtonCommand(), MAKELPARAM(pMenu.m_hMenu, 0));
  1219. #endif
  1220.             SetMenuShowing(TRUE);
  1221.  
  1222.             CWnd *pWnd = WFE_GetOwnerFrame(this);
  1223.             CRect rect;
  1224.             GetWindowRect(&rect);
  1225.  
  1226.             pMenu.TrackPopupMenu(TPM_LEFTALIGN,point.x, point.y, pWnd ? pWnd : this, &rect);
  1227.                 
  1228.             SetMenuShowing(FALSE);
  1229.  
  1230.             int nCount = pMenu.GetMenuItemCount();
  1231.  
  1232.             for(int i = 0; i < nCount ; i++)
  1233.             {
  1234.                 pMenu.DeleteMenu(0, MF_BYPOSITION);
  1235.             }
  1236.  
  1237.         }
  1238.  
  1239.         SetState( eNORMAL);
  1240.         RedrawWindow();
  1241.     }
  1242.     if(nIDEvent == IDT_BUTTONFOCUS)
  1243.     {
  1244.         RemoveButtonFocus();
  1245.     }
  1246.  
  1247.  
  1248. }
  1249.  
  1250. LRESULT CToolbarButton::OnDragMenuOpen(WPARAM wParam, LPARAM lParam)
  1251. {
  1252.     GetParentFrame()->SendMessage(NSDRAGMENUOPEN,wParam, lParam);
  1253.  
  1254.     return 1;
  1255. }
  1256.  
  1257. LRESULT CToolbarButton::OnDraggingOnButton(WPARAM wParam, LPARAM lParam)
  1258. {
  1259.  
  1260.     m_bDraggingOnButton = TRUE;
  1261.     if(m_dwButtonStyle & TB_HAS_TIMED_MENU)
  1262.     {
  1263.         m_hMenuTimer = SetTimer(IDT_MENU, MENU_DELAY_MS, NULL);
  1264.     }
  1265.     else if(m_dwButtonStyle & TB_HAS_IMMEDIATE_MENU)
  1266.     {
  1267.         m_hMenuTimer = SetTimer(IDT_MENU, 0, NULL);
  1268.     }
  1269.  
  1270.     return 1;
  1271. }
  1272.  
  1273. void CToolbarButton::OnPaletteChanged( CWnd* pFocusWnd )
  1274. {
  1275.     if (pFocusWnd != this ) {
  1276.         Invalidate();
  1277.         UpdateWindow();
  1278.     }
  1279.  
  1280. }
  1281.  
  1282. void CToolbarButton::OnSysColorChange( )
  1283. {
  1284.     if(!m_bBitmapFromParent)
  1285.     {
  1286.         if(m_bIsResourceID)
  1287.         {
  1288.             if(m_hBmpImg)
  1289.                 ::DeleteObject(m_hBmpImg);
  1290.  
  1291.             HINSTANCE hInst = AfxGetResourceHandle();
  1292.             HDC hDC = ::GetDC(m_hWnd);
  1293.  
  1294.             HPALETTE hPalette= WFE_GetUIPalette(GetParentFrame());
  1295.             m_hBmpImg = WFE_LoadTransparentBitmap(hInst, hDC, sysInfo.m_clrBtnFace, RGB(255, 0, 255), hPalette, m_nBitmapID);
  1296.             
  1297.             ::ReleaseDC(m_hWnd, hDC);
  1298.             Invalidate();
  1299.         }
  1300.     }
  1301. }
  1302.  
  1303. HBRUSH CToolbarButton::OnCtlColor( CDC* pDC, CWnd* pWnd, UINT nCtlColor )
  1304. {
  1305.     if(pWnd == m_pTextEdit && nCtlColor == CTLCOLOR_EDIT)
  1306.     {
  1307.  
  1308.         pDC->SetBkColor(sysInfo.m_clrBtnFace);
  1309.         pDC->SetTextColor(sysInfo.m_clrBtnText);
  1310.         return sysInfo.m_hbrBtnFace;
  1311.     }
  1312.  
  1313.     return NULL;
  1314. }
  1315.  
  1316. //////////////////////////////////////////////////////////////////////////
  1317. //                    Helper Functions for CToolbarButton
  1318. //////////////////////////////////////////////////////////////////////////
  1319.  
  1320. void CToolbarButton::DrawPicturesAndTextMode(HDC hDC, CRect rect)
  1321. {
  1322.  
  1323.     DrawBitmapOnTop(hDC, rect);
  1324. }
  1325.  
  1326. void CToolbarButton::DrawPicturesMode(HDC hDC, CRect rect)
  1327. {
  1328.  
  1329.     DrawButtonBitmap(hDC, rect);
  1330.  
  1331. }
  1332.  
  1333. void CToolbarButton::DrawTextMode(HDC hDC, CRect rect)
  1334. {
  1335.  
  1336.     DrawTextOnly(hDC, rect);
  1337. }
  1338.  
  1339. void CToolbarButton::DrawBitmapOnTop(HDC hDC, CRect rect)
  1340. {
  1341.     CRect bitmapRect = rect;
  1342.  
  1343.     //goes 2 pixels from top
  1344.     bitmapRect.top += BITMAPVERTMARGIN;
  1345.     // Adjust the image rect
  1346.     bitmapRect.bottom = bitmapRect.top + m_bitmapSize.cy;
  1347.     
  1348.     DrawButtonBitmap(hDC, bitmapRect);
  1349.  
  1350.         // must make room for text . Note that our owner is
  1351.     // responsible for making sure our overall height is big enough to
  1352.     // hold both text and graphics.
  1353.     CString strTxt(m_pButtonText);
  1354.  
  1355.     if(m_nMaxTextChars != SHOW_ALL_CHARACTERS)
  1356.     {
  1357.          strTxt = strTxt.Left(m_nMaxTextChars);
  1358.     }
  1359.  
  1360.     HFONT font = WFE_GetUIFont(hDC);
  1361.  
  1362.     HFONT hOldFont = (HFONT)::SelectObject(hDC, font);
  1363.  
  1364.     SIZE sizeTxt;
  1365.  
  1366.     CRect sizeRect(0,0,150,0);
  1367.     ::DrawText(hDC, strTxt, strTxt.GetLength(), &sizeRect, DT_CALCRECT | DT_WORDBREAK);
  1368.     sizeTxt.cx = sizeRect.Width();
  1369.     sizeTxt.cy = sizeRect.Height();
  1370.  
  1371.     // text's baseline should be 3 pixels from bottom
  1372.     CRect txtRect = rect;
  1373.  
  1374.     txtRect.top = bitmapRect.bottom +TEXT_BITMAPVERTMARGIN;
  1375.     
  1376.     DrawButtonText(hDC, txtRect, sizeTxt, strTxt);
  1377.  
  1378.     ::SelectObject(hDC, hOldFont);
  1379.  
  1380. }
  1381.  
  1382. void CToolbarButton::DrawBitmapOnSide(HDC hDC, CRect rect)
  1383. {
  1384.  
  1385.     CRect bitmapRect = rect;
  1386.  
  1387.     bitmapRect.right = m_bitmapSize.cx + BORDERSIZE;
  1388.  
  1389.     DrawButtonBitmap(hDC, bitmapRect);
  1390.  
  1391.     CString strTxt(m_pButtonText);
  1392.  
  1393.     if(m_nMaxTextChars != SHOW_ALL_CHARACTERS)
  1394.     {
  1395.          strTxt = strTxt.Left(m_nMaxTextChars);
  1396.     }
  1397.  
  1398.     HFONT font = WFE_GetUIFont(hDC);
  1399.  
  1400.     HFONT hOldFont = (HFONT)::SelectObject(hDC, font);
  1401.  
  1402.     SIZE sizeTxt;
  1403. #if defined (WIN32)
  1404.     ::GetTextExtentPoint32(hDC, (LPCSTR)strTxt, strTxt.GetLength(), &sizeTxt);
  1405. #else
  1406.     DWORD dwSize = ::GetTextExtent(hDC, (LPCSTR)strTxt, strTxt.GetLength());
  1407.     sizeTxt.cx = LOWORD(dwSize);
  1408.     sizeTxt.cy = HIWORD(dwSize);
  1409. #endif
  1410.  
  1411.     CRect txtRect = rect;
  1412.  
  1413.     txtRect.left = bitmapRect.right;
  1414.  
  1415.     DrawButtonText(hDC, txtRect, sizeTxt, strTxt);
  1416.  
  1417.     ::SelectObject(hDC, hOldFont);
  1418. }
  1419.  
  1420. void CToolbarButton::DrawTextOnly(HDC hDC, CRect rect)
  1421. {
  1422.  
  1423.     CString strTxt(m_pButtonText);
  1424.  
  1425.     if(m_nMaxTextChars != SHOW_ALL_CHARACTERS)
  1426.     {
  1427.          strTxt = strTxt.Left(m_nMaxTextChars);
  1428.     }
  1429.  
  1430.     HFONT font = WFE_GetUIFont(hDC);
  1431.  
  1432.     HFONT hOldFont = (HFONT)::SelectObject(hDC, font);
  1433.  
  1434.  
  1435.     SIZE sizeTxt;
  1436.  
  1437.     CRect sizeRect(0,0,150,0);
  1438.     ::DrawText(hDC, strTxt, strTxt.GetLength(), &sizeRect, DT_CALCRECT | DT_WORDBREAK);
  1439.     sizeTxt.cx = sizeRect.Width();
  1440.     sizeTxt.cy = sizeRect.Height();
  1441.  
  1442.     CRect txtRect = rect;
  1443.  
  1444.     DrawButtonText(hDC, txtRect, sizeTxt, strTxt);
  1445.  
  1446.  
  1447.     ::SelectObject(hDC, hOldFont);
  1448. }
  1449.  
  1450. void CToolbarButton::DrawButtonText(HDC hDC, CRect rcTxt, CSize sizeTxt, CString strTxt)
  1451. {
  1452.  
  1453.     int nOldBkMode = ::SetBkMode(hDC, TRANSPARENT);
  1454.  
  1455.  
  1456.     if(m_bEnabled)
  1457.     {
  1458.         UINT nFormat = strTxt.Find('\n') != -1 ? 0 : DT_SINGLELINE | DT_VCENTER;
  1459.  
  1460.         COLORREF oldColor;
  1461.  
  1462.         if (hasCustomTextColor)
  1463.         {
  1464.             oldColor = ::SetTextColor(hDC, customTextColor);
  1465.         }
  1466.         else if(m_eState == eNORMAL || m_eState == eBUTTON_CHECKED)
  1467.         {
  1468.             oldColor = ::SetTextColor(hDC, sysInfo.m_clrBtnText);
  1469.             if (m_bDepressed)
  1470.                 oldColor = ::SetTextColor(hDC, RGB(255,255,255));
  1471.         }
  1472.         else if (m_eState == eBUTTON_DOWN)
  1473.         {
  1474.             oldColor = ::SetTextColor(hDC, RGB(0, 0, 128));
  1475.         }
  1476.         else if(m_eState == eBUTTON_UP)
  1477.         {
  1478.             oldColor = ::SetTextColor(hDC, RGB(0, 0, 255));
  1479.         }
  1480.  
  1481.         DrawText(hDC, (LPCSTR)strTxt, -1, &rcTxt, DT_CENTER | DT_EXTERNALLEADING | nFormat);
  1482.  
  1483.         ::SetTextColor(hDC, oldColor);
  1484.     }
  1485.     else
  1486.     {
  1487.         CRect textRect = rcTxt;
  1488.  
  1489.         
  1490.         textRect.left = textRect.left + (textRect.Width() - sizeTxt.cx) / 2;
  1491.         textRect.top = textRect.top + (textRect.Height() - sizeTxt.cy) / 2;
  1492.  
  1493.         CRect textBackgroundRect = textRect;
  1494.  
  1495. #ifdef XP_WIN32
  1496.         if(sysInfo.m_bWin4)
  1497.         {
  1498.             
  1499.             TEXTMETRIC tm;
  1500.             
  1501.             GetTextMetrics(hDC, &tm);
  1502.  
  1503.             int descent = tm.tmDescent;
  1504.             int retVal = DrawState(hDC, NULL, NULL, (LPARAM)strTxt.LockBuffer(), 0, textRect.left, textRect.top, 0, 0, DST_TEXT | DSS_DISABLED);
  1505.             strTxt.UnlockBuffer();
  1506.  
  1507.         }
  1508.         else
  1509. #endif
  1510.         {
  1511.             UINT nFormat = strTxt.Find('\n') != -1 ? 0 : DT_SINGLELINE;
  1512.  
  1513.             textBackgroundRect.left +=1;
  1514.             textBackgroundRect.top +=1;
  1515.             
  1516.             COLORREF oldColor = ::SetTextColor(hDC,  GetSysColor(COLOR_BTNHIGHLIGHT )); // white
  1517.             ::DrawText( hDC, (LPCSTR) strTxt, -1, &textBackgroundRect,   DT_EXTERNALLEADING | nFormat);
  1518.             ::SetTextColor(hDC, GetSysColor( COLOR_GRAYTEXT ) );
  1519.             ::DrawText(hDC, (LPCSTR) strTxt, -1, &textRect,   DT_EXTERNALLEADING | nFormat);
  1520.             ::SetTextColor(hDC, oldColor );
  1521.         }
  1522.     }
  1523.  
  1524.     ::SetBkMode(hDC, nOldBkMode);
  1525. }
  1526.  
  1527.  
  1528. void CToolbarButton::DrawButtonBitmap(HDC hDC, CRect rcImg)
  1529. {
  1530.     if(m_hBmpImg != NULL)
  1531.     {
  1532.         // Create a scratch DC and select our bitmap into it.
  1533.         HDC pBmpDC  = ::CreateCompatibleDC(hDC);
  1534.         HPALETTE hPalette = WFE_GetUIPalette(GetParentFrame());
  1535.  
  1536.         CBitmap BmpImg;
  1537.  
  1538.         CPoint ptDst;
  1539.  
  1540.         HINSTANCE hInst = AfxGetResourceHandle();
  1541.  
  1542.  
  1543.         HBITMAP hBmpImg;
  1544.  
  1545.         hBmpImg = m_hBmpImg;
  1546.  
  1547.         HBITMAP hOldBmp = (HBITMAP)::SelectObject(pBmpDC, hBmpImg);
  1548.         HPALETTE hOldPal = ::SelectPalette(pBmpDC, WFE_GetUIPalette(NULL), TRUE);
  1549.         ::RealizePalette(pBmpDC);
  1550.         // Get the image dimensions
  1551.         CSize sizeImg;
  1552.         BITMAP bmp;
  1553.  
  1554.         ::GetObject(hBmpImg, sizeof(bmp), &bmp);
  1555.         sizeImg.cx = bmp.bmWidth;
  1556.         sizeImg.cy = bmp.bmHeight;
  1557.  
  1558.         // Center the image within the button    
  1559.         ptDst.x = (rcImg.Width() >= m_bitmapSize.cx) ?
  1560.             rcImg.left + (((rcImg.Width() - m_bitmapSize.cx) + 1) / 2) : 0;
  1561.         
  1562.         ptDst.y = rcImg.top; 
  1563.         // If we're in the checked state, shift the image one pixel
  1564.         if (m_eState == eBUTTON_CHECKED || (m_eState == eBUTTON_UP && m_nChecked == 1))
  1565.         {
  1566.             ptDst.x += 1;
  1567.             ptDst.y += 1;
  1568.         }
  1569.     
  1570.         // Call the handy transparent blit function to paint the bitmap over
  1571.         // whatever colors exist.
  1572.         
  1573.         CPoint bitmapStart;
  1574.  
  1575.         BTN_STATE eState = m_eState;
  1576.  
  1577.         if(m_eState == eBUTTON_CHECKED)
  1578.             // A checked button has same bitmap as the normal state with no mouse-over
  1579.             eState = eNORMAL;
  1580.         else if(m_eState == eBUTTON_UP && m_nChecked == 2)
  1581.             // if we are in the mouse over mode, but indeterminate we want our bitmap to have a disabled look
  1582.             eState = eDISABLED;
  1583.  
  1584.         if(m_bIsResourceID)
  1585.             bitmapStart = CPoint(m_nBitmapIndex * m_bitmapSize.cx, m_bEnabled ? m_bitmapSize.cy * eState : m_bitmapSize.cy);
  1586.  
  1587.         if(m_bIsResourceID)  
  1588.         {
  1589.             UpdateIconInfo();
  1590.             if(m_nIconType == LOCAL_FILE)
  1591.             {
  1592.                 DrawLocalIcon(hDC, ptDst.x, ptDst.y);
  1593.             }
  1594.             else if (m_nIconType == ARBITRARY_URL)
  1595.             {
  1596.                 DrawCustomIcon(hDC, ptDst.x, ptDst.y);
  1597.             }
  1598.             else       
  1599.                 ::BitBlt(hDC, ptDst.x, ptDst.y, m_bitmapSize.cx, m_bitmapSize.cy, 
  1600.                      pBmpDC, bitmapStart.x, bitmapStart.y, SRCCOPY);
  1601.         }
  1602.         else
  1603.         {
  1604.             CSize destSize;
  1605.  
  1606.             if(sizeImg.cx > sizeImg.cy)
  1607.             {
  1608.                 destSize.cx = m_bitmapSize.cx;
  1609.                 destSize.cy = (int)(m_bitmapSize.cy * ((double)sizeImg.cy / sizeImg.cx));
  1610.             }
  1611.             else
  1612.             {
  1613.                 destSize.cx = (int)(m_bitmapSize.cx * ((double)sizeImg.cx/ sizeImg.cy));
  1614.                 destSize.cy = m_bitmapSize.cy;
  1615.             }
  1616.             StretchBlt(hDC, ptDst.x, ptDst.y, destSize.cx, destSize.cy,
  1617.                         pBmpDC, 0, 0, sizeImg.cx, sizeImg.cy, SRCCOPY);
  1618.         }
  1619.  
  1620.         // Cleanup
  1621.  
  1622.         ::SelectObject(pBmpDC, hOldBmp);
  1623.         ::SelectPalette(pBmpDC, hOldPal, TRUE);
  1624.         ::DeleteDC(pBmpDC);
  1625.  
  1626.     }
  1627. }
  1628.  
  1629. /****************************************************************************
  1630. *
  1631. *    Function: DrawUpButton
  1632. *
  1633. *    PARAMETERS:
  1634. *        pDC        - pointer to DC to draw on
  1635. *        rect    - client rect to draw in
  1636. *
  1637. *    RETURNS:
  1638. *        void
  1639. *
  1640. *    DESCRIPTION:
  1641. *        Protected helper function for drawing the 3d "up button" look.
  1642. *        This is a static function so it may be called without instantiating
  1643. *        the object.
  1644. *
  1645. ****************************************************************************/
  1646. void CToolbarButton::DrawUpButton(HDC hDC, CRect & rect)
  1647. {
  1648.     HBRUSH br = ::CreateSolidBrush(::GetSysColor(COLOR_BTNHIGHLIGHT));
  1649.  
  1650.     CRect rc(rect.left+1, rect.top+1, rect.right, 2);
  1651.     ::FillRect(hDC, rc, br);
  1652.     rc.SetRect(rect.left+1, rect.top+1, rect.left+2, rect.bottom - 1);
  1653.     ::FillRect(hDC, rc, br);
  1654.     ::DeleteObject(br);
  1655.     
  1656.     br = ::CreateSolidBrush((RGB(0, 0, 0)));
  1657.     // Extra focus indication is solid black rect around outside
  1658.     // Looks more like "Win3.0" style buttons
  1659.     FrameRect(hDC, &rect, br );
  1660.  
  1661.     // Hilight
  1662.     // Shadow
  1663.     ::DeleteObject(br);
  1664.     br = ::CreateSolidBrush(::GetSysColor(COLOR_BTNSHADOW));
  1665.     rc.SetRect(rect.left+1, rect.bottom - 2, rect.right - 1 , rect.bottom - 1);
  1666.     ::FillRect(hDC, rc, br);
  1667.     rc.SetRect(rect.right - 2, rect.top, rect.right - 1, rect.bottom - 1);
  1668.     ::FillRect(hDC, rc, br);
  1669.     ::DeleteObject(br);
  1670. /****************************************************************************
  1671. *
  1672. *    FUNCTION:  DrawDownButton
  1673. *
  1674. *    PARAMETERS:
  1675. *        pDC        - pointer to DC to draw on
  1676. *        rect    - client rect to draw in
  1677. *
  1678. *    RETURNS:
  1679. *        void
  1680. *
  1681. *    DESCRIPTION:
  1682. *        Protected helper function for drawing the 3d "down button" look.
  1683. *        This is a static function so it may be called without instantiating
  1684. *        the object.
  1685. *
  1686. ****************************************************************************/
  1687.  
  1688. void CToolbarButton::DrawDownButton(HDC hDC, CRect & rect)
  1689. {
  1690.     DrawCheckedButton(hDC, rect);
  1691.     HBRUSH br = ::CreateSolidBrush((RGB(0, 0, 0)));
  1692.  
  1693.     ::FrameRect(hDC, &rect, br );
  1694.     ::DeleteObject(br);
  1695. }
  1696.  
  1697. /****************************************************************************
  1698. *
  1699. *    FUNCTION:  DrawCheckedButton
  1700. *
  1701. *    PARAMETERS:
  1702. *        pDC        - pointer to DC to draw on
  1703. *        rect    - client rect to draw in
  1704. *
  1705. *    RETURNS:
  1706. *        void
  1707. *
  1708. *    DESCRIPTION:
  1709. *        Protected helper function for drawing the 3d "down button" look.
  1710. *        This is a static function so it may be called without instantiating
  1711. *        the object.
  1712. *
  1713. ****************************************************************************/
  1714.  
  1715. void CToolbarButton::DrawCheckedButton(HDC hDC, CRect & rect)
  1716. {
  1717.     // Hilight
  1718.     CRect rc(rect.left+1, rect.bottom - 2, rect.right - 1, rect.bottom - 1);
  1719.     HBRUSH br = ::CreateSolidBrush(::GetSysColor(COLOR_BTNHIGHLIGHT));
  1720.     ::FillRect(hDC, rc, br);
  1721.     rc.SetRect(rect.right - 2, rect.top+1, rect.right - 1, rect.bottom - 1);
  1722.     ::FillRect(hDC, rc, br);
  1723.     
  1724.     // Shadow
  1725.     ::DeleteObject(br);
  1726.     br = ::CreateSolidBrush(::GetSysColor(COLOR_BTNSHADOW));
  1727.     rc.SetRect(rect.left+1, rect.top+1, rect.right - 1, 2);
  1728.     ::FillRect(hDC, rc, br);
  1729.     rc.SetRect(rect.left+1, rect.top+1, rect.left+2, rect.bottom - 1);
  1730.     ::FillRect(hDC, rc, br);
  1731.     ::DeleteObject(br);
  1732. }
  1733.  
  1734. void CALLBACK EXPORT NSButtonMenuTimerProc(
  1735.     HWND hwnd,    // handle of window for timer messages 
  1736.     UINT uMsg,    // WM_TIMER message
  1737.     UINT idEvent,    // timer identifier
  1738.     ULONG dwTime     // current system time
  1739.     )
  1740. {
  1741. }
  1742.  
  1743. CSize CToolbarButton::GetBitmapOnTopSize(CString strTxt, int c)
  1744. {
  1745.  
  1746.     HDC hDC = ::GetDC(m_hWnd);
  1747.  
  1748.     if (c == 0)
  1749.     {
  1750.         strTxt = "";
  1751.     }
  1752.     else if(c != SHOW_ALL_CHARACTERS)
  1753.     {
  1754.          if (strTxt.GetLength() > c)
  1755.              strTxt = strTxt.Left(c - 3) + "...";
  1756.          else strTxt = strTxt.Left(c);
  1757.     }
  1758.  
  1759.     HFONT font = WFE_GetUIFont(hDC);
  1760.  
  1761.     HFONT hOldFont = (HFONT)::SelectObject(hDC, font);
  1762.     
  1763.     CRect textRect(0,0,150,0);
  1764.  
  1765.     CSize sizeTxt;
  1766.  
  1767.     if(strTxt.IsEmpty())
  1768.         sizeTxt.cx = sizeTxt.cy = 0;
  1769.     else
  1770.     {
  1771.         DrawText(hDC, strTxt, strTxt.GetLength(), &textRect, DT_CALCRECT | DT_WORDBREAK);
  1772.         sizeTxt.cx = textRect.Width();
  1773.         sizeTxt.cy = textRect.Height();
  1774.     }
  1775.  
  1776.     int nWidth, nHeight;
  1777.  
  1778.     ::SelectObject(hDC, hOldFont);
  1779.  
  1780.     nWidth = ((m_bitmapSize.cx > sizeTxt.cx) ? m_bitmapSize.cx : sizeTxt.cx) + (2 * BORDERSIZE) + HORIZMARGINSIZE;
  1781.     nHeight = m_bitmapSize.cy + sizeTxt.cy + TEXTVERTMARGIN + TEXT_BITMAPVERTMARGIN + BITMAPVERTMARGIN + (2 *BORDERSIZE);
  1782.  
  1783.     ::ReleaseDC(m_hWnd, hDC);
  1784.  
  1785.  
  1786.     return CSize(nWidth, nHeight);
  1787. }
  1788.  
  1789. CSize CToolbarButton::GetBitmapOnlySize(void)
  1790. {
  1791.  
  1792.     int nWidth, nHeight;
  1793.  
  1794.  
  1795.     nWidth = m_bitmapSize.cx + (2 * BORDERSIZE) + HORIZMARGINSIZE;
  1796.     nHeight = m_bitmapSize.cy + (2 * BORDERSIZE);
  1797.  
  1798.     return CSize(nWidth, nHeight);
  1799.  
  1800. }
  1801.  
  1802. CSize CToolbarButton::GetBitmapOnSideSize(CString strTxt, int c)
  1803. {
  1804.  
  1805.     HDC hDC = ::GetDC(m_hWnd);
  1806.  
  1807.     if(c != SHOW_ALL_CHARACTERS)
  1808.     {
  1809.          if (strTxt.GetLength() > c)
  1810.              strTxt = strTxt.Left(c - 3) + "...";
  1811.          else strTxt = strTxt.Left(c);
  1812.     }
  1813.  
  1814.     HFONT font = WFE_GetUIFont(hDC);
  1815.  
  1816.     HFONT hOldFont = (HFONT)::SelectObject(hDC, font);
  1817.     
  1818.     SIZE sizeTxt;
  1819. #if defined (_WIN32)
  1820.     ::GetTextExtentPoint32(hDC, (LPCSTR)strTxt, strTxt.GetLength(), &sizeTxt);
  1821. #else
  1822.     DWORD dwSize = ::GetTextExtent(hDC, (LPCSTR)strTxt, strTxt.GetLength());
  1823.     sizeTxt.cx = LOWORD(dwSize);
  1824.     sizeTxt.cy = HIWORD(dwSize);
  1825. #endif
  1826.  
  1827.     ::SelectObject(hDC, hOldFont);
  1828.  
  1829.     int nWidth, nHeight;
  1830.  
  1831.     nWidth = sizeTxt.cx + m_bitmapSize.cx + (2 * BORDERSIZE) + HORIZMARGINSIZE;
  1832.     nHeight =((m_bitmapSize.cy > sizeTxt.cy) ? m_bitmapSize.cy : sizeTxt.cy) + (2 * BORDERSIZE);
  1833.  
  1834.     ::ReleaseDC(m_hWnd, hDC);
  1835.     return CSize(nWidth, nHeight);
  1836. }
  1837.  
  1838. CSize CToolbarButton::GetTextOnlySize(CString strTxt, int c)
  1839. {
  1840.  
  1841.     HDC hDC = ::GetDC(m_hWnd);
  1842.  
  1843.     if(c != SHOW_ALL_CHARACTERS)
  1844.     {
  1845.          if (strTxt.GetLength() > c)
  1846.              strTxt = strTxt.Left(c - 3) + "...";
  1847.          else strTxt = strTxt.Left(c);
  1848.     }
  1849.  
  1850.     HFONT font = WFE_GetUIFont(hDC);
  1851.  
  1852.     HFONT hOldFont = (HFONT)::SelectObject(hDC, font);
  1853.     
  1854.     CRect textRect(0,0,150,0);
  1855.  
  1856.     CSize sizeTxt;
  1857.  
  1858.     if(strTxt.IsEmpty())
  1859.         sizeTxt.cx = sizeTxt.cy = 0;
  1860.     else
  1861.     {
  1862.         DrawText(hDC, strTxt, strTxt.GetLength(), &textRect, DT_CALCRECT | DT_WORDBREAK);
  1863.  
  1864.         sizeTxt.cx = textRect.Width();
  1865.         sizeTxt.cy = textRect.Height();
  1866.     }
  1867.  
  1868.     int nWidth, nHeight;
  1869.  
  1870.     ::SelectObject(hDC, hOldFont);
  1871.  
  1872.     nWidth = sizeTxt.cx +  (2 * BORDERSIZE) + HORIZMARGINSIZE;
  1873.     nHeight = sizeTxt.cy + (2 * BORDERSIZE) + (2 * TEXTONLYVERTMARGIN);
  1874.  
  1875.     ::ReleaseDC(m_hWnd, hDC);
  1876.  
  1877.     return CSize(nWidth, nHeight);
  1878.  
  1879. }
  1880.  
  1881.  void CToolbarButton::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler)
  1882. {
  1883.     m_state.m_pOther = this;
  1884.  
  1885.     m_state.m_nID = m_nCommand;
  1886.  
  1887.     m_state.DoUpdate(pTarget, bDisableIfNoHndler);
  1888. }
  1889.  
  1890.  void CToolbarButton::RemoveButtonFocus(void)
  1891.  {
  1892.  
  1893.     BOOL bStatusText = (strcmp(m_pStatusText, "") != 0);
  1894.     POINT point;
  1895.  
  1896.     KillTimer(IDT_BUTTONFOCUS);
  1897.     m_hFocusTimer = 0;
  1898.     GetCursorPos(&point);
  1899.  
  1900.     CRect rcClient;
  1901.     GetWindowRect(&rcClient);
  1902.  
  1903.     if (!rcClient.PtInRect(point))
  1904.     {
  1905.         m_bHaveFocus = FALSE;
  1906.  
  1907.         if ( bStatusText && WFE_GetOwnerFrame(this) != NULL) {
  1908.             WFE_GetOwnerFrame(this)->SendMessage( WM_SETMESSAGESTRING,
  1909.                                            (WPARAM) 0, (LPARAM) "" );
  1910.         }
  1911.  
  1912.     
  1913.         //if we lose capture and we don't have a menu showing we just want to show
  1914.         //the normal state.  If we have a menu showing we want to show the button down
  1915.         //state
  1916.         if(m_nChecked == 1)
  1917.         {
  1918.             m_eState = eBUTTON_CHECKED;
  1919.             RedrawWindow();
  1920.         }
  1921.         else if(m_nChecked == 2)
  1922.         {
  1923.             m_eState = eDISABLED;
  1924.             RedrawWindow();
  1925.         }
  1926.         else if(m_eState != eNORMAL && !m_bMenuShowing)
  1927.         {
  1928.             if(m_nChecked == 0)
  1929.             {
  1930.                 m_eState = eNORMAL;
  1931.                 RedrawWindow();
  1932.             }
  1933.         }
  1934.         else if(m_bMenuShowing)
  1935.         {
  1936.             m_eState = eBUTTON_CHECKED; //eBUTTON_DOWN;
  1937.             RedrawWindow();
  1938.         }
  1939.         else if(m_bEnabled)
  1940.         {
  1941.             if(m_nChecked == 0)
  1942.             {
  1943.                 m_eState = eNORMAL;
  1944.                 RedrawWindow();
  1945.             }
  1946.         }
  1947.         UpdateWindow();
  1948.         pCurrentButton = NULL;
  1949.     }
  1950.     else
  1951.         m_hFocusTimer = SetTimer(IDT_BUTTONFOCUS, BUTTONFOCUS_DELAY_MS, NULL);
  1952.  }
  1953.  
  1954.  BOOL CToolbarButton::CreateRightMouseMenu(void)
  1955.  {
  1956.      if((m_dwButtonStyle & TB_HAS_TIMED_MENU) && m_bEnabled)
  1957.     {
  1958.  
  1959.         #ifdef _WIN32
  1960.             GetParentFrame()->SendMessage(NSBUTTONMENUOPEN, MAKEWPARAM(m_nCommand, 0 ),(LPARAM)m_menu.m_hMenu);
  1961.         #else
  1962.             GetParentFrame()->SendMessage(NSBUTTONMENUOPEN, (WPARAM)m_nCommand, MAKELPARAM(m_menu.m_hMenu,0));
  1963.         #endif
  1964.         return TRUE;
  1965.     }
  1966.  
  1967.     return FALSE;
  1968.  }
  1969.  
  1970.  void CToolbarButton::DisplayAndTrackMenu(void)
  1971.  {
  1972.  
  1973.     m_eState = eBUTTON_DOWN;
  1974.     RedrawWindow();
  1975.  
  1976.     CPoint point = RequestMenuPlacement();
  1977.     
  1978.     CWnd *pWnd = GetMenuParent();
  1979.     CRect rect;
  1980.     GetWindowRect(&rect);
  1981.     KillTimer(IDT_BUTTONFOCUS);
  1982.     m_hFocusTimer = 0;
  1983.  
  1984.     m_menu.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,point.x, point.y, pWnd ? pWnd : this, &rect);
  1985.     
  1986.     int nCount = m_menu.GetMenuItemCount();
  1987.  
  1988.     for(int i = 0; i < nCount ; i++)
  1989.     {
  1990.         m_menu.DeleteMenu(0, MF_BYPOSITION);
  1991.     }
  1992.  
  1993.     if(m_nChecked == 0)
  1994.         m_eState = eNORMAL;
  1995.     RedrawWindow();
  1996.  
  1997.  }
  1998.  
  1999.  CWnd* CToolbarButton::GetMenuParent(void)
  2000.  {
  2001.     return GetParentFrame();
  2002.  }
  2003.  
  2004.  void CToolbarButton::GetTextRect(CRect &rect)
  2005.  {
  2006.     GetClientRect(rect);
  2007.  
  2008.     rect.InflateRect(-BORDERSIZE, -BORDERSIZE);
  2009.  
  2010.  
  2011.     if(m_nToolbarStyle == TB_PICTURESANDTEXT)
  2012.     {
  2013.         GetPicturesAndTextModeTextRect(rect);
  2014.     }
  2015.     else if(m_nToolbarStyle == TB_PICTURES)
  2016.     {
  2017.         GetPicturesModeTextRect(rect);
  2018.     }
  2019.     else
  2020.     {
  2021.         GetTextModeTextRect(rect);
  2022.     }
  2023.  
  2024.  
  2025.  }
  2026.  
  2027.  void CToolbarButton::GetPicturesAndTextModeTextRect(CRect &rect)
  2028.  {
  2029.     GetBitmapOnTopTextRect(rect);
  2030.  }
  2031.  
  2032.  void CToolbarButton::GetPicturesModeTextRect(CRect &rect)
  2033.  {
  2034.     // there is no text
  2035.     rect.SetRect(0,0,0,0);
  2036.  
  2037.  }
  2038.  
  2039.  
  2040.  void CToolbarButton::GetTextModeTextRect(CRect &rect)
  2041.  {
  2042.     GetTextOnlyTextRect(rect);
  2043.  }
  2044.  
  2045.  void CToolbarButton::GetBitmapOnTopTextRect(CRect &rect)
  2046.  {
  2047.     CRect bitmapRect = rect;
  2048.  
  2049.     //goes 2 pixels from top
  2050.     bitmapRect.top += BITMAPVERTMARGIN;
  2051.     // Adjust the image rect
  2052.     bitmapRect.bottom = bitmapRect.top + m_bitmapSize.cy;
  2053.     
  2054.     rect.top = bitmapRect.bottom +TEXT_BITMAPVERTMARGIN;
  2055.  
  2056.  }
  2057.  
  2058.  void CToolbarButton::GetTextOnlyTextRect(CRect &rect)
  2059.  {
  2060.         
  2061.  }
  2062.  
  2063.  void CToolbarButton::GetBitmapOnSideTextRect(CRect &rect)
  2064.  {
  2065.     CRect bitmapRect = rect;
  2066.  
  2067.     bitmapRect.right = m_bitmapSize.cx + BORDERSIZE;
  2068.  
  2069.     rect.left = bitmapRect.right;
  2070.  
  2071.  }
  2072.  
  2073. // End CToolbar Implementation
  2074.  
  2075. //////////////////////////////////////////////////////////////////////////////////////
  2076. //                            CDragableToolbarButton
  2077. //////////////////////////////////////////////////////////////////////////////////////
  2078.  
  2079. CDragableToolbarButton::CDragableToolbarButton()
  2080. {
  2081.     m_bDragging = FALSE;
  2082. }
  2083.  
  2084. //////////////////////////////////////////////////////////////////////////
  2085. //                    Messages for CDragableToolbarButton
  2086. //////////////////////////////////////////////////////////////////////////
  2087.  
  2088. BEGIN_MESSAGE_MAP(CDragableToolbarButton, CToolbarButton)
  2089.     //{{AFX_MSG_MAP(CWnd)
  2090.     ON_WM_LBUTTONDOWN()
  2091.     ON_WM_LBUTTONUP()
  2092.     ON_WM_MOUSEMOVE()
  2093.     ON_WM_TIMER()
  2094.     //}}AFX_MSG_MAP
  2095.  
  2096. END_MESSAGE_MAP()
  2097.  
  2098. void CDragableToolbarButton::OnLButtonUp(UINT nFlags, CPoint point)
  2099. {
  2100.     CToolbarButton::OnLButtonUp(nFlags, point);
  2101.  
  2102.     if(m_bDragging)
  2103.     {
  2104.         ReleaseCapture();
  2105.         m_bDragging = FALSE;
  2106.     }
  2107. }
  2108.  
  2109. void CDragableToolbarButton::OnLButtonDown(UINT nFlags, CPoint point)
  2110. {
  2111.     m_bDragging = TRUE;
  2112.  
  2113.     m_draggingPoint = point;
  2114.  
  2115.     CToolbarButton::OnLButtonDown(nFlags, point);
  2116.  
  2117. }
  2118.  
  2119. void CDragableToolbarButton::OnMouseMove(UINT nFlags, CPoint point)
  2120. {
  2121.     if(m_bDragging)
  2122.     {
  2123.         if((abs(point.x - m_draggingPoint.x) > 5)
  2124.              || (abs(point.y - m_draggingPoint.y) > 5))
  2125.         {
  2126.             ButtonDragged();
  2127.             m_bDragging = FALSE;
  2128.  
  2129.             GetParent()->PostMessage(NSBUTTONDRAGGING, 0,(LPARAM)m_hWnd);
  2130.             return;
  2131.         }
  2132.     }
  2133.     CToolbarButton::OnMouseMove(nFlags, point);
  2134. }
  2135.  
  2136. void CDragableToolbarButton::OnTimer( UINT  nIDEvent )
  2137. {
  2138.     CToolbarButton::OnTimer(nIDEvent);
  2139.  
  2140.     if(nIDEvent == IDT_MENU)
  2141.     {
  2142.         m_bDragging = FALSE;
  2143.     }
  2144. }
  2145. // End CDragableToolbarButton Implementation
  2146.  
  2147. //////////////////////////////////////////////////////////////////////////////////////
  2148. //                            CStationaryToolbarButton
  2149. //////////////////////////////////////////////////////////////////////////////////////
  2150. int CStationaryToolbarButton::Create(CWnd *pParent, int nToolbarStyle, 
  2151.                                 CSize noviceButtonSize, CSize advancedButtonSize,
  2152.                                 LPCTSTR pButtonText, LPCTSTR pToolTipText, 
  2153.                                 LPCTSTR pStatusText, UINT nBitmapID, UINT nBitmapIndex,
  2154.                                 CSize bitmapSize, BOOL bNeedsUpdate, UINT nCommand, 
  2155.                                 int nMaxTextChars, DWORD dwButtonStyle, int nMinTextChars)
  2156. {
  2157.     
  2158.     return(CToolbarButton::Create(pParent, nToolbarStyle, noviceButtonSize, advancedButtonSize,
  2159.                            pButtonText, pToolTipText, pStatusText, nBitmapID, nBitmapIndex, 
  2160.                            bitmapSize, bNeedsUpdate,
  2161.                            nCommand, nMaxTextChars, nMinTextChars, dwButtonStyle));
  2162.  
  2163.  
  2164. }
  2165.  
  2166. int CStationaryToolbarButton::Create(CWnd *pParent, int nToolbarStyle, 
  2167.                                     CSize noviceButtonSize, CSize advancedButtonSize,
  2168.                                     LPCTSTR pButtonText, LPCTSTR pToolTipText, 
  2169.                                     LPCTSTR pStatusText, LPCTSTR pBitmapFile,
  2170.                                     CSize bitmapSize, BOOL bNeedsUpdate, UINT nCommand, 
  2171.                                     int nMaxTextChars, DWORD dwButtonStyle, int nMinTextChars)
  2172. {
  2173.     return(CToolbarButton::Create(pParent, nToolbarStyle, noviceButtonSize, advancedButtonSize,
  2174.                            pButtonText, pToolTipText, pStatusText, pBitmapFile, 
  2175.                            bitmapSize, bNeedsUpdate,
  2176.                            nCommand, nMaxTextChars, nMinTextChars, dwButtonStyle));
  2177.  
  2178. }
  2179.  
  2180.  
  2181. //////////////////////////////////////////////////////////////////////////
  2182. //                    Messages for CStationaryToolbarButton
  2183. //////////////////////////////////////////////////////////////////////////
  2184.  
  2185. BEGIN_MESSAGE_MAP(CStationaryToolbarButton, CToolbarButton)
  2186.     //{{AFX_MSG_MAP(CWnd)
  2187.     ON_WM_LBUTTONDOWN()
  2188.     ON_WM_LBUTTONUP()
  2189.     ON_WM_MOUSEMOVE()
  2190.     //}}AFX_MSG_MAP
  2191.  
  2192. END_MESSAGE_MAP()
  2193.  
  2194. void CStationaryToolbarButton::OnLButtonUp(UINT nFlags, CPoint point)
  2195. {
  2196.     CToolbarButton::OnLButtonUp(nFlags, point);
  2197. }
  2198.  
  2199. void CStationaryToolbarButton::OnLButtonDown(UINT nFlags, CPoint point)
  2200. {
  2201.     CToolbarButton::OnLButtonDown(nFlags, point);
  2202. }
  2203.  
  2204. void CStationaryToolbarButton::OnMouseMove(UINT nFlags, CPoint point)
  2205. {
  2206.     CToolbarButton::OnMouseMove(nFlags, point);
  2207. }
  2208. // End CStationaryToolbar Implementation
  2209.  
  2210.  
  2211.  
  2212.  
  2213.  
  2214.  //////////////////////////////////////////////////////////////////////////////////////
  2215. //                            CCommandToolbarButton
  2216. //////////////////////////////////////////////////////////////////////////////////////
  2217.  
  2218. CCommandToolbarButton::CCommandToolbarButton()
  2219. {
  2220.     m_pActionOwner = NULL;
  2221. }
  2222.  
  2223. int CCommandToolbarButton::Create(CWnd *pParent, int nToolbarStyle, CSize noviceButtonSize, CSize advancedButtonSize,
  2224.                                 LPCTSTR pButtonText, LPCTSTR pToolTipText, 
  2225.                                 LPCTSTR pStatusText, UINT nBitmapID, UINT nBitmapIndex,
  2226.                                 CSize bitmapSize, UINT nCommand, int nMaxTextChars, DWORD dwButtonStyle, int nMinTextChars)
  2227. {
  2228.     
  2229.     return(CStationaryToolbarButton::Create(pParent, nToolbarStyle, noviceButtonSize, advancedButtonSize,
  2230.                            pButtonText, pToolTipText, pStatusText, nBitmapID, nBitmapIndex, bitmapSize, TRUE,
  2231.                            nCommand, nMaxTextChars, dwButtonStyle, nMinTextChars));
  2232.  
  2233.  
  2234. }
  2235.  
  2236. int CCommandToolbarButton::Create(CWnd *pParent, int nToolbarStyle, CSize noviceButtonSize, CSize advancedButtonSize,
  2237.                                   LPCTSTR pButtonText, LPCTSTR pToolTipText, 
  2238.                                   LPCTSTR pStatusText, LPCTSTR pBitmapFile,
  2239.                                   CSize bitmapSize, UINT nCommand, int nMaxTextChars, DWORD dwButtonStyle, int nMinTextChars)
  2240. {
  2241.     return(CStationaryToolbarButton::Create(pParent, nToolbarStyle, noviceButtonSize, advancedButtonSize,
  2242.                            pButtonText, pToolTipText, pStatusText, pBitmapFile, bitmapSize, TRUE,
  2243.                            nCommand, nMaxTextChars, dwButtonStyle, nMinTextChars));
  2244.  
  2245. }
  2246.  
  2247. void CCommandToolbarButton::OnAction(void)
  2248. {
  2249.      CWnd *pActionOwner;
  2250.  
  2251.      if(m_pActionOwner == NULL)
  2252.         pActionOwner = WFE_GetOwnerFrame(this);
  2253.      else
  2254.         pActionOwner = m_pActionOwner;
  2255.  
  2256. #ifdef _WIN32
  2257.     pActionOwner->PostMessage(WM_COMMAND, MAKEWPARAM(m_nCommand, m_nCommand), 0);
  2258. #else
  2259.     pActionOwner->PostMessage(WM_COMMAND, (WPARAM) m_nCommand, MAKELPARAM(this->m_hWnd, 0));
  2260. #endif
  2261. }
  2262.  
  2263.  void CCommandToolbarButton::FillInOleDataSource(COleDataSource *pDataSource)
  2264.  {
  2265.  
  2266.     HGLOBAL hCommandButton = GlobalAlloc(GMEM_DDESHARE | GMEM_ZEROINIT, sizeof(COMMANDBUTTONITEM));
  2267.     if(!hCommandButton) {
  2268.         return;
  2269.     }
  2270.  
  2271.     LPCOMMANDBUTTONITEM pCommandButton = (LPCOMMANDBUTTONITEM)GlobalLock(hCommandButton);
  2272.     
  2273.     CToolbarButton::FillInButtonData(&(pCommandButton->buttonInfo));
  2274.  
  2275.     GlobalUnlock(hCommandButton);
  2276.  
  2277.     // Create the DataSourceObject
  2278.     pDataSource->CacheGlobalData(RegisterClipboardFormat(NETSCAPE_COMMAND_BUTTON_FORMAT), hCommandButton);
  2279.   
  2280.  
  2281.  }
  2282.  
  2283.  void CCommandToolbarButton::SetActionMessageOwner(CWnd *pActionOwner)
  2284.  {
  2285.      m_pActionOwner = pActionOwner;
  2286.  }
  2287.