home *** CD-ROM | disk | FTP | other *** search
/ Prima Shareware 3 / DuCom_Prima-Shareware-3_cd1.bin / PROGRAMO / C / MRCE / SOURCE.ZIP / CLRLABEL.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-20  |  17.5 KB  |  587 lines

  1. // MRCEXT: Micro Focus Extension DLL for MFC 2.1+
  2. // Copyright (C)1994-5    Micro Focus Inc, 2465 East Bayshore Rd, Palo Alto, CA 94303.
  3. // 
  4. //  This program is free software; you can redistribute it and/or modify
  5. //  it under the terms of the GNU General Public License as published by
  6. //  the Free Software Foundation. In addition, you may also charge for any
  7. //  application    using MRCEXT, and are under no obligation to supply source
  8. //  code. You must accredit Micro Focus Inc in the "About Box", or banner
  9. //  of your application. 
  10. //
  11. //  This program is distributed in the hope that it will be useful,
  12. //  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. //  GNU General Public License for more details.
  15. //
  16. //  You should also have received a copy of the GNU General Public License with this
  17. //  software, also indicating additional rights you have when using MRCEXT.  
  18. //
  19. //
  20. // clrlabel.cpp : implementation file
  21. // $Revision:   1.0  $
  22. // $Date:   04 Dec 1995 15:24:40  $
  23. // $Author:   MRC  $
  24. //
  25. // CMRCColorLabel class
  26. //
  27. // This is meant to be a general purpose control (similar to CStatic) that can display either
  28. //      i) colored text in a specified font
  29. //  or ii) a bitmap (including 256-color bitmaps) 
  30. //
  31. // It can either be contructed direct from C API calls, resource loads, etc with the class
  32. // name "CMRCColorLabel", or from MFC CWnd::Create,CreateEx functions. 
  33.  
  34. #include "mrcstafx.h"     
  35.  
  36.  
  37.  
  38. #ifdef _DEBUG
  39. #undef THIS_FILE
  40. static char BASED_CODE THIS_FILE[] = __FILE__;
  41. #endif
  42.  
  43. /////////////////////////////////////////////////////////////////////////////
  44. // CMRCColorLabel
  45.  
  46. // Custom control style code..
  47. extern "C"
  48. {
  49. LRESULT CALLBACK CMRCColorLabelWndProc(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam);
  50. }
  51.  
  52. BOOL CMRCColorLabel::m_bRegistered = Register();
  53.  
  54. #define CMRCColorLabel_WNDCLASS     "CMRCColorLabel"        // name of the registered windows class
  55.  
  56. //-----------------------------------------------------------------------------
  57. BOOL CMRCColorLabel::Register()
  58. //-----------------------------------------------------------------------------
  59. {
  60.     // Register the window class of the control.
  61.     WNDCLASS wc;
  62.     wc.style = CS_GLOBALCLASS | CS_HREDRAW | CS_VREDRAW;
  63.     wc.lpfnWndProc = CMRCColorLabelWndProc;
  64.     wc.cbClsExtra = 0;
  65.     wc.cbWndExtra = 0;
  66.     wc.hInstance = NULL;
  67.     wc.hIcon = NULL;
  68.     wc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
  69.     wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  70.     wc.lpszMenuName = NULL;
  71.     wc.lpszClassName = CMRCColorLabel_WNDCLASS;
  72.     if (!::RegisterClass(&wc))
  73.     {
  74.         ASSERT(0);
  75.         return FALSE;
  76.     } 
  77.     return TRUE;
  78. }
  79.  
  80.  
  81. //-----------------------------------------------------------------------------
  82. LRESULT CALLBACK CMRCColorLabelWndProc(HWND hWnd, UINT uiMsg, WPARAM wParam,
  83.                                LPARAM lParam)
  84. //-----------------------------------------------------------------------------
  85. {
  86.     switch (uiMsg)
  87.     {
  88.         case WM_NCCREATE:
  89.            {
  90.             // Create a C++ object to handle the messages.
  91.             if (CWnd::FromHandlePermanent(hWnd) != NULL)    
  92.                 return TRUE;        // window already has an MFC window (ie was created via CWnd)
  93.             CMRCColorLabel * pCtl = new CMRCColorLabel;
  94.             ASSERT(pCtl);
  95.             // Attach the window handle to the new object.
  96.             BOOL b = pCtl->SubclassWindow(hWnd);
  97.             ASSERT(b);
  98.             return b;
  99.         }
  100.              break;
  101.  
  102.         default:
  103.             return ::DefWindowProc(hWnd, uiMsg, wParam, lParam);
  104.     }
  105. }
  106.  
  107.  
  108. //-----------------------------------------------------------------------------
  109. WNDPROC* CMRCColorLabel::GetSuperWndProcAddr()
  110. // Provide a place for MFC's subclassing mechanism to store the super-class pointer.
  111. //-----------------------------------------------------------------------------
  112. {
  113.     static WNDPROC NEAR pfnSuper = NULL;
  114.     return &pfnSuper;
  115. }
  116.  
  117.  
  118. //-----------------------------------------------------------------------------
  119. void CMRCColorLabel::OnNcDestroy()
  120. //-----------------------------------------------------------------------------
  121. {
  122.     CWnd::OnNcDestroy();
  123.     // Make sure the window was destroyed.
  124.     ASSERT(m_hWnd == NULL);
  125.     // Destroy this object because it won't be destroyed otherwise.
  126.     delete this;
  127. }
  128.  
  129.  
  130. //-----------------------------------------------------------------------------
  131. CMRCColorLabel::CMRCColorLabel()
  132. //-----------------------------------------------------------------------------
  133. {
  134.     m_foreground = RGB(0,0,0);          // default to BLACK on WHITE
  135.     m_background = RGB(255,255,255); 
  136.     m_pFont = NULL;
  137.     m_pDib = NULL;
  138.     m_pDibPal = NULL;
  139. }
  140.  
  141.  
  142. //-----------------------------------------------------------------------------
  143. CMRCColorLabel::~CMRCColorLabel()
  144. //-----------------------------------------------------------------------------
  145. {
  146.     delete m_pDib;
  147.     delete m_pDibPal;
  148. }
  149.  
  150.  
  151. //-----------------------------------------------------------------------------
  152. void CMRCColorLabel::SetColors(COLORREF foreground, COLORREF background)
  153. //-----------------------------------------------------------------------------
  154. {
  155.     m_foreground = foreground;
  156.     m_background = background;
  157.     InvalidateRect(NULL);
  158. }
  159.  
  160.  
  161. //-----------------------------------------------------------------------------
  162. void CMRCColorLabel::SetFont(CFont * pFont)
  163. //-----------------------------------------------------------------------------
  164. {
  165.     m_pFont = pFont;
  166.     InvalidateRect(NULL);
  167. }
  168.  
  169.  
  170. BEGIN_MESSAGE_MAP(CMRCColorLabel, CWnd)
  171.     //{{AFX_MSG_MAP(CMRCColorLabel)
  172.     ON_WM_PAINT()
  173.     ON_WM_NCDESTROY()
  174.     ON_WM_ERASEBKGND()
  175.     ON_WM_CREATE()
  176.     //}}AFX_MSG_MAP
  177. END_MESSAGE_MAP()
  178.  
  179.  
  180.  
  181. /////////////////////////////////////////////////////////////////////////////
  182. // CMRCColorLabel message handlers
  183.  
  184. //-----------------------------------------------------------------------------
  185. void CMRCColorLabel::OnPaint() 
  186. //-----------------------------------------------------------------------------
  187. {
  188.     CString str;
  189.     CFont * pOldFont = NULL;
  190.     CPaintDC dc(this); // device context for painting
  191.     CRect rect;
  192.  
  193.     GetClientRect(&rect);
  194.     int style = GetStyle();
  195.     
  196.     // draw fake border round the window. 
  197.     if (style & CLBS_BORDER_RAISED)
  198.     {
  199.         ::DrawBorderRaisedOuter(&dc, &rect);
  200.         ::DrawBorderRaisedInner(&dc, &rect);
  201.     }
  202.     else
  203.         if (style & CLBS_BORDER_SUNKEN)
  204.         {
  205.             ::DrawBorderSunkenOuter(&dc, &rect);
  206.             ::DrawBorderSunkenInner(&dc, &rect);
  207.         }
  208.  
  209.  
  210.     if (style & CLBS_BITMAP)        // is it a bitmap ?
  211.     {
  212.         if (m_pDib != NULL)
  213.         {
  214.             CPoint pt;
  215.             CPalette * pOldPal = NULL;
  216.             if (m_pDibPal != NULL)         // if there's a palette, realize it
  217.             {                           
  218.                 pOldPal = dc.SelectPalette(m_pDibPal, FALSE);
  219.                 dc.RealizePalette();
  220.             }
  221.         
  222.             if (style & CLBS_CENTER)
  223.             {
  224.                 pt.x = (rect.right + rect.left - m_pDib->DibWidth()) / 2;
  225.                 pt.y = (rect.bottom + rect.top - m_pDib->DibHeight()) / 2;
  226.             }
  227.             else        // draw top left
  228.             {
  229.                 pt.x = rect.left;
  230.                 pt.y = rect.top;
  231.             }
  232.  
  233.             if (style & CLBS_BITMAP_STRETCH)
  234.                 m_pDib->Draw(&dc, 0, 0, rect.right, rect.bottom);
  235.             else
  236.                 m_pDib->Draw(&dc, pt.x, pt.y);
  237.             
  238.             if (pOldPal != NULL) 
  239.                 dc.SelectPalette(pOldPal, FALSE);
  240.           }
  241.     }
  242.     else        
  243.     {        // it's just text
  244.         UINT DrawStyle = DT_WORDBREAK; 
  245.         if (style & CLBS_CENTER)   
  246.             DrawStyle = DT_SINGLELINE | DT_CENTER | DT_VCENTER;
  247.     
  248.         dc.SetTextColor(m_foreground);
  249.     // If we've filled the background, just draw the text opaque
  250.         if (style & CLBS_FILLBACKGROUND)
  251.             dc.SetBkMode(TRANSPARENT);
  252.         else
  253.             dc.SetBkColor(m_background);
  254.     
  255.         if (m_pFont != NULL)
  256.             pOldFont = dc.SelectObject(m_pFont);
  257.         else 
  258.             pOldFont = dc.SelectObject(GetParent()->GetFont());
  259.     
  260.         GetWindowText(str);
  261.         dc.DrawText(str, str.GetLength(), &rect, DrawStyle);        
  262.         if (pOldFont)
  263.             dc.SelectObject(pOldFont);
  264.     }
  265.     
  266. }
  267.  
  268.  
  269.  
  270. //---------------------------------------------------------------------------------
  271. BOOL CMRCColorLabel::OnEraseBkgnd(CDC* pDC) 
  272. //---------------------------------------------------------------------------------
  273. {
  274.     int style = GetStyle();
  275.     // explicitly fill the background with the background brush
  276.     // if style no specified then the window will not draw into the background
  277.     if (style & CLBS_FILLBACKGROUND)
  278.     {
  279.         CRect rect;
  280.         pDC->GetClipBox(&rect);
  281.         CBrush brush(m_background);
  282.         pDC->FillRect(&rect, &brush);
  283.         return TRUE;
  284.     }
  285.     else
  286.         return TRUE;
  287. }
  288.  
  289.  
  290. //---------------------------------------------------------------------------------
  291. BOOL CMRCColorLabel::LoadDIB(LPCTSTR lpszResource, DWORD dwStyle)
  292. // Loads a bitmap and creates a palette for it
  293. //---------------------------------------------------------------------------------
  294. {
  295.     m_pDib = new CMRCDib;
  296.     if ( !m_pDib->LoadFromResource(lpszResource))
  297.     {
  298.         delete m_pDib;
  299.         m_pDib = NULL;
  300.         return FALSE;
  301.     }
  302.     return SetDibInfo(dwStyle);
  303. }    
  304.  
  305.  
  306. //---------------------------------------------------------------------------------
  307. BOOL CMRCColorLabel::LoadDIBFromFile(LPCTSTR lpszFile, DWORD dwStyle)
  308. // Loads a bitmap and creates a palette for it
  309. //---------------------------------------------------------------------------------
  310. {
  311.     m_pDib = new CMRCDib;
  312.     if ( !m_pDib->LoadFileName(lpszFile))
  313.     {
  314.         delete m_pDib;
  315.         m_pDib = NULL;
  316.         return FALSE;
  317.     }
  318.     return SetDibInfo(dwStyle);
  319. }    
  320.  
  321.  
  322. //---------------------------------------------------------------------------------
  323. BOOL CMRCColorLabel::SetDibInfo(DWORD dwStyle)
  324. // helper function to cope after a dib has been loaded
  325. //---------------------------------------------------------------------------------
  326. {
  327.     DWORD style = GetStyle();
  328.     if (dwStyle != 0x70000000)         // if new style specified, attempt to changed it
  329.     {
  330.         style &= ~(CLBS_BITMAP_STYLES);
  331.         style |= dwStyle;
  332.     }
  333.     style |= CLBS_BITMAP;        // make sure it's a bitmap
  334.     ::SetWindowLong(m_hWnd, GWL_STYLE, style);        // set the window style
  335.     
  336.     // if palette required, load it
  337.     if (style & CLBS_BITMAP_PALETTE)    
  338.     {    
  339.         m_pDibPal = new CMRCDibPal;
  340.         if (!m_pDibPal->Create(m_pDib))
  341.         {
  342.             delete m_pDibPal;
  343.             m_pDibPal = NULL;
  344.             return FALSE;
  345.         }
  346.     }
  347.     
  348.     // check for auto sizing
  349.     if (style & CLBS_BITMAP_AUTOSIZE)
  350.     {
  351.         ASSERT((style & CLBS_BITMAP_STRETCH) == 0);    // can't stretch and auto size !
  352.  
  353.         CRect rect;
  354.         GetWindowRect(&rect);
  355.         // convert to parent co-ords
  356.         CWnd * pParentWnd = GetParent();
  357.         if (pParentWnd != NULL)
  358.             pParentWnd->ScreenToClient(&rect);
  359.         CSize size(m_pDib->DibWidth(), m_pDib->DibHeight());
  360.         UINT SWPflags;
  361.         // centering means we actually move the window to where we think it should be
  362.         if (style & CLBS_CENTER)
  363.         {
  364.             rect.left = (rect.left + rect.right - size.cx ) / 2;
  365.             rect.top  = (rect.top + rect.bottom - size.cy ) / 2;
  366.             SWPflags = SWP_NOZORDER;
  367.         }
  368.         else
  369.             SWPflags = SWP_NOZORDER | SWP_NOMOVE;
  370.  
  371.         SetWindowPos(NULL, rect.left, rect.top, size.cx, size.cy, SWPflags);
  372.     }
  373.     return TRUE;
  374. }
  375.  
  376.  
  377. //-----------------------------------------------------------------------------------
  378. int CMRCColorLabel::OnCreate(LPCREATESTRUCT lpCS) 
  379. //-----------------------------------------------------------------------------------
  380. {
  381.     if (CWnd::OnCreate(lpCS) == -1)
  382.         return -1;
  383.     
  384.     // check to see if user has asked us to load a bitmap from the ID.
  385.     if (lpCS->style & CLBS_BITMAP_FROMTITLE)
  386.     {
  387.         ASSERT((lpCS->style & CLBS_BITMAP_FROMID) == 0);        // invalid combination of styles
  388.  
  389.         int nResourceID = atoi(lpCS->lpszName);
  390.         BOOL status;
  391.         if (nResourceID == 0)
  392.             status = LoadDIB(lpCS->lpszName);
  393.         else
  394.             status = LoadDIB(nResourceID);
  395.         if (status == FALSE)
  396.         {
  397.             TRACE("CMRCColorLabel: Failed to load bitmap via caption: \"%s\"\n", lpCS->lpszName);
  398.             return -1;
  399.         }
  400.     }        
  401.     else
  402.         if (lpCS->style & CLBS_BITMAP_FROMID)
  403.         {
  404.             if (!LoadDIB((UINT)lpCS->hMenu))
  405.             {
  406.                 TRACE("CMRCColorLabel: Failed to load bitmap via ID: %d\n", (int)lpCS->hMenu);
  407.                 return -1;
  408.             }
  409.         }
  410.     return 0;
  411. }
  412.  
  413.  
  414.  
  415.  
  416. //---------------------------------------------------------------------------------
  417. BOOL CMRCColorLabel::CreateSplash(LPCTSTR lpszResource, DWORD dwStyle, BOOL bBorder)
  418. // Creates a TOPMOST, visible window, centred in the display - really meant as a 
  419. // splash screen. 
  420. //---------------------------------------------------------------------------------
  421. {
  422.     dwStyle |= WS_POPUP | CLBS_CENTER;
  423.     if (bBorder)
  424.         dwStyle |= CLBS_BORDER_RAISED | CLBS_FILLBACKGROUND;
  425.     
  426.     if (!CreateEx(0 /*WS_EX_TOPMOST */,
  427.               CMRCColorLabel_WNDCLASS, NULL,
  428.              dwStyle,
  429.              0, 0, 0, 0, NULL, 0))
  430.     {
  431.         TRACE("CMRCColorLabel:CreateSplash failed\n");
  432.         return FALSE;
  433.     }
  434.     // now load the bitmap...
  435.     if (!LoadDIB(lpszResource, dwStyle))
  436.     {
  437.         DestroyWindow();
  438.          TRACE("CMRCColorLabel:CreateSplash failed to load bitmap\n");
  439.         return FALSE;
  440.     }
  441.     
  442.     ASSERT(m_pDib != NULL);
  443.  
  444.     // position in center and force drawing.
  445.     CRect deskrect;
  446.  
  447.     int winHt, winWd, winx, winy;
  448.     winHt = m_pDib->DibHeight();
  449.     winWd = m_pDib->DibWidth();
  450.     if (bBorder)
  451.     {
  452.         m_background = GetSysColor(COLOR_BTNFACE);
  453.         winHt += 7;
  454.         winWd += 7;
  455.     }
  456.  
  457.     // did try using the correct system metrics, but Microsoft forgot to define them...
  458.     // winx = ((GetSystemMetric(SM_CXWORKAREA) - winWd ) / 2) + GetSystemMetric(SM_XWORKAREA);
  459.     // winy = ((GetSystemMetric(SM_CYWORKAREA) - winHt ) / 2) + GetSystemMetric(SM_YWORKAREA);
  460.     // so use API code instead...
  461.     ::GetWindowRect(::GetDesktopWindow(), &deskrect);
  462.     winx = ((deskrect.right - winWd ) / 2) ;
  463.     winy = ((deskrect.bottom - winHt ) / 2) ;
  464.  
  465.     SetWindowPos(NULL, winx, winy, winWd, winHt, SWP_SHOWWINDOW); 
  466.     
  467.     InvalidateRect(NULL, FALSE);        // force paint of window
  468.     UpdateWindow();
  469.     return TRUE;
  470. }
  471.  
  472.  
  473. //---------------------------------------------------------------------------------
  474. BOOL CMRCColorLabel::Create(LPCTSTR lpszWindowName, DWORD dwStyle, RECT & rect,
  475.                          CWnd *pParentWnd, UINT nID)
  476. //---------------------------------------------------------------------------------
  477. {
  478.     // add these to get the total border for the window....
  479.     return (CWnd::Create(CMRCColorLabel_WNDCLASS, lpszWindowName, dwStyle,
  480.                              rect, pParentWnd, nID));
  481. }
  482.  
  483.  
  484.  
  485. // Borrowed from MFCUSEFL.cpp
  486.  
  487. // widths/heights of rectangle borders. Probably will always be 1, but you never know
  488. #define bheight 1
  489. #define bwidth  1
  490.  
  491. //-----------------------------------------------------------------------------------------
  492. void DrawBorderSunkenInner(CDC *pDC, RECT * prect)
  493. //-----------------------------------------------------------------------------------------
  494. {
  495.     DrawRectBorder(pDC, prect, ::GetSysColor(COLOR_WINDOWFRAME), ::GetSysColor(COLOR_BTNFACE));
  496. }
  497.  
  498. //-----------------------------------------------------------------------------------------
  499. void DrawBorderSunkenOuter(CDC *pDC, RECT * prect)
  500. //-----------------------------------------------------------------------------------------
  501. {
  502.     DrawRectBorder(pDC, prect, ::GetSysColor(COLOR_BTNSHADOW), ::GetSysColor(COLOR_BTNHIGHLIGHT));
  503. }
  504.  
  505. //-----------------------------------------------------------------------------------------
  506. void DrawBorderRaisedInner(CDC *pDC, RECT * prect)
  507. //-----------------------------------------------------------------------------------------
  508. {
  509.     DrawRectBorder(pDC, prect, ::GetSysColor(COLOR_BTNHIGHLIGHT), ::GetSysColor(COLOR_BTNSHADOW));
  510. }
  511.  
  512. //-----------------------------------------------------------------------------------------
  513. void DrawBorderRaisedOuter(CDC *pDC, RECT * prect)
  514. //-----------------------------------------------------------------------------------------
  515. {
  516.     DrawRectBorder(pDC, prect, ::GetSysColor(COLOR_BTNFACE), ::GetSysColor(COLOR_WINDOWFRAME));
  517. }
  518.  
  519. //-----------------------------------------------------------------------------------------
  520. void DrawRectBorder(CDC *pDC, RECT *prect, COLORREF crTopLeft, COLORREF crBottomRight)
  521. // draws a rectangle. Top & Right edges drawn with one brush, Bottom & Left edges drawn
  522. // with another. Generic function used to give different border types, as described by
  523. // Chicago style guide.
  524. //-----------------------------------------------------------------------------------------
  525. {
  526.     RECT rect;
  527.     CBrush TopLeftBrush (crTopLeft);  
  528.     CBrush BottomRightBrush (crBottomRight);
  529.  
  530. // draw top side
  531.     rect.top    = prect->top;
  532.     rect.bottom = prect->top + bheight;
  533.     rect.left   = prect->left;
  534.     rect.right  = prect->right - bwidth;
  535.     pDC->FillRect(&rect, &TopLeftBrush);    
  536.     
  537. // draw left side
  538.     rect.top    = prect->top + bheight;
  539.     rect.bottom = prect->bottom - bheight;
  540.     rect.left   = prect->left;
  541.     rect.right  = prect->left + bwidth;
  542.     pDC->FillRect(&rect, &TopLeftBrush);    
  543.         
  544. // draw right side
  545.     rect.top    = prect->top;
  546.     rect.bottom = prect->bottom - bheight;
  547.     rect.left   = prect->right - bwidth;
  548.     rect.right  = prect->right;
  549.     pDC->FillRect(&rect, &BottomRightBrush);    
  550.     
  551. // draw bottom side
  552.     rect.top    = prect->bottom - bheight;
  553.     rect.bottom = prect->bottom;
  554.     rect.left   = prect->left;
  555.     rect.right  = prect->right;
  556.     pDC->FillRect(&rect, &BottomRightBrush);    
  557.  
  558. // shrink the rectangle
  559.     prect->top += bheight;
  560.     prect->bottom -= bheight;
  561.     prect->left += bwidth;
  562.     prect->right -= bwidth;
  563. }
  564.  
  565.  
  566.  
  567.  
  568. //-----------------------------------------------------------------------------------
  569. int GetNumberSystemColors()    
  570. // Returns color capability of the screen. Used to distinguish 16/256 color displays. 
  571. //-----------------------------------------------------------------------------------
  572. {
  573.     static NumColors = 0;
  574.  
  575.     if (NumColors == 0)
  576.     {        
  577.     // Get number of colors screen DC can display - this is only done once
  578.         HDC hdc = ::GetDC(NULL);
  579.         NumColors = ::GetDeviceCaps(hdc, SIZEPALETTE /*NUMCOLORS */);
  580.         ::ReleaseDC(NULL,hdc);
  581.     }
  582.     return(NumColors);
  583. }
  584.  
  585.  
  586.  
  587.