winhyperlinks.cpp
上传用户:center1979
上传日期:2022-07-26
资源大小:50633k
文件大小:7k
源码类别:

OpenGL

开发平台:

Visual C++

  1. // winhyperlinks.cpp
  2. //
  3. // Copyright (C) 2003, Chris Laurel <claurel@shatters.net>
  4. //
  5. // Code to convert a static control to a hyperlink.
  6. //
  7. // This program is free software; you can redistribute it and/or
  8. // modify it under the terms of the GNU General Public License
  9. // as published by the Free Software Foundation; either version 2
  10. // of the License, or (at your option) any later version.
  11. #include "winhyperlinks.h"
  12. #include "res/resource.h"
  13. static LPTSTR hyperLinkFromStatic = "_Hyperlink_From_Static_";
  14. static LPTSTR hyperLinkOriginalProc = "_Hyperlink_Original_Proc_";
  15. static LPTSTR hyperLinkOriginalFont = "_Hyperlink_Original_Font_";
  16. static LPTSTR hyperLinkUnderlineFont = "_Hyperlink_Underline_Font_";
  17. bool GetTextRect(HWND hWnd, RECT* rectText)
  18. {
  19.     bool result = false;
  20.     SIZE sizeText;
  21.     RECT rectControl;
  22.     char staticText[1024];
  23.     HDC hDC;
  24.     HFONT hFont, hOldFont;
  25.     HWND hWndScreen;
  26.     // Get DC of static control and select font so that text extent is computed accurately
  27.     if (hDC = GetDC(hWnd))
  28.     {
  29.         hFont = (HFONT)GetProp(hWnd, hyperLinkOriginalFont);
  30.         hOldFont = (HFONT)SelectObject(hDC, hFont);
  31.         GetWindowText(hWnd, staticText, sizeof(staticText) - 1);
  32.         if (GetTextExtentPoint32(hDC, staticText, strlen(staticText), &sizeText))
  33.         {
  34.             // Construct bounding rectangle of text, assuming text is centered in client area
  35.             if (GetClientRect(hWnd, &rectControl))
  36.             {
  37.                 hWndScreen = GetDesktopWindow();
  38.                 rectText->left = (rectControl.right - sizeText.cx) / 2;
  39.                 rectText->top = (rectControl.bottom - sizeText.cy) / 2;
  40.                 rectText->right = rectText->left + sizeText.cx;
  41.                 rectText->bottom = rectText->top + sizeText.cy;
  42.                 result = true;
  43.             }
  44.         }
  45.         SelectObject(hDC, hOldFont);
  46.         ReleaseDC(hWnd, hDC);
  47.     }
  48.     return result;
  49. }
  50. LRESULT CALLBACK _HyperlinkParentProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  51. {
  52.     WNDPROC origProc = (WNDPROC)GetProp(hWnd, hyperLinkOriginalProc);
  53.     switch (message)
  54.     {
  55.     case WM_CTLCOLORSTATIC:
  56.         {
  57.             HDC hDC = (HDC)wParam;
  58.             HWND hCtrl = (HWND)lParam;
  59.             // Change the color of the static text to hyperlink color (blue).
  60.             if (GetProp(hCtrl, hyperLinkFromStatic) != NULL)
  61.             {
  62.                 LRESULT result = CallWindowProc(origProc, hWnd, message, wParam, lParam);
  63.                 SetTextColor(hDC, RGB(0, 0, 192));
  64.                 return result;
  65.             }
  66.             break;
  67.         }
  68.     case WM_DESTROY:
  69.         {
  70.             SetWindowLong(hWnd, GWL_WNDPROC, (LONG)origProc);
  71.             RemoveProp(hWnd, hyperLinkOriginalProc);
  72.             break;
  73.         }
  74.     }
  75.     return CallWindowProc(origProc, hWnd, message, wParam, lParam);
  76. }
  77. LRESULT CALLBACK _HyperlinkProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  78. {
  79.     WNDPROC origProc = (WNDPROC)GetProp(hWnd, hyperLinkOriginalProc);
  80.     switch (message)
  81.     {
  82.     case WM_MOUSEMOVE:
  83.         {
  84.             if (GetCapture() != hWnd)
  85.             {
  86.                 RECT rect;
  87.                 if (!GetTextRect(hWnd, &rect))
  88.                     GetClientRect(hWnd, &rect);
  89.                 POINT pt = { LOWORD(lParam), HIWORD(lParam) };
  90.                 if (PtInRect(&rect, pt))
  91.                 {
  92.                     HFONT hFont = (HFONT)GetProp(hWnd, hyperLinkUnderlineFont);
  93.                     SendMessage(hWnd, WM_SETFONT, (WPARAM)hFont, FALSE);
  94.                     InvalidateRect(hWnd, NULL, FALSE);
  95.                     SetCapture(hWnd);
  96.                     HCURSOR hCursor = LoadCursor(NULL, MAKEINTRESOURCE(IDC_HAND));
  97.                     if (NULL == hCursor)
  98.                         hCursor = LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW));
  99.                     SetCursor(hCursor);
  100.                 }
  101.             }
  102.             else
  103.             {
  104.                 RECT rect;
  105.                 if (!GetTextRect(hWnd, &rect))
  106.                     GetClientRect(hWnd, &rect);
  107.                 POINT pt = { LOWORD(lParam), HIWORD(lParam) };
  108.                 if (!PtInRect(&rect, pt))
  109.                 {
  110.                     HFONT hFont = (HFONT)GetProp(hWnd, hyperLinkOriginalFont);
  111.                     SendMessage(hWnd, WM_SETFONT, (WPARAM)hFont, FALSE);
  112.                     InvalidateRect(hWnd, NULL, FALSE);
  113.                     ReleaseCapture();
  114.                 }
  115.             }
  116.             break;
  117.         }
  118.     case WM_DESTROY:
  119.         {
  120.             SetWindowLong(hWnd, GWL_WNDPROC, (LONG)origProc);
  121.             RemoveProp(hWnd, hyperLinkOriginalProc);
  122.             HFONT hOrigFont = (HFONT)GetProp(hWnd, hyperLinkOriginalFont);
  123.             SendMessage(hWnd, WM_SETFONT, (WPARAM) hOrigFont, 0);
  124.             RemoveProp(hWnd, hyperLinkOriginalFont);
  125.             HFONT hFont = (HFONT)GetProp(hWnd, hyperLinkUnderlineFont);
  126.             DeleteObject(hFont);
  127.             RemoveProp(hWnd, hyperLinkUnderlineFont);
  128.             RemoveProp(hWnd, hyperLinkFromStatic);
  129.             break;
  130.         }
  131.     }
  132.     return CallWindowProc(origProc, hWnd, message, wParam, lParam);
  133. }
  134. BOOL MakeHyperlinkFromStaticCtrl(HWND hDlg, UINT ctrlID)
  135. {
  136.     BOOL result = FALSE;
  137.     HWND hCtrl = GetDlgItem(hDlg, ctrlID);
  138.     if (hCtrl)
  139.     {
  140.         // Subclass the parent so we can color the controls as we desire.
  141.         HWND hParent = GetParent(hCtrl);
  142.         if (hParent)
  143.         {
  144.             WNDPROC origProc = (WNDPROC)GetWindowLong(hParent, GWL_WNDPROC);
  145.             if (origProc != _HyperlinkParentProc)
  146.             {
  147.                 SetProp(hParent, hyperLinkOriginalProc, (HANDLE)origProc);
  148.                 SetWindowLong(hParent, GWL_WNDPROC, (LONG)(WNDPROC)_HyperlinkParentProc);
  149.             }
  150.         }
  151.         // Make sure the control will send notifications.
  152.         DWORD dwStyle = GetWindowLong(hCtrl, GWL_STYLE);
  153.         SetWindowLong(hCtrl, GWL_STYLE, dwStyle | SS_NOTIFY);
  154.         // Subclass the existing control.
  155.         WNDPROC origProc = (WNDPROC)GetWindowLong(hCtrl, GWL_WNDPROC);
  156.         SetProp(hCtrl, hyperLinkOriginalProc, (HANDLE)origProc);
  157.         SetWindowLong(hCtrl, GWL_WNDPROC, (LONG)(WNDPROC)_HyperlinkProc);
  158.         // Create an updated font by adding an underline.
  159.         HFONT hOrigFont = (HFONT) SendMessage(hCtrl, WM_GETFONT, 0, 0);
  160.         SetProp(hCtrl, hyperLinkOriginalFont, (HANDLE)hOrigFont);
  161.         LOGFONT lf;
  162.         GetObject(hOrigFont, sizeof(lf), &lf);
  163.         lf.lfUnderline = TRUE;
  164.         HFONT hFont = CreateFontIndirect(&lf);
  165.         SetProp(hCtrl, hyperLinkUnderlineFont, (HANDLE)hFont);
  166.         // Set a flag on the control so we know what color it should be.
  167.         SetProp(hCtrl, hyperLinkFromStatic, (HANDLE)1);
  168.         result = TRUE;
  169.     }
  170.     return result;
  171. }