home *** CD-ROM | disk | FTP | other *** search
/ Softwarová Záchrana 3 / Softwarova-zachrana-3.bin / TaskSwitchXP / TaskSwitchXP_1.0.26.exe / Source / ConfigTsXP / ownerdrawXp.cpp < prev    next >
C/C++ Source or Header  |  2004-08-30  |  11KB  |  383 lines

  1. // ownerdrawXp.cpp
  2.  
  3. #include "stdafx.h"
  4. #include "main.h"
  5. #include "ownerdrawXp.h"
  6.  
  7. //-----------------------------------------------------------------
  8.  
  9. LRESULT CALLBACK _UxButtonProc(HWND, UINT, WPARAM, LPARAM);
  10. BOOL LoadUxThemeDll();
  11. void FreeUxThemeDll();
  12.  
  13.  
  14. typedef HTHEME (WINAPI *OPENTHEMEDATA)(HWND, LPCWSTR);
  15. typedef HRESULT (WINAPI *CLOSETHEMEDATA)(HTHEME);
  16. typedef BOOL (WINAPI *ISTHEMEBACKGROUNDPARTIALLYTRANSPARENT)(HTHEME, int, int);
  17. typedef HRESULT (WINAPI *DRAWTHEMEPARENTBACKGROUND)(HWND, HDC, RECT*);
  18. typedef HRESULT (WINAPI *DRAWTHEMEBACKGROUND)(HTHEME, HDC, int, int, const RECT*, const RECT*);
  19.  
  20. OPENTHEMEDATA _pfnOpenThemeData                                                    = NULL;
  21. CLOSETHEMEDATA _pfnCloseThemeData                                                = NULL;
  22. ISTHEMEBACKGROUNDPARTIALLYTRANSPARENT _pfnIsThemeBackgroundPartiallyTransparent    = NULL;
  23. DRAWTHEMEPARENTBACKGROUND _pfnDrawThemeParentBackground                            = NULL;
  24. DRAWTHEMEBACKGROUND _pfnDrawThemeBackground                                        = NULL;
  25. ENABLETHEMEDIALOGTEXTURE g_pfnEnableThemeDialogTexture                            = NULL;
  26.  
  27. //-----------------------------------------------------------------
  28.  
  29. HINSTANCE _hinstUxThemeDll        = NULL;
  30. HTHEME _hthemeBtn                = NULL;
  31. WNDPROC _wpBtnProc                = NULL;
  32.  
  33. //-----------------------------------------------------------------
  34.  
  35. BOOL LoadUxThemeDll(HWND hwnd) {
  36.  
  37.     _ASSERT(_hinstUxThemeDll == NULL);
  38.  
  39.     _hinstUxThemeDll = LoadLibrary(L"UxTheme.dll");
  40.  
  41.     if (_hinstUxThemeDll) {
  42.  
  43.         _pfnOpenThemeData = (OPENTHEMEDATA) \
  44.             GetProcAddress(_hinstUxThemeDll, "OpenThemeData");
  45.         if (_pfnOpenThemeData) {
  46.             _hthemeBtn = (_pfnOpenThemeData)(hwnd, L"Button");
  47.  
  48.             _pfnCloseThemeData = (CLOSETHEMEDATA) \
  49.                 GetProcAddress(_hinstUxThemeDll, "CloseThemeData");
  50.             _pfnIsThemeBackgroundPartiallyTransparent = (ISTHEMEBACKGROUNDPARTIALLYTRANSPARENT) \
  51.                 GetProcAddress(_hinstUxThemeDll, "IsThemeBackgroundPartiallyTransparent");
  52.             _pfnDrawThemeParentBackground = (DRAWTHEMEPARENTBACKGROUND) \
  53.                 GetProcAddress(_hinstUxThemeDll, "DrawThemeParentBackground");
  54.             _pfnDrawThemeBackground = (DRAWTHEMEBACKGROUND) \
  55.                 GetProcAddress(_hinstUxThemeDll, "DrawThemeBackground");
  56.             g_pfnEnableThemeDialogTexture = (ENABLETHEMEDIALOGTEXTURE) \
  57.                 GetProcAddress(_hinstUxThemeDll, "EnableThemeDialogTexture");
  58.         }
  59.  
  60.         if (!_pfnOpenThemeData || !_pfnCloseThemeData ||  
  61.             !_pfnIsThemeBackgroundPartiallyTransparent ||
  62.             !_pfnDrawThemeParentBackground || !_pfnDrawThemeBackground ||
  63.             !g_pfnEnableThemeDialogTexture || !_hthemeBtn) {
  64.                 FreeUxThemeDll();
  65.             }
  66.     }
  67.     return(_hinstUxThemeDll != NULL);
  68. }
  69.  
  70. //-----------------------------------------------------------------
  71.  
  72. void FreeUxThemeDll() {
  73.  
  74.     if (_hinstUxThemeDll) {
  75.         if (_hthemeBtn) {
  76.             (_pfnCloseThemeData)(_hthemeBtn);
  77.             _hthemeBtn = NULL;
  78.         }
  79.         FreeLibrary(_hinstUxThemeDll);
  80.         _hinstUxThemeDll = NULL;
  81.     }
  82. }
  83.  
  84. //-----------------------------------------------------------------
  85.  
  86. void InitOwnerDrawCtrls(HWND hwnd) {
  87.  
  88.     WNDCLASSEX wcex;
  89.     wcex.cbSize = sizeof(WNDCLASSEX);
  90.     GetClassInfoEx(g_hinstExe, WC_BUTTON, &wcex);
  91.     _wpBtnProc = wcex.lpfnWndProc;
  92.     
  93.     LoadUxThemeDll(hwnd);
  94. }
  95.  
  96. //-----------------------------------------------------------------
  97.  
  98. void UxThemeChanged(HWND hwnd) {
  99.  
  100.     if (_hthemeBtn) {
  101.         (_pfnCloseThemeData)(_hthemeBtn);
  102.         _hthemeBtn = NULL;
  103.     }
  104.  
  105.     if (!_hinstUxThemeDll)
  106.         LoadUxThemeDll(hwnd);
  107.     else {
  108.         if (_hinstUxThemeDll) {
  109.             _hthemeBtn = (_pfnOpenThemeData)(hwnd, L"Button");
  110.         }
  111.     }
  112. }
  113.  
  114. //-----------------------------------------------------------------
  115. //-----------------------------------------------------------------
  116.  
  117. typedef struct {
  118.     DWORD dwType;
  119.     LPARAM lParam1;
  120.     LPARAM lParam2;
  121.     BOOL fMouseOverBtn;
  122. } UXBUTTON_DATA, *PUXBUTTON_DATA;
  123.  
  124. #define UXBTN_ICON16                1
  125. #define UXBTN_COLOR                    2
  126.  
  127. //-----------------------------------------------------------------
  128.  
  129. void SubClassUxIconButton(HWND hwndBtn, UINT idIcon, UINT idIconDisabled) {
  130.  
  131.     SetWindowLong(hwndBtn, GWL_STYLE, 
  132.         GetWindowLong(hwndBtn, GWL_STYLE) | BS_OWNERDRAW);
  133.  
  134.     PUXBUTTON_DATA puxbd = new UXBUTTON_DATA;
  135.  
  136.     puxbd->dwType = UXBTN_ICON16;
  137.     puxbd->fMouseOverBtn = FALSE;
  138.     if (idIcon) {
  139.         puxbd->lParam1 = (LPARAM)LoadIcon(g_hinstExe, MAKEINTRESOURCE(idIcon));
  140.     } else puxbd->lParam1 = NULL;
  141.     
  142.     if (idIconDisabled) {
  143.         puxbd->lParam2 = (LPARAM)LoadIcon(g_hinstExe, MAKEINTRESOURCE(idIconDisabled));
  144.     } else puxbd->lParam2 = NULL;
  145.  
  146.     SetWindowLongPtr(hwndBtn, GWLP_USERDATA, (LONG)(LONG_PTR)puxbd);
  147.     SetWindowLongPtr(hwndBtn, GWLP_WNDPROC, (LONG)(LONG_PTR)(WNDPROC)_UxButtonProc);
  148. }
  149.  
  150. void SubClassUxColorButton(HWND hwndBtn, COLORREF cr) {
  151.  
  152.     SetWindowLong(hwndBtn, GWL_STYLE, 
  153.         GetWindowLong(hwndBtn, GWL_STYLE) | BS_OWNERDRAW);
  154.  
  155.     PUXBUTTON_DATA puxbd = new UXBUTTON_DATA;
  156.  
  157.     puxbd->dwType = UXBTN_COLOR;
  158.     puxbd->fMouseOverBtn = FALSE;
  159.     puxbd->lParam1 = (LPARAM)cr;
  160.     puxbd->lParam2 = NULL;
  161.     
  162.     SetWindowLongPtr(hwndBtn, GWLP_USERDATA, (LONG)(LONG_PTR)puxbd);
  163.     SetWindowLongPtr(hwndBtn, GWLP_WNDPROC, (LONG)(LONG_PTR)(WNDPROC)_UxButtonProc);
  164. }
  165.  
  166. //-----------------------------------------------------------------
  167.  
  168. void DrawUxButton(const DRAWITEMSTRUCT *pdi) {
  169.  
  170.     PUXBUTTON_DATA puxbd = (PUXBUTTON_DATA)(LONG_PTR)\
  171.         GetWindowLongPtr(pdi->hwndItem, GWLP_USERDATA);
  172.     _ASSERT(puxbd);
  173.  
  174.     RECT itemRect = pdi->rcItem;
  175.     SetBkMode(pdi->hDC, TRANSPARENT);
  176.  
  177.     if (_hthemeBtn) { // XP style
  178.  
  179.         _ASSERT(_pfnIsThemeBackgroundPartiallyTransparent &&
  180.             _pfnDrawThemeParentBackground && _pfnDrawThemeBackground);
  181.  
  182.         int iStateId = PBS_NORMAL;
  183.  
  184.         if (pdi->itemState & ODS_DISABLED)
  185.             iStateId = PBS_DISABLED;
  186.         else if (pdi->itemState & ODS_SELECTED)
  187.             iStateId = PBS_PRESSED;
  188.         else if (puxbd->fMouseOverBtn)
  189.             iStateId = PBS_HOT;
  190.         else if (pdi->itemState & ODS_FOCUS)
  191.             iStateId = PBS_DEFAULTED;
  192.  
  193.         if ((_pfnIsThemeBackgroundPartiallyTransparent)(_hthemeBtn, BP_PUSHBUTTON, iStateId))
  194.             (_pfnDrawThemeParentBackground)(pdi->hwndItem, pdi->hDC, &itemRect);
  195.         (_pfnDrawThemeBackground)(_hthemeBtn, pdi->hDC, BP_PUSHBUTTON, iStateId, &itemRect, NULL);
  196.  
  197.     } else {
  198.  
  199.         if (pdi->itemState & ODS_FOCUS) {
  200.             HBRUSH hbr = CreateSolidBrush(RGB(0,0,0));
  201.             FrameRect(pdi->hDC, &itemRect, hbr);
  202.             InflateRect(&itemRect, -1, -1);
  203.             DeleteObject(hbr);
  204.         }
  205.  
  206.         FillRect(pdi->hDC, &itemRect, GetSysColorBrush(COLOR_BTNFACE));
  207.         
  208.         if (pdi->itemState & ODS_SELECTED) { // draw pressed button
  209.             HBRUSH hbrBtnShadow = CreateSolidBrush(GetSysColor(COLOR_BTNSHADOW));
  210.             FrameRect(pdi->hDC, &itemRect, hbrBtnShadow);
  211.             DeleteObject(hbrBtnShadow);
  212.         } else { // draw non pressed button
  213.             DrawFrameControl(pdi->hDC, &itemRect, DFC_BUTTON, 
  214.                 (puxbd->fMouseOverBtn ? DFCS_BUTTONPUSH | DFCS_HOT : DFCS_BUTTONPUSH));
  215.             /* | ((pdi->itemState & ODS_SELECTED) ? DFCS_PUSHED : 0)*/
  216.         }
  217.     }
  218.  
  219.     switch (puxbd->dwType) {
  220.     
  221.         case UXBTN_ICON16: {
  222.  
  223.             const int cxDlgUnit = LOWORD(GetDialogBaseUnits()),
  224.                 cxSmIcon = 16,
  225.                 cySmIcon = 16;
  226.             int x, y;
  227.             int xIcon = -1;
  228.  
  229.             WCHAR szText[1024];
  230.             if (GetWindowText(pdi->hwndItem, szText, SIZEOF_ARRAY(szText))) {
  231.                 SIZE sizeText;
  232.                 int n = 0;
  233.                 x = pdi->rcItem.left + cxSmIcon + cxDlgUnit + 6;
  234.                 if (pdi->rcItem.right - x - 6 > 0) {
  235.                     if (GetTextExtentExPoint(pdi->hDC, szText, lstrlen(szText), 
  236.                         pdi->rcItem.right - x - 6, &n, NULL, &sizeText)) {
  237.                         if (n > 0 && szText[n] != L'\0') {
  238.                             szText[n--] = L'\0';
  239.                             for (int i = 0; i < 3; i++) {
  240.                                 if (n < 0) break;
  241.                                 szText[n--] = L'.';
  242.                             }
  243.                         }
  244.                         sizeText.cx = min(sizeText.cx, pdi->rcItem.right - x - 6);
  245.                         x = x + (pdi->rcItem.right - x - 6 - sizeText.cx) / 2;
  246.                         xIcon = x - cxDlgUnit - cxSmIcon;
  247.                         y = pdi->rcItem.top + (pdi->rcItem.bottom - pdi->rcItem.top - sizeText.cy) / 2;
  248.                         if (pdi->itemState & ODS_SELECTED && !_hthemeBtn) {
  249.                             x++;
  250.                             y++;
  251.                         }
  252.                         DrawState(pdi->hDC, NULL, NULL, (LPARAM)szText, 0, 
  253.                             x, y, sizeText.cx, sizeText.cy, (pdi->itemState & ODS_DISABLED) 
  254.                             ? DST_PREFIXTEXT | DSS_DISABLED : DST_PREFIXTEXT | DSS_NORMAL);
  255.                     }
  256.                 }
  257.             }
  258.             HICON hIcon = (pdi->itemState & ODS_DISABLED) 
  259.                 ? (HICON)puxbd->lParam2 : (HICON)puxbd->lParam1;
  260.             if (hIcon) {
  261.                 if (xIcon == -1) {
  262.                     xIcon = pdi->rcItem.left + (pdi->rcItem.right - pdi->rcItem.left - cxSmIcon) / 2;
  263.                 }
  264.                 y = pdi->rcItem.top + (pdi->rcItem.bottom - pdi->rcItem.top - cySmIcon) / 2;
  265.  
  266.                 if (pdi->itemState & ODS_SELECTED && !_hthemeBtn) {
  267.                     xIcon++;
  268.                     y++;
  269.                 }
  270.                 DrawIconEx(pdi->hDC, xIcon, y, 
  271.                     hIcon, cxSmIcon, cySmIcon, 0, NULL, DI_NORMAL);
  272.             }
  273.             break;
  274.                            }
  275.  
  276.         case UXBTN_COLOR: {
  277.  
  278.             RECT rc = pdi->rcItem;
  279.             InflateRect(&rc, -4, -4);
  280.             if (pdi->itemState & ODS_SELECTED && !_hthemeBtn)
  281.                 OffsetRect(&rc, 1, 1);
  282.  
  283.             if (!(pdi->itemState & ODS_DISABLED)) {
  284.  
  285.                 HBRUSH hbr = CreateSolidBrush((COLORREF)puxbd->lParam1);
  286.                 FillRect(pdi->hDC, &rc, hbr);
  287.                 DeleteObject(hbr);
  288.  
  289.                 FrameRect(pdi->hDC, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH));
  290.             }
  291.             break;
  292.                           }
  293.         default:
  294.             _ASSERT(FALSE);
  295.     }
  296.  
  297.     if (pdi->itemState & ODS_FOCUS && !(pdi->itemState & ODS_NOFOCUSRECT)) {
  298.         InflateRect(&itemRect, -3, -3);
  299.         DrawFocusRect(pdi->hDC, &itemRect);
  300.     }
  301. }
  302.  
  303. //-----------------------------------------------------------------
  304.  
  305. LRESULT CALLBACK _UxButtonProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
  306.  
  307.     switch (uMsg) {
  308.  
  309.         case WM_MOUSEMOVE: {
  310.             PUXBUTTON_DATA puxbd = (PUXBUTTON_DATA)(LONG_PTR)\
  311.                 GetWindowLongPtr(hwnd, GWLP_USERDATA);
  312.             _ASSERT(puxbd);
  313.  
  314.             if (!puxbd->fMouseOverBtn) {
  315.                 TRACKMOUSEEVENT tme;
  316.                 tme.cbSize      = sizeof(tme);
  317.                 tme.dwFlags     = TME_LEAVE;
  318.                 tme.hwndTrack   = hwnd;
  319.                 tme.dwHoverTime = 0;
  320.  
  321.                 if (TrackMouseEvent(&tme)) {
  322.                     puxbd->fMouseOverBtn = TRUE;
  323.                     InvalidateRect(hwnd, NULL, TRUE);
  324.                 }
  325.             }
  326.             break;
  327.                            }
  328.  
  329.         case WM_MOUSELEAVE: {
  330.             PUXBUTTON_DATA puxbd = (PUXBUTTON_DATA)(LONG_PTR)\
  331.                 GetWindowLongPtr(hwnd, GWLP_USERDATA);
  332.             _ASSERT(puxbd);
  333.             puxbd->fMouseOverBtn = FALSE;
  334.             InvalidateRect(hwnd, NULL, TRUE);
  335.             break;
  336.                             }
  337.  
  338.         /*case WM_SETCURSOR: {
  339.             HCURSOR hCursor = LoadCursor(NULL, IDC_HAND);
  340.             if (!hCursor)
  341.                 hCursor = LoadCursor(NULL, IDC_ARROW);
  342.             SetCursor(hCursor);
  343.             return(TRUE);
  344.             //break;
  345.                            }*/
  346.         
  347.         case WM_LBUTTONDBLCLK:
  348.             PostMessage(hwnd, WM_LBUTTONDOWN, wParam, lParam);
  349.             return(0);
  350.  
  351.         case WM_DESTROY: {
  352.             PUXBUTTON_DATA puxbd = (PUXBUTTON_DATA)(LONG_PTR)\
  353.                 GetWindowLongPtr(hwnd, GWLP_USERDATA);
  354.             _ASSERT(puxbd);
  355.             delete puxbd;
  356.             break;
  357.                          }
  358.     }
  359.     return(CallWindowProc(_wpBtnProc, hwnd, uMsg, wParam, lParam));
  360. }
  361.  
  362. //-----------------------------------------------------------------
  363.  
  364. void SetUxButtonColor(HWND hwndBtn, COLORREF cr) {
  365.     PUXBUTTON_DATA puxbd = (PUXBUTTON_DATA)(LONG_PTR)\
  366.         GetWindowLongPtr(hwndBtn, GWLP_USERDATA);
  367.     _ASSERT(puxbd);
  368.     _ASSERT(puxbd->dwType == UXBTN_COLOR);
  369.     puxbd->lParam1 = (LPARAM)cr;
  370.     InvalidateRect(hwndBtn, NULL, TRUE);
  371. }
  372.  
  373. COLORREF GetUxButtonColor(HWND hwndBtn) {
  374.     PUXBUTTON_DATA puxbd = (PUXBUTTON_DATA)(LONG_PTR)\
  375.         GetWindowLongPtr(hwndBtn, GWLP_USERDATA);
  376.     _ASSERT(puxbd);
  377.     _ASSERT(puxbd->dwType == UXBTN_COLOR);
  378.     return((COLORREF)puxbd->lParam1);
  379. }
  380.  
  381. //-----------------------------------------------------------------
  382. //-----------------------------------------------------------------
  383.