home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 23 / IOPROG_23.ISO / SOFT / BCOLOR.ZIP / ComboBtn.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-02-03  |  18.8 KB  |  674 lines

  1. // colorctl.cpp : implementation file
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include "ComboBtn.h"
  6.  
  7. void FillSolidRect(CDC * pDC, int x, int y, int cx, int cy, COLORREF clr)
  8. {
  9.     ASSERT(pDC != NULL);
  10.     ASSERT(pDC->m_hDC != NULL);
  11.  
  12.     COLORREF oldColor = pDC->SetBkColor(clr);
  13.     CRect rect(x, y, x + cx, y + cy);
  14.     pDC->ExtTextOut(0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
  15.     pDC->SetBkColor(oldColor);
  16. }
  17.  
  18. void Draw3dRect(CDC * pDC, int x, int y, int cx, int cy, COLORREF clrTopLeft, COLORREF clrBottomRight)
  19. {
  20.     FillSolidRect(pDC, x, y, cx - 1, 1, clrTopLeft);
  21.     FillSolidRect(pDC, x, y, 1, cy - 1, clrTopLeft);
  22.     FillSolidRect(pDC, x + cx, y, -1, cy, clrBottomRight);
  23.     FillSolidRect(pDC, x, y + cy, cx, -1, clrBottomRight);
  24. }
  25.  
  26. void Draw3dRect(CDC * pDC, LPCRECT lpRect, COLORREF clrTopLeft, COLORREF clrBottomRight)
  27. {
  28.     Draw3dRect(pDC, lpRect->left, lpRect->top, lpRect->right - lpRect->left, 
  29.         lpRect->bottom - lpRect->top, clrTopLeft, clrBottomRight);
  30. }
  31.  
  32. #ifdef _DEBUG
  33. #undef THIS_FILE
  34. static char BASED_CODE THIS_FILE[] = __FILE__;
  35. #endif
  36.  
  37. /////////////////////////////////////////////////////////////////////////////
  38. // CButtonCombo
  39.  
  40. CButtonCombo::CButtonCombo()
  41. {
  42.     m_bLeftBtnDown     = m_bRightBtnDown    = FALSE;
  43.     m_bLeftBtnOut     = FALSE;
  44.     m_lItem            = m_iRealItem = 0;
  45. }
  46.  
  47. CButtonCombo::~CButtonCombo()
  48. {    
  49.     m_wndColor.DestroyWindow();
  50. }
  51.  
  52.  
  53. BEGIN_MESSAGE_MAP(CButtonCombo, CWnd)
  54.     //{{AFX_MSG_MAP(CButtonCombo)
  55.     ON_WM_LBUTTONDOWN()
  56.     ON_WM_LBUTTONUP()
  57.     ON_WM_MOUSEMOVE()
  58.     ON_WM_PAINT()
  59.     ON_WM_ENABLE()
  60.     //}}AFX_MSG_MAP
  61. END_MESSAGE_MAP()
  62.  
  63.  
  64. /////////////////////////////////////////////////////////////////////////////
  65. // CButtonCombo message handlers
  66.  
  67. // rect         = size of the button
  68. // sizeGrid     = size of grid containing the color (x rectangles by y rectangles)
  69. // sizeBtn         = size of ech rectangle in the grid containing the color
  70. // pParent        = parent of the button
  71. // nID            = ID of the button
  72. // sTextItems    = (optional) text to show when selecting a color
  73.  
  74. BOOL CButtonCombo::Create(CRect rect, CSize sizeGrid, CSize sizeBtn, CWnd * pParent, 
  75.                         UINT nID, CString sTextItems)
  76. {              
  77.     ASSERT(pParent);
  78.     m_pParent    = pParent;
  79.     m_nID         = nID;
  80.  
  81.     if(!CWnd::Create(NULL, NULL, WS_BORDER | WS_VISIBLE | WS_CHILD, rect, m_pParent, m_nID))
  82.         return FALSE;
  83.         
  84.     if (!m_wndColor.Create(rect.left, rect.bottom, sizeGrid, sizeBtn, this, sTextItems))
  85.         return FALSE;        
  86.         
  87.     return TRUE;
  88. }
  89.  
  90. // rect                 = size of the button
  91. // sizeGrid             = size of grid containing the color (x rectangles by y rectangles)
  92. // nBitmapIDResource     = ID of the bitmap
  93. // iNbImages            = number of images in the bitmap
  94. // nID                    = ID of the button
  95. // sTextItems            = (optional) text to show when selecting a color
  96.  
  97. BOOL CButtonCombo::Create(CRect rect, CSize sizeGrid, UINT nBitmapIDResource, int iNbImages, 
  98.                         CWnd * pParent, UINT nID, CString sTextItems)
  99. {
  100.     ASSERT(pParent);
  101.     m_pParent    = pParent;
  102.     m_nID         = nID;
  103.  
  104.     if(!CWnd::Create(NULL, NULL, WS_BORDER | WS_VISIBLE | WS_CHILD, rect, m_pParent, m_nID))
  105.         return FALSE;
  106.         
  107.     if (!m_wndColor.Create(rect.left, rect.bottom, sizeGrid, nBitmapIDResource, 
  108.                             iNbImages, this, sTextItems))
  109.         return FALSE;
  110.     return TRUE;
  111. }
  112.  
  113. void CButtonCombo::OnItemSelected(long lItem, int iRealItem)
  114. {                  
  115.     m_lItem         = lItem;
  116.     m_iRealItem       = iRealItem;
  117.     m_bLeftBtnDown     = FALSE;
  118.     m_bRightBtnDown = FALSE;
  119.     m_wndColor.SetSelectedItem(m_iRealItem);
  120.     m_wndColor.ShowWindow(m_bRightBtnDown ? SW_SHOW : SW_HIDE);
  121.     Invalidate(FALSE);
  122.     UpdateWindow();
  123.  
  124.     if (m_lItem >= 0)
  125.     {                
  126.         if (m_pParent->GetOwner()->IsKindOf(RUNTIME_CLASS(CDialog)))
  127.             m_pParent->GetOwner()->SendMessage(WM_USER+21, (WPARAM)m_nID, (LPARAM)m_lItem);
  128.         else    
  129.             AfxGetMainWnd()->SendMessageToDescendants(WM_USER+21, (WPARAM)m_nID, (LPARAM)m_lItem, TRUE, TRUE);
  130.     }
  131. }
  132.  
  133. void CButtonCombo::UnpressRightButton() 
  134. {
  135.     m_bRightBtnDown = FALSE;
  136.     Invalidate(FALSE);
  137.     UpdateWindow();
  138. }
  139.  
  140. void CButtonCombo::OnLButtonDown(UINT nFlags, CPoint point) 
  141. {         
  142.     CRect rect;
  143.     GetClientRect(&rect);
  144.     CRect rcLeft(rect.left, rect.top, rect.right - 15, rect.bottom);
  145.     CRect rcRight(rect.right - 15, rect.top, rect.right, rect.bottom);
  146.     
  147.     if (rcLeft.PtInRect(point))
  148.     {             
  149.         m_bLeftBtnDown    = TRUE;
  150.         m_bRightBtnDown = FALSE;
  151.     }
  152.     else if (rcRight.PtInRect(point))
  153.         m_bRightBtnDown ^= 1;
  154.     else              
  155.         m_bLeftBtnDown     = m_bRightBtnDown = FALSE;
  156.   
  157.       GetWindowRect(rect);
  158.     m_wndColor.SetWindowPos(NULL, rect.left, rect.bottom, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
  159.     m_wndColor.SetSelectedItem(m_iRealItem);
  160.     m_wndColor.ShowWindow(m_bRightBtnDown ? SW_SHOW : SW_HIDE);
  161.  
  162.     Invalidate(FALSE);
  163.     UpdateWindow();
  164.  
  165.     SetCapture();
  166.      
  167.     CWnd::OnLButtonDown(nFlags, point);
  168. }
  169.  
  170. void CButtonCombo::OnLButtonUp(UINT nFlags, CPoint point) 
  171. {       
  172.     ReleaseCapture();
  173.  
  174.     if (m_bLeftBtnDown)
  175.         OnItemSelected(m_lItem, m_iRealItem);
  176.     m_bLeftBtnDown = FALSE;
  177.     Invalidate(FALSE);
  178.     UpdateWindow();
  179.     
  180.     CWnd::OnLButtonUp(nFlags, point);
  181. }
  182.  
  183. void CButtonCombo::OnMouseMove(UINT nFlags, CPoint point) 
  184. {
  185.     BOOL bOut = m_bLeftBtnOut;
  186.     CRect rect;
  187.     GetClientRect(&rect);
  188.     CRect rcLeft(rect.left, rect.top, rect.right - 15, rect.bottom);
  189.     
  190.     if (rcLeft.PtInRect(point))
  191.         m_bLeftBtnOut    = FALSE;
  192.     else
  193.         m_bLeftBtnOut     = TRUE;
  194.  
  195.     if (bOut != m_bLeftBtnOut)
  196.     {
  197.         Invalidate(FALSE);
  198.         UpdateWindow();
  199.     }
  200.     
  201.     CWnd::OnMouseMove(nFlags, point);
  202. }
  203.  
  204. void CButtonCombo::OnPaint() 
  205. {
  206.     CPaintDC dc(this); // device context for painting
  207.     
  208.     CRect rect;
  209.     GetClientRect(&rect);
  210.     CRect rcLeft(rect.left, rect.top, rect.right - 15, rect.bottom-1);
  211.     CRect rcRight(rect.right - 15, rect.top, rect.right - 1, rect.bottom-1);
  212.  
  213.     CDC memDC;
  214.     CBitmap bitmap;
  215.     bitmap.CreateCompatibleBitmap(&dc, rect.Width(), rect.Height());
  216.     memDC.CreateCompatibleDC(&dc);
  217.     CBitmap * pOldBitmap = memDC.SelectObject(&bitmap);
  218.  
  219.     CBrush brBack(GetSysColor(COLOR_BTNFACE));
  220.     memDC.FillRect(rect, &brBack);
  221.  
  222.     Draw3dRect(&memDC, &rect, GetSysColor(COLOR_BTNHIGHLIGHT), GetSysColor(COLOR_BTNSHADOW)); 
  223.  
  224.     CRect rcImage(rcLeft.left+1, rcLeft.top+1, rcLeft.right-1, rcLeft.bottom-1);
  225.     if (!m_bLeftBtnDown || m_bLeftBtnOut) // Draw Button Up
  226.         Draw3dRect(&memDC, &rcLeft, GetSysColor(COLOR_BTNHIGHLIGHT), GetSysColor(COLOR_BTNSHADOW)); 
  227.     else
  228.     {
  229.         rcLeft.SetRect(rcLeft.left, rcLeft.top, rcLeft.right+1, rcLeft.bottom+1);
  230.         Draw3dRect(&memDC, &rcLeft, GetSysColor(COLOR_BTNSHADOW), GetSysColor(COLOR_BTNFACE)); 
  231.         rcImage.OffsetRect(1, 1);
  232.     }
  233.  
  234.     m_wndColor.DrawBtnFace(&memDC, rcImage, m_lItem);
  235.  
  236.     if (!m_bRightBtnDown) // Draw Button Up
  237.         Draw3dRect(&memDC, &rcRight, GetSysColor(COLOR_BTNHIGHLIGHT), GetSysColor(COLOR_BTNSHADOW)); 
  238.     else
  239.     {
  240.         rcRight.SetRect(rcRight.left, rcRight.top, rcRight.right+1, rcRight.bottom+1);
  241.         Draw3dRect(&memDC, &rcRight, GetSysColor(COLOR_BTNSHADOW), GetSysColor(COLOR_BTNFACE)); 
  242.         rcRight.OffsetRect(1, 1);
  243.     }
  244.     
  245.     DrawArrow(&memDC, &rcRight);    
  246.     
  247.     if (!IsWindowEnabled())
  248.         DrawDisabled(&memDC, rect);
  249.  
  250.     dc.BitBlt(rect.left, rect.top, rect.Width(), rect.Height(), &memDC, rect.left, rect.top, SRCCOPY);
  251.     memDC.SelectObject(pOldBitmap);
  252.  
  253.     brBack.DeleteObject();
  254.     bitmap.DeleteObject();
  255. }
  256.  
  257. void CButtonCombo::DrawDisabled( CDC * pDC, const CRect & rc )
  258. {
  259.     // create a monochrome memory DC
  260.     CDC memDC;
  261.     memDC.CreateCompatibleDC(0);
  262.     CBitmap bmp;
  263.     bmp.CreateCompatibleBitmap(&memDC, rc.Width(), rc.Height());
  264.     CBitmap * pOldBmp = memDC.SelectObject(&bmp);
  265.     
  266.     // build a mask
  267.     memDC.PatBlt(0, 0, rc.Width(), rc.Height(), WHITENESS);
  268.     pDC->SetBkColor(GetSysColor(COLOR_BTNFACE));
  269.     memDC.BitBlt(0, 0, rc.Width(), rc.Height(), pDC, rc.left, rc.top, SRCCOPY);
  270.     pDC->SetBkColor(GetSysColor(COLOR_BTNHIGHLIGHT));
  271.     memDC.BitBlt(0, 0, rc.Width(), rc.Height(), pDC, rc.left, rc.top, SRCPAINT);
  272.  
  273.     // Copy the image from the toolbar into the memory DC
  274.     // and draw it (grayed) back into the toolbar.
  275.     CBrush     brShadow(GetSysColor(COLOR_BTNSHADOW)), 
  276.             brHilight(GetSysColor(COLOR_BTNHIGHLIGHT)), 
  277.             brFace(GetSysColor(COLOR_BTNFACE));
  278.     
  279. //    pDC->FillRect(rc, &brFace);
  280.     pDC->SetBkColor(RGB(0, 0, 0));
  281.     pDC->SetTextColor(RGB(255, 255, 255));
  282.  
  283.  
  284.     CBrush * pOldBrush = pDC->SelectObject(&brHilight);
  285.     pDC->BitBlt(rc.left+1, rc.top+1, rc.Width(), rc.Height(), &memDC, 0, 0, 0x00E20746L);
  286.     pDC->SelectObject(&brShadow);
  287.     pDC->BitBlt(rc.left, rc.top, rc.Width(), rc.Height(), &memDC, 0, 0, 0x00E20746L);
  288.     
  289.     // reset DCs
  290.     pDC->SelectObject(pOldBrush);
  291.     memDC.SelectObject(pOldBmp);
  292.     memDC.DeleteDC();
  293.  
  294.     brShadow.DeleteObject();
  295.     brHilight.DeleteObject();
  296.     brFace.DeleteObject();
  297.     bmp.DeleteObject();
  298. }
  299.  
  300. void CButtonCombo::DrawArrow(CDC * pDC, CRect * pRect)
  301. {
  302.     ASSERT(pRect);
  303.  
  304.     CPoint ptCenter(pRect->left + (pRect->Width() / 2), pRect->top + (pRect->Height() / 2));
  305.  
  306.     CPoint ptArrow[7];
  307.     ptArrow[0].x = ptCenter.x-1;
  308.     ptArrow[0].y = ptCenter.y-4;
  309.     
  310.     ptArrow[1].x = ptCenter.x-1;
  311.     ptArrow[1].y = ptCenter.y-1;
  312.  
  313.     ptArrow[2].x = ptCenter.x-3;
  314.     ptArrow[2].y = ptCenter.y-1;
  315.  
  316.     ptArrow[3].x = ptCenter.x;
  317.     ptArrow[3].y = ptCenter.y+2;
  318.  
  319.     ptArrow[4].x = ptCenter.x+3;
  320.     ptArrow[4].y = ptCenter.y-1;
  321.  
  322.     ptArrow[5].x = ptCenter.x+1;
  323.     ptArrow[5].y = ptCenter.y-1;
  324.  
  325.     ptArrow[6].x = ptCenter.x+1;
  326.     ptArrow[6].y = ptCenter.y-4;
  327.  
  328.     CBrush brBlack(RGB(0, 0, 0));
  329.       CBrush * pOldBrush = pDC->SelectObject(&brBlack);
  330.     pDC->Polygon(ptArrow, 7);  
  331.     pDC->MoveTo(ptCenter.x - 3, ptCenter.y + 4);
  332.     pDC->LineTo(ptCenter.x + 4, ptCenter.y + 4);
  333.       pDC->SelectObject(pOldBrush);
  334.     brBlack.DeleteObject();
  335. }
  336.  
  337. void CButtonCombo::OnEnable(BOOL bEnable) 
  338. {
  339.     CWnd::OnEnable(bEnable);
  340.     
  341.     Invalidate(FALSE);
  342.     UpdateWindow();
  343. }
  344.  
  345. /////////////////////////////////////////////////////////////////////////////
  346. // CWndCombo
  347.  
  348. CWndCombo::CWndCombo()
  349. {         
  350.     m_rgbBkColor     = GetSysColor(COLOR_BTNFACE);
  351.     m_iSelectedItem    = 0;
  352.     m_iNbImages        = -1; 
  353. }
  354.  
  355. CWndCombo::~CWndCombo()
  356. {       
  357.     if (m_bmImage.m_hObject)
  358.         m_bmImage.DeleteObject();
  359.     if (m_font.m_hObject)
  360.         m_font.DeleteObject();
  361. }
  362.  
  363. BEGIN_MESSAGE_MAP(CWndCombo, CWnd)
  364.     //{{AFX_MSG_MAP(CWndCombo)
  365.     ON_WM_LBUTTONDOWN()
  366.     ON_WM_LBUTTONUP()
  367.     ON_WM_MOUSEMOVE()
  368.     ON_WM_PAINT()
  369.     ON_WM_KILLFOCUS()
  370.     //}}AFX_MSG_MAP
  371. END_MESSAGE_MAP()
  372.  
  373.  
  374. /////////////////////////////////////////////////////////////////////////////
  375. // CWndCombo message handlers
  376.  
  377. BOOL CWndCombo::Create(int x, int y, CSize sizeGrid, CSize sizeBtn, CWnd * pParent, CString sTextItems)
  378. {
  379.     ASSERT(pParent);  
  380.     if (m_hWnd)    return FALSE;
  381.         
  382.     m_sizeGrid    = sizeGrid;
  383.     m_sizeBtn     = sizeBtn;
  384.     m_pParent     = pParent;
  385.     m_iNbImages = m_sizeGrid.cx * m_sizeGrid.cy;
  386.     
  387.     CSize sizeText = UpdateTextItems(sTextItems);
  388.     int iWidth    = (m_sizeGrid.cx * m_sizeBtn.cx) + (m_sizeGrid.cx - 1) + 4; 
  389.     int iRow = (sizeText.cy > 0) ? 0 : 1;
  390.     int iHeight = (m_sizeGrid.cy * m_sizeBtn.cy) + (m_sizeGrid.cy - iRow) + 4 + sizeText.cy; 
  391.     CRect rect(x, y, x + iWidth, y + iHeight);
  392.  
  393.     return CWnd::CreateEx(0, NULL, NULL, WS_CHILD | WS_POPUP, rect.left, rect.top, 
  394.                             rect.Width(), rect.Height(), m_pParent->m_hWnd, 0);
  395. }
  396.  
  397. BOOL CWndCombo::Create(int x, int y, CSize sizeGrid, UINT nBitmapIDResource, int iNbImages, 
  398.                         CWnd * pParent, CString sTextItems)
  399. {
  400.     ASSERT(pParent);  
  401.     if (m_hWnd)    return FALSE;
  402.     m_pParent     = pParent;
  403.     m_sizeGrid    = sizeGrid;
  404.     m_iNbImages    = iNbImages;
  405.     
  406.     m_bmImage.LoadBitmap(nBitmapIDResource);    
  407.  
  408.     BITMAP bm;
  409.     m_bmImage.GetObject( sizeof( bm ), &bm );
  410.     m_sizeBtn     = CSize(bm.bmWidth / m_iNbImages, bm.bmHeight);
  411.  
  412.     CSize sizeText = UpdateTextItems(sTextItems);
  413.     int iWidth    = (m_sizeGrid.cx * (m_sizeBtn.cx + 8)) + (m_sizeGrid.cx - 1) + 4; 
  414.     int iRow = (sizeText.cy > 0) ? 0 : 1;
  415.     int iHeight = (m_sizeGrid.cy * (m_sizeBtn.cy + 8)) + (m_sizeGrid.cy - iRow) + 4 + sizeText.cy; 
  416.     CRect rect(x, y, x + iWidth, y + iHeight);
  417.  
  418.     return CWnd::CreateEx(0, NULL, NULL, WS_CHILD | WS_POPUP, rect.left, rect.top, 
  419.                             rect.Width(), rect.Height(), m_pParent->m_hWnd, 0);
  420. }
  421.  
  422. CSize CWndCombo::UpdateTextItems(CString sTextItems)
  423. {
  424.     if (sTextItems.IsEmpty())
  425.         return CSize(0, 0);
  426.     int i;
  427.     m_lstTextItems.RemoveAll;
  428.     while ((i = sTextItems.Find(';')) != -1)
  429.     {
  430.         m_lstTextItems.Add(sTextItems.Left(i));
  431.         sTextItems = sTextItems.Mid(i+1);
  432.     }
  433.     m_lstTextItems.Add(sTextItems);
  434.  
  435.     CDC *pDC = GetDC();
  436.     LOGFONT logfont;
  437.     memset(&logfont, 0, sizeof(logfont));
  438.     // 8 point height Sans Serif font
  439.     logfont.lfHeight = -MulDiv(8, pDC->GetDeviceCaps(LOGPIXELSY), 72);
  440.     logfont.lfWeight = FW_NORMAL;
  441.     logfont.lfPitchAndFamily = VARIABLE_PITCH | FF_SWISS;
  442.     static char BASED_CODE szFaceName[] = "MS Sans Serif";
  443.     lstrcpy(logfont.lfFaceName, szFaceName);
  444.     m_font.CreateFontIndirect(&logfont);
  445.     CSize sizeText = pDC->GetTextExtent("Test", 4);
  446.     ReleaseDC(pDC);    
  447.     return sizeText;
  448. }
  449.  
  450. void CWndCombo::OnLButtonDown(UINT nFlags, CPoint point) 
  451. {
  452.     CWnd::OnLButtonDown(nFlags, point);
  453. }
  454.  
  455. void CWndCombo::OnLButtonUp(UINT nFlags, CPoint point) 
  456. {
  457.     if (m_iSelectedItem != -1)
  458.     {        
  459.         if (m_bmImage.m_hObject)
  460.             ((CButtonCombo*)m_pParent)->OnItemSelected(m_iSelectedItem, m_iSelectedItem);
  461.         else
  462.             ((CButtonCombo*)m_pParent)->OnItemSelected(GetColor(m_iSelectedItem), m_iSelectedItem);
  463.     }
  464.     m_iSelectedItem    = -1;
  465.     ShowWindow(SW_HIDE);
  466.  
  467.     CWnd::OnLButtonUp(nFlags, point);
  468. }
  469.  
  470. void CWndCombo::OnMouseMove(UINT nFlags, CPoint point) 
  471. {
  472.     CRect rcItem;
  473.     int iItem = GetItem(point, &rcItem);
  474.     if (iItem != -1)
  475.         m_iSelectedItem = iItem;    
  476.     Invalidate();
  477.     UpdateWindow();
  478.                                         
  479.     CWnd::OnMouseMove(nFlags, point);
  480. }
  481.  
  482. int CWndCombo::GetItem(CPoint point, CRect * pRect)
  483. {
  484.     ASSERT(pRect);
  485.     pRect->SetRectEmpty();
  486.  
  487.     CRect rect;
  488.     GetClientRect(rect);
  489.  
  490.     if (!rect.PtInRect(point))
  491.         return -1;    
  492.  
  493.     int iTop = rect.top + 2, iLeft, iItem;
  494.     CRect rcBtn;
  495.         
  496.     for (int i = 0; i < m_sizeGrid.cy; i++)
  497.     {   
  498.         rcBtn.top         = iTop;
  499.         if (m_bmImage.m_hObject)
  500.             rcBtn.bottom    = rcBtn.top + m_sizeBtn.cy + 8;
  501.         else
  502.             rcBtn.bottom    = rcBtn.top + m_sizeBtn.cy;
  503.         iTop             = rcBtn.bottom + 2;
  504.         if (point.y > rcBtn.bottom)
  505.             continue;
  506.         else        
  507.         {
  508.             iLeft = rect.left + 2;
  509.             for (int j = 0; j < m_sizeGrid.cx; j++)
  510.             {        
  511.                 rcBtn.left    = iLeft;
  512.                 if (m_bmImage.m_hObject)
  513.                     rcBtn.right = rcBtn.left + m_sizeBtn.cx + 8;
  514.                 else
  515.                     rcBtn.right = rcBtn.left + m_sizeBtn.cx;
  516.                 iLeft = rcBtn.right + 2;
  517.                 if (point.x > rcBtn.right)
  518.                     continue;             
  519.                 else              
  520.                 {
  521.                     *pRect = rcBtn;      
  522.                     iItem = (i * m_sizeGrid.cx) + j;
  523.                     if (iItem < m_iNbImages)
  524.                         return iItem;
  525.                     else
  526.                         return -1;
  527.                 }
  528.             }                   
  529.         }
  530.     } 
  531.     return -1;            
  532. }
  533.  
  534. void CWndCombo::DrawBtnFace(CDC * pDC, CRect rect, long lItem)
  535. {            
  536.     if (lItem == -1)
  537.         return;
  538.     if (m_bmImage.m_hObject)
  539.     {                       
  540.         CPoint ptCenter(rect.left + (rect.Width() / 2), rect.top + (rect.Height() / 2));
  541.         CPoint ptOffSet(ptCenter.x - (m_sizeBtn.cx / 2), ptCenter.y - (m_sizeBtn.cy / 2));
  542.  
  543.         CDC memDC;
  544.         memDC.CreateCompatibleDC(pDC);
  545.         CBitmap * pOldBitmap = memDC.SelectObject(&m_bmImage);
  546.  
  547.         pDC->BitBlt(ptOffSet.x, ptOffSet.y, m_sizeBtn.cx, m_sizeBtn.cy, &memDC, 
  548.                     (int) lItem * m_sizeBtn.cx, 0, SRCCOPY);
  549.         memDC.SelectObject(pOldBitmap);
  550.     }
  551.     else 
  552.     {
  553.         CBrush brRect(lItem);
  554.         pDC->FillRect(CRect(rect.left+2, rect.top+2, rect.right-3, rect.bottom-2), &brRect);
  555.         brRect.DeleteObject();
  556.     }    
  557. }
  558.  
  559. void CWndCombo::OnPaint() 
  560. {
  561.     CPaintDC dc(this); // device context for painting
  562.     
  563.     CRect rect;
  564.     GetClientRect(&rect);
  565.  
  566.     CDC memDC;
  567.     CBitmap bitmap;
  568.     bitmap.CreateCompatibleBitmap(&dc, rect.Width(), rect.Height());
  569.     memDC.CreateCompatibleDC(&dc);
  570.     CBitmap * pOldBitmap = memDC.SelectObject(&bitmap);
  571.  
  572.     CBrush brBack(m_rgbBkColor), brBlack(RGB(0, 0, 0));
  573.     memDC.FillRect(rect, &brBack);
  574.     Draw3dRect(&memDC, &rect, GetSysColor(COLOR_BTNHIGHLIGHT), GetSysColor(COLOR_WINDOWFRAME)); 
  575.  
  576.     int iTop = rect.top + 2, iLeft, iItem;
  577.     CRect rcBtn;
  578.     
  579.     for (int i = 0; i < m_sizeGrid.cy; i++)
  580.     {        
  581.         rcBtn.top         = iTop;
  582.         if (m_bmImage.m_hObject)
  583.             rcBtn.bottom    = rcBtn.top + m_sizeBtn.cy + 8;
  584.         else
  585.             rcBtn.bottom    = rcBtn.top + m_sizeBtn.cy;
  586.         iLeft             = rect.left + 2;
  587.         for (int j = 0; j < m_sizeGrid.cx; j++)
  588.         {
  589.             rcBtn.left    = iLeft;
  590.             iItem         = (i * m_sizeGrid.cx) + j; 
  591.  
  592.             if (m_bmImage.m_hObject)
  593.             {                       
  594.                 rcBtn.right = rcBtn.left + m_sizeBtn.cx + 8;
  595.                 if (iItem < m_iNbImages)
  596.                 {
  597.                     CPoint ptCenter(rcBtn.left + (rcBtn.Width() / 2), rcBtn.top + (rcBtn.Height() / 2));
  598.                     CPoint ptOffSet(ptCenter.x - (m_sizeBtn.cx / 2), ptCenter.y - (m_sizeBtn.cy / 2));
  599.  
  600.                     CDC tmpDC;
  601.                     tmpDC.CreateCompatibleDC(&dc);
  602.                     CBitmap * pOldBitmap = tmpDC.SelectObject(&m_bmImage);
  603.                     memDC.BitBlt(ptOffSet.x, ptOffSet.y, m_sizeBtn.cx, m_sizeBtn.cy,
  604.                             &tmpDC, iItem * m_sizeBtn.cx, 0, SRCCOPY);
  605.                     tmpDC.SelectObject(pOldBitmap);
  606.                     Draw3dRect(&memDC, &rcBtn, GetSysColor(COLOR_BTNSHADOW), GetSysColor(COLOR_BTNHIGHLIGHT)); 
  607.                 }
  608.             }
  609.             else
  610.             {
  611.                 rcBtn.right = rcBtn.left + m_sizeBtn.cx;
  612.                 Draw3dRect(&memDC, &rcBtn, GetSysColor(COLOR_BTNSHADOW), GetSysColor(COLOR_BTNHIGHLIGHT)); 
  613.                 CBrush brRect(GetColor(iItem));
  614.                 memDC.FillRect(CRect(rcBtn.left + 1, rcBtn.top + 1, rcBtn.right-1, rcBtn.bottom-1), &brRect);
  615.                 brRect.DeleteObject();
  616.             }
  617.             if (iItem == m_iSelectedItem)
  618.                 memDC.FrameRect(CRect(rcBtn.left-1, rcBtn.top-1, rcBtn.right+1, rcBtn.bottom+1), &brBlack);
  619.             iLeft = rcBtn.right + 1;
  620.         }
  621.         iTop = rcBtn.bottom + 1;
  622.     }
  623.  
  624.     if (m_lstTextItems.GetSize() > 0)
  625.     {                  
  626.         CRect rcText(rect.left + 2, iTop, rect.right - 2, rect.bottom - 2);
  627.         CBrush brWhite(RGB(255, 255, 255));
  628.         memDC.FillRect(rcText, &brWhite);
  629.         Draw3dRect(&memDC, &rcText, GetSysColor(COLOR_BTNSHADOW), GetSysColor(COLOR_BTNHIGHLIGHT)); 
  630.         brWhite.DeleteObject();
  631.         if (m_iSelectedItem != -1)
  632.         {   
  633.             CFont * pOldFont = memDC.SelectObject(&m_font);
  634.             memDC.DrawText(m_lstTextItems[m_iSelectedItem], -1, rcText, DT_SINGLELINE | DT_VCENTER | DT_CENTER);
  635.             memDC.SelectObject(pOldFont);
  636.         }
  637.     }
  638.  
  639.     dc.BitBlt(rect.left, rect.top, rect.Width(), rect.Height(), &memDC, rect.left, rect.top, SRCCOPY);
  640.     memDC.SelectObject(pOldBitmap);
  641.  
  642.     brBack.DeleteObject();
  643.     brBlack.DeleteObject();
  644.     bitmap.DeleteObject();
  645. }
  646.  
  647. void CWndCombo::OnKillFocus(CWnd* pNewWnd) 
  648. {
  649.     CWnd::OnKillFocus(pNewWnd);
  650.  
  651.     POINT pt;    
  652.     GetCursorPos(&pt);
  653.     CRect rect;
  654.     m_pParent->GetWindowRect(rect);
  655.     if (!rect.PtInRect(pt))
  656.     {
  657.         ShowWindow(SW_HIDE);
  658.         CButtonCombo * pBtnColor = (CButtonCombo*)m_pParent;
  659.         pBtnColor->UnpressRightButton();
  660.     }
  661. }
  662.  
  663. COLORREF CWndCombo::GetColor(int iIndex)
  664. {
  665.     const int  NUMENTRIES = 255;
  666.     PALETTEENTRY palette[NUMENTRIES];           
  667.     HDC hDC = ::GetDC(NULL);
  668.  
  669.     UINT uResult = GetSystemPaletteEntries(hDC, 0, NUMENTRIES, palette);        
  670.     ::ReleaseDC(NULL, hDC);
  671.     return RGB(palette[iIndex].peRed, palette[iIndex].peGreen, palette[iIndex].peBlue);
  672. }    
  673.  
  674.