home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 2001 June / VPR0106A.BIN / OLS / TCL228 / TCL228.lzh / DLLSRC.lzh / startbtn.c < prev    next >
C/C++ Source or Header  |  1999-09-18  |  15KB  |  561 lines

  1. /*-------------------------------------------
  2.   startbtn.c
  3.     customize start button
  4.     Kazubon 1997-1999
  5. ---------------------------------------------*/
  6.  
  7. #include "tcdll.h"
  8.  
  9. extern HANDLE hmod;
  10.  
  11. /*------------------------------------------------
  12.   globals
  13. --------------------------------------------------*/
  14. LRESULT CALLBACK WndProcStart(HWND, UINT, WPARAM, LPARAM);
  15. LRESULT CALLBACK WndProcTask(HWND, UINT, WPARAM, LPARAM);
  16. WNDPROC oldWndProcStart = NULL, oldWndProcTask = NULL;
  17. HWND hwndStart = NULL, hwndTask = NULL, hwndTray = NULL;
  18. HBITMAP hbmpstart = NULL, hbmpstartold = NULL;
  19. int wStart = -1, hStart = -1;
  20. static BOOL bCustStartButton = FALSE;
  21. static BOOL bHideStartButton = FALSE;
  22. static BOOL bStartButtonFlat = FALSE;
  23. static BOOL bCursorOnStartButton = FALSE;
  24.  
  25. static void OnPaint(HWND hwnd, HDC hdc);
  26. static void SetStartButtonBmp(void);
  27. static void SetTaskWinPos(void);
  28.  
  29. /*--------------------------------------------------
  30.    initialize
  31. ----------------------------------------------------*/
  32. void SetStartButton(HWND hwndClock)
  33. {
  34.     HANDLE hwnd;
  35.     char classname[80];
  36.     
  37.     EndStartButton();
  38.     
  39.     // "button"と"MSTaskSwWClass"のウィンドウハンドルを得る
  40.     hwndStart = hwndTask = NULL;
  41.     hwndTray = GetParent(hwndClock); // TrayNotifyWnd
  42.     hwnd = GetParent(hwndTray);      // Shell_TrayWnd
  43.     if(hwnd == NULL) return;
  44.     hwnd = GetWindow(hwnd, GW_CHILD);
  45.     while(hwnd)
  46.     {
  47.         GetClassName(hwnd, classname, 80);
  48.         if(lstrcmpi(classname, "Button") == 0)
  49.             hwndStart = hwnd;
  50.         else if(lstrcmpi(classname, "MSTaskSwWClass") == 0)
  51.             hwndTask = hwnd;
  52.         else if(lstrcmpi(classname, "ReBarWindow32") == 0)
  53.             hwndTask = hwnd;
  54.         hwnd = GetWindow(hwnd, GW_HWNDNEXT);
  55.     }
  56.     if(hwndStart == NULL || hwndTask == NULL)
  57.     {
  58.         hwndStart = hwndTask = NULL; return;
  59.     }
  60.     
  61.     bCustStartButton = GetMyRegLong(NULL, "StartButton", FALSE);
  62.     bHideStartButton = GetMyRegLong(NULL, "StartButtonHide", FALSE);
  63.     bStartButtonFlat = GetMyRegLong(NULL, "StartButtonFlat", FALSE);
  64.     if(!bCustStartButton && !bHideStartButton && !bStartButtonFlat) return;
  65.     
  66.     // サブクラス化
  67.     oldWndProcStart = (WNDPROC)GetWindowLong(hwndStart, GWL_WNDPROC);
  68.     SetWindowLong(hwndStart, GWL_WNDPROC, (LONG)WndProcStart);
  69.     oldWndProcTask = (WNDPROC)GetWindowLong(hwndTask, GWL_WNDPROC);
  70.     SetWindowLong(hwndTask, GWL_WNDPROC, (LONG)WndProcTask);
  71.     
  72.     if(bHideStartButton) // ボタンを隠す
  73.     {
  74.         RECT rc; POINT pt;
  75.         ShowWindow(hwndStart, SW_HIDE);
  76.         wStart = 0; hStart = 0;
  77.         GetWindowRect(hwndTray, &rc);
  78.         pt.x = rc.left; pt.y = rc.top;
  79.         ScreenToClient(GetParent(hwndTray), &pt);
  80.         SetWindowPos(hwndStart, NULL, pt.x, pt.y,
  81.             rc.right - rc.left, rc.bottom - rc.top,
  82.             SWP_NOZORDER|SWP_NOACTIVATE);
  83.     }
  84.     else if(bCustStartButton)
  85.     {
  86.         // ボタン用ビットマップの設定
  87.         SetStartButtonBmp();
  88.     }
  89.     // MSTaskSwWClassの位置・サイズの設定
  90.     if(bCustStartButton || bHideStartButton)
  91.         SetTaskWinPos();
  92. }
  93.  
  94. /*--------------------------------------------------
  95.     reset start button
  96. ----------------------------------------------------*/
  97. void EndStartButton(void)
  98. {
  99.     if(hwndStart && IsWindow(hwndStart))
  100.     {
  101.         if(hbmpstartold != NULL)
  102.         {
  103.             SendMessage(hwndStart, BM_SETIMAGE,
  104.                 0, (LPARAM)hbmpstartold);
  105.             hbmpstartold = NULL;
  106.         }
  107.         if(oldWndProcStart)
  108.             SetWindowLong(hwndStart, GWL_WNDPROC, (LONG)oldWndProcStart);
  109.         oldWndProcStart = NULL;
  110.         SetWindowPos(hwndStart, NULL, 0, 0, 0, 0,
  111.             SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE);
  112.         ShowWindow(hwndStart, SW_SHOW);
  113.     }
  114.     hwndStart = NULL;
  115.     
  116.     if(hbmpstart) DeleteObject(hbmpstart); hbmpstart = NULL;
  117.     
  118.     if(hwndTask && IsWindow(hwndTask) && oldWndProcTask)
  119.         SetWindowLong(hwndTask, GWL_WNDPROC, (LONG)oldWndProcTask);
  120.     oldWndProcTask = NULL; hwndStart = NULL;
  121.     
  122.     bCustStartButton = bHideStartButton = bStartButtonFlat = FALSE;
  123. }
  124.  
  125. /*------------------------------------------------
  126.    subclass procedure of start button
  127. --------------------------------------------------*/
  128. LRESULT CALLBACK WndProcStart(HWND hwnd, UINT message,
  129.     WPARAM wParam, LPARAM lParam)
  130. {
  131.     switch(message)
  132.     {
  133.         case WM_SYSCOLORCHANGE:  // システムの設定変更
  134.         case WM_WININICHANGE:
  135.             if(bCustStartButton)
  136.                 PostMessage(hwnd, WM_USER+10, 0, 0L);
  137.             return 0;
  138.         case (WM_USER + 10):     // 再初期化
  139.             SetStartButtonBmp();
  140.             return 0;
  141.         case WM_WINDOWPOSCHANGING:  // サイズを変更させない
  142.         {
  143.             LPWINDOWPOS pwp;
  144.             if(!(bCustStartButton || bHideStartButton)) break;
  145.             pwp = (LPWINDOWPOS)lParam;
  146.             if(!(pwp->flags & SWP_NOSIZE))
  147.             {
  148.                 if(wStart > 0) pwp->cx = wStart;
  149.                 if(hStart > 0) pwp->cy = hStart;
  150.             }
  151.             if(bHideStartButton && !IsWindowVisible(hwnd))
  152.             {
  153.                 RECT rc; POINT pt;
  154.                 GetWindowRect(hwndTray, &rc);
  155.                 pt.x = rc.left; pt.y = rc.top;
  156.                 ScreenToClient(GetParent(hwndTray), &pt);
  157.                 pwp->x = pt.x; pwp->y = pt.y;
  158.                 pwp->cx = rc.right - rc.left;
  159.                 pwp->cy = rc.bottom - rc.top;
  160.             }
  161.             break;
  162.         }
  163.         case WM_DESTROY:
  164.             if(hbmpstartold)
  165.                 SendMessage(hwndStart, BM_SETIMAGE,
  166.                     0, (LPARAM)hbmpstartold);
  167.             hbmpstartold = NULL;
  168.             if(hbmpstart) DeleteObject(hbmpstart); hbmpstart = NULL;
  169.             break;
  170.  
  171.         // -------- for "flat start button" -----------
  172.         case WM_PAINT:
  173.         {
  174.             HDC hdc;
  175.             PAINTSTRUCT ps;
  176.             if(!bStartButtonFlat) break;
  177.             hdc = BeginPaint(hwnd, &ps);
  178.             OnPaint(hwnd, hdc);
  179.             EndPaint(hwnd, &ps);
  180.             return 0;
  181.         }
  182.         case BM_SETSTATE:
  183.         {
  184.             LRESULT r;
  185.             HDC hdc;
  186.             if(!bStartButtonFlat) break;
  187.             r = CallWindowProc(oldWndProcStart, hwnd, message, wParam, lParam);
  188.             hdc = GetDC(hwnd);
  189.             OnPaint(hwnd, hdc);
  190.             ReleaseDC(hwnd, hdc);
  191.             return 0;
  192.         }
  193.         case WM_SETFOCUS:
  194.             if(!bStartButtonFlat) break;
  195.             return 0;
  196.         case WM_MOUSEMOVE:
  197.             CheckCursorOnStartButton();
  198.             break;
  199.     }
  200.     return CallWindowProc(oldWndProcStart, hwnd, message, wParam, lParam);
  201. }
  202.  
  203. /*--------------------------------------------------
  204.    subclass procedure of
  205.    "MSTaskSwWClass"/"ReBarWindow32" class window
  206. ----------------------------------------------------*/
  207. LRESULT CALLBACK WndProcTask(HWND hwnd, UINT message,
  208.     WPARAM wParam, LPARAM lParam)
  209. {
  210.     switch(message)
  211.     {
  212.         case WM_WINDOWPOSCHANGING: // 位置・サイズの制限
  213.         {
  214.             LPWINDOWPOS pwp;
  215.             RECT rcBar, rcTray;
  216.             
  217.             if(!(bCustStartButton || bHideStartButton)) break;
  218.             
  219.             pwp = (LPWINDOWPOS)lParam;
  220.             if((pwp->flags & SWP_NOMOVE) ||
  221.                 wStart < 0 || hStart < 0) break;
  222.             
  223.             GetClientRect(GetParent(hwndStart), &rcBar); // タスクバー
  224.             GetWindowRect(hwndTray, &rcTray); // TrayNotifyWnd
  225.             
  226.             // タスクバーが横置きのとき
  227.             if(rcBar.right > rcBar.bottom)
  228.             {
  229.                 pwp->x = 2 + wStart; // 右位置
  230.                 pwp->cx = rcTray.left - 2 - wStart - 2; // 横幅
  231.                 if(wStart > 0)
  232.                 {
  233.                     pwp->x += 2; pwp->cx -= 2;
  234.                 }
  235.             }
  236.             else // 縦置きのとき
  237.             {
  238.                 if(rcTray.top < pwp->y)
  239.                 {
  240.                     pwp->cy = rcBar.bottom - 2 - hStart - 2; // 高さ
  241.                 }
  242.                 else
  243.                 {
  244.                     pwp->cy = rcTray.top - 2 - hStart - 2; // 高さ
  245.                 }
  246.                 pwp->y = 2 + hStart; // 上位置
  247.                 if(hStart > 0)
  248.                 {
  249.                     pwp->y += 1; pwp->cy -= 2;
  250.                 }
  251.             }
  252.             break;
  253.         }
  254.     }
  255.     return CallWindowProc(oldWndProcTask, hwnd, message, wParam, lParam);
  256. }
  257.  
  258. /*--------------------------------------------------
  259.  スタートボタンのビットマップとサイズの設定
  260. ----------------------------------------------------*/
  261. void SetStartButtonBmp(void)
  262. {
  263.     char s[1024], caption[80];
  264.     HBITMAP hbmpicon, hbmpold;
  265.     HICON hicon;
  266.     HDC hdc, hdcMem;
  267.     HFONT hfont;
  268.     BITMAP bmp;
  269.     int whbmp, hhbmp, cxicon, cyicon;
  270.  
  271.     if(hwndStart == NULL) return;
  272.     
  273.     hbmpicon = NULL; hicon = NULL;
  274.     cxicon = GetSystemMetrics(SM_CXSMICON);
  275.     cyicon = GetSystemMetrics(SM_CYSMICON);
  276.     
  277.     // ファイルからアイコン用ビットマップの読み込み
  278.     if(GetMyRegStr(NULL, "StartButtonIcon", s, 1024, "") > 0)
  279.     {
  280.         char fname[MAX_PATH], head[2];
  281.         HFILE hf;
  282.         
  283.         parse(fname, s, 0);
  284.         hf = _lopen(fname, OF_READ);
  285.         if(hf != HFILE_ERROR)
  286.         {
  287.             _lread(hf, head, 2);
  288.             _lclose(hf);
  289.             if(head[0] == 'B' && head[1] == 'M') //ビットマップの場合
  290.                 hbmpicon = ReadBitmap(hwndStart, fname, TRUE);
  291.             else if(head[0] == 'M' && head[1] == 'Z') //実行ファイルの場合
  292.             {
  293.                 char numstr[10], *p; int n;
  294.                 HICON hiconl;
  295.                 parse(numstr, s, 1);
  296.                 n = 0; p = numstr;
  297.                 while(*p)
  298.                 {
  299.                     if(*p < '0' || '9' < *p) break;
  300.                     n = n * 10 + *p++ - '0';
  301.                 }
  302.                 if(ExtractIconEx(fname, n, &hiconl, &hicon, 1) < 2)
  303.                     hicon = NULL;
  304.                 else DestroyIcon(hiconl);
  305.             }
  306.             else // アイコンの場合
  307.             {
  308.                 hicon = (HICON)LoadImage(hmod, fname,
  309.                     IMAGE_ICON, cxicon, cyicon,
  310.                     LR_DEFAULTCOLOR|LR_LOADFROMFILE);
  311.             }
  312.         }
  313.     }
  314.     
  315.     if(hbmpicon)
  316.     {
  317.         GetObject(hbmpicon, sizeof(BITMAP), (LPVOID)&bmp);
  318.         cxicon = bmp.bmWidth; cyicon = bmp.bmHeight;
  319.     }
  320.  
  321.     // キャプションの取得
  322.     GetMyRegStr(NULL, "StartButtonCaption", caption, 80, "");
  323.     
  324.     hdc = GetDC(hwndStart);
  325.     
  326.     // ボタン用のフォント = タイトルバーのフォント + BOLD
  327.     hfont = NULL;
  328.     whbmp = cxicon; hhbmp = cyicon;
  329.     if(caption[0])
  330.     {
  331.         NONCLIENTMETRICS ncm;
  332.         SIZE sz;
  333.         ncm.cbSize = sizeof(ncm);
  334.         SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
  335.         ncm.lfCaptionFont.lfWeight = FW_BOLD;
  336.         hfont =  CreateFontIndirect(&(ncm.lfCaptionFont));
  337.         SelectObject(hdc, hfont);
  338.         
  339.         //キャプションの幅を得る
  340.         GetTextExtentPoint32(hdc, caption, strlen(caption), &sz);
  341.         whbmp = sz.cx;
  342.         if(hbmpicon || hicon) whbmp += cxicon + 2;
  343.         hhbmp = sz.cy;
  344.         if((hbmpicon || hicon) && cyicon > sz.cy)
  345.             hhbmp = cyicon;
  346.         //if(hhbmp < 16) hhbmp = 16;
  347.     }
  348.     
  349.     // ビットマップの作成
  350.     hdcMem = CreateCompatibleDC(hdc);
  351.     hbmpstart = CreateCompatibleBitmap(hdc, whbmp, hhbmp);
  352.     SelectObject(hdcMem, hbmpstart);
  353.     
  354.     { // 背景色で塗りつぶし
  355.         RECT rc; HBRUSH hbr;
  356.         SetRect(&rc, 0, 0, whbmp, hhbmp);
  357.         hbr = CreateSolidBrush(GetSysColor(COLOR_3DFACE));
  358.         FillRect(hdcMem, &rc, hbr);
  359.         DeleteObject(hbr);
  360.     }
  361.     
  362.     // ビットマップにアイコンの絵を描画
  363.     if(hbmpicon)
  364.     {
  365.         HDC hdcicon;
  366.         hdcicon = CreateCompatibleDC(hdc);
  367.         SelectObject(hdcicon, hbmpicon);
  368.         BitBlt(hdcMem, 0, (hhbmp - cyicon)/2,
  369.             cxicon, cyicon, hdcicon, 0, 0, SRCCOPY);
  370.         DeleteDC(hdcicon);
  371.         DeleteObject(hbmpicon);
  372.     }
  373.     if(hicon)
  374.     {
  375.         DrawIconEx(hdcMem, 0, (hhbmp - cyicon)/2,
  376.             hicon, cxicon, cyicon, 0, NULL, DI_NORMAL);
  377.         DestroyIcon(hicon);
  378.     }
  379.     
  380.     // ビットマップにキャプションを書く
  381.     if(caption[0])
  382.     {
  383.         TEXTMETRIC tm;
  384.         int x, y;
  385.  
  386.         GetTextMetrics(hdc, &tm);
  387.         SelectObject(hdcMem, hfont);
  388.         x = 0; if(hbmpicon || hicon) x = cxicon + 2;
  389.         y = (hhbmp - tm.tmHeight) / 2;
  390.         SetBkMode(hdcMem, TRANSPARENT);
  391.         SetTextColor(hdcMem, GetSysColor(COLOR_BTNTEXT));
  392.         TextOut(hdcMem, x, y, caption, strlen(caption));
  393.     }
  394.     
  395.     DeleteDC(hdcMem);
  396.     ReleaseDC(hwndStart, hdc);
  397.     if(hfont) DeleteObject(hfont);
  398.  
  399.     // ボタンにビットマップを設定
  400.     hbmpold = (HBITMAP)SendMessage(hwndStart,
  401.         BM_SETIMAGE, 0, (LPARAM)hbmpstart);
  402.     // 以前のビットマップを保存 / 破棄
  403.     if(hbmpstartold == NULL) hbmpstartold = hbmpold;
  404.     else DeleteObject(hbmpold);
  405.     
  406.     // ボタンのサイズの設定  上限:160x80
  407.     wStart = whbmp + 8;
  408.     if(wStart > 160) wStart = 160;
  409.     hStart = GetSystemMetrics(SM_CYCAPTION) + 3;
  410.     if(hhbmp + 6 > hStart) hStart = hhbmp + 6;
  411.     if(hStart > 80) hStart = 80;
  412.     SetWindowPos(hwndStart, NULL, 0, 0,
  413.         wStart, hStart,
  414.         SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE);
  415. }
  416.  
  417. /*--------------------------------------------------
  418.  MSTaskSwWClassの位置・サイズの設定
  419. ----------------------------------------------------*/
  420. void SetTaskWinPos(void)
  421. {
  422.     RECT rcBar, rcTask, rcTray;
  423.     POINT pt;
  424.     int x, y, w, h;
  425.  
  426.     GetClientRect(GetParent(hwndStart), &rcBar);  // Shell_TrayWnd
  427.     GetWindowRect(hwndTray, &rcTray); // TrayNotifyWnd
  428.     GetWindowRect(hwndTask, &rcTask);             // MSTaskSwWClass
  429.     
  430.     // MSTaskSwWClassの右上位置
  431.     pt.x = rcTask.left; pt.y = rcTask.top;
  432.     ScreenToClient(GetParent(hwndStart), &pt);
  433.     
  434.     x = pt.x; y = pt.y;
  435.     w = rcTask.right - rcTask.left;
  436.     h = rcTask.bottom - rcTask.top;
  437.     
  438.     // タスクバーが横置きのとき
  439.     if(rcBar.right > rcBar.bottom)
  440.     {
  441.         x = 2 + wStart;
  442.         w = rcTray.left - 2 - wStart - 2;
  443.         if(wStart > 0)
  444.         {
  445.             x += 2; w -= 2;
  446.         }
  447.     }
  448.     else // 縦置きのとき
  449.     {
  450.         y = 2 + hStart;
  451.         h = rcTray.top - 2 - hStart - 2;
  452.         if(hStart > 0)
  453.         {
  454.             y += 1; h -= 2;
  455.         }
  456.     }
  457.     SetWindowPos(hwndTask, NULL, x, y, w, h,
  458.         SWP_NOZORDER|SWP_NOACTIVATE);
  459. }
  460.  
  461. /*--------------------------------------------------
  462.    draw "flat start button"
  463. ----------------------------------------------------*/
  464. void OnPaint(HWND hwnd, HDC hdc)
  465. {
  466.     HDC hdcMem1, hdcMem2;
  467.     HBITMAP hbmp, hbmpTemp;
  468.     HBRUSH hbr;
  469.     BITMAP bmp;
  470.     RECT rc;
  471.     int x, y, w, h;
  472.     BOOL bPushed;
  473.     
  474.     bPushed = (SendMessage(hwnd, BM_GETSTATE, 0, 0) & BST_PUSHED)?1:0;
  475.     
  476.     hdcMem1 = CreateCompatibleDC(hdc);
  477.     hbmp = (HBITMAP)SendMessage(hwnd, BM_GETIMAGE, IMAGE_BITMAP, 0);
  478.     SelectObject(hdcMem1, hbmp);
  479.     GetObject(hbmp, sizeof(BITMAP), (LPVOID)&bmp);
  480.     w = bmp.bmWidth; h = bmp.bmHeight;
  481.     
  482.     hdcMem2 = CreateCompatibleDC(hdc);
  483.     GetClientRect(hwnd, &rc);
  484.     hbmpTemp = CreateCompatibleBitmap(hdc, rc.right, rc.bottom);
  485.     SelectObject(hdcMem2, hbmpTemp);
  486.     
  487.     hbr = CreateSolidBrush(GetSysColor(COLOR_3DFACE));
  488.     FillRect(hdcMem2, &rc, hbr);
  489.     DeleteObject(hbr);
  490.     
  491.     x = (rc.right - w)/2 + (!bCustStartButton ? 2:0) + (int)bPushed;
  492.     y = (rc.bottom - h)/2 + (int)bPushed;
  493.     BitBlt(hdcMem2, x, y, w, h, hdcMem1, 0, 0, SRCCOPY);
  494.  
  495.     if(bPushed || bCursorOnStartButton) // draw frame
  496.     {
  497.         HPEN hpen, hpenold;
  498.         int color;
  499.         
  500.         color = GetSysColor(bPushed?COLOR_3DSHADOW:COLOR_3DHILIGHT);
  501.         hpen = CreatePen(PS_SOLID, 1, color);
  502.         hpenold = SelectObject(hdcMem2, hpen);
  503.         MoveToEx(hdcMem2, 0, 0, NULL);
  504.         LineTo(hdcMem2, rc.right, 0);
  505.         MoveToEx(hdcMem2, 0, 0, NULL);
  506.         LineTo(hdcMem2, 0, rc.bottom);
  507.         SelectObject(hdcMem2, hpenold);
  508.         DeleteObject(hpen);
  509.         
  510.         color = GetSysColor(bPushed?COLOR_3DHILIGHT:COLOR_3DSHADOW);
  511.         hpen = CreatePen(PS_SOLID, 1, color);
  512.         hpenold = SelectObject(hdcMem2, hpen);
  513.         MoveToEx(hdcMem2, rc.right-1, 0, NULL);
  514.         LineTo(hdcMem2, rc.right-1, rc.bottom);
  515.         MoveToEx(hdcMem2, 0, rc.bottom-1, NULL);
  516.         LineTo(hdcMem2, rc.right, rc.bottom-1);
  517.         SelectObject(hdcMem2, hpenold);
  518.         DeleteObject(hpen);
  519.     }
  520.     
  521.     BitBlt(hdc, 0, 0,
  522.         rc.right, rc.bottom, hdcMem2, 0, 0, SRCCOPY);
  523.     
  524.     DeleteDC(hdcMem1);
  525.     DeleteDC(hdcMem2);
  526.     DeleteObject(hbmpTemp);
  527. }
  528.  
  529. /*--------------------------------------------------
  530.    called when clock window receive WM_TIMER.
  531.    check cursor position, and draw "flat start button"
  532. ----------------------------------------------------*/
  533. void CheckCursorOnStartButton(void)
  534. {
  535.     POINT pt;
  536.     RECT rc;
  537.     
  538.     if(hwndStart == NULL) return;
  539.     if(!bStartButtonFlat) return;
  540.     
  541.     GetCursorPos(&pt);
  542.     GetWindowRect(hwndStart, &rc);
  543.     if(PtInRect(&rc, pt))
  544.     {
  545.         if(!bCursorOnStartButton)
  546.         {
  547.             bCursorOnStartButton = TRUE;
  548.             InvalidateRect(hwndStart, NULL, FALSE);
  549.         }
  550.     }
  551.     else
  552.     {
  553.         if(bCursorOnStartButton)
  554.         {
  555.             bCursorOnStartButton = FALSE;
  556.             InvalidateRect(hwndStart, NULL, FALSE);
  557.         }
  558.     }
  559. }
  560.  
  561.