Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

winhyperlinks.cpp

Go to the documentation of this file.
00001 // winhyperlinks.cpp
00002 //
00003 // Copyright (C) 2003, Chris Laurel <claurel@shatters.net>
00004 //
00005 // Code to convert a static control to a hyperlink.
00006 //
00007 // This program is free software; you can redistribute it and/or
00008 // modify it under the terms of the GNU General Public License
00009 // as published by the Free Software Foundation; either version 2
00010 // of the License, or (at your option) any later version.
00011 
00012 #include "winhyperlinks.h"
00013 #include "res/resource.h"
00014 
00015 static LPTSTR hyperLinkFromStatic = "_Hyperlink_From_Static_";
00016 static LPTSTR hyperLinkOriginalProc = "_Hyperlink_Original_Proc_";
00017 static LPTSTR hyperLinkOriginalFont = "_Hyperlink_Original_Font_";
00018 static LPTSTR hyperLinkUnderlineFont = "_Hyperlink_Underline_Font_";
00019 
00020 bool GetTextRect(HWND hWnd, RECT* rectText)
00021 {
00022     bool result = false;
00023     SIZE sizeText;
00024     RECT rectControl;
00025     char staticText[1024];
00026     HDC hDC;
00027     HFONT hFont, hOldFont;
00028     HWND hWndScreen;
00029 
00030     // Get DC of static control and select font so that text extent is computed accurately
00031     if (hDC = GetDC(hWnd))
00032     {
00033         hFont = (HFONT)GetProp(hWnd, hyperLinkOriginalFont);
00034         hOldFont = (HFONT)SelectObject(hDC, hFont);
00035         GetWindowText(hWnd, staticText, sizeof(staticText) - 1);
00036         if (GetTextExtentPoint32(hDC, staticText, strlen(staticText), &sizeText))
00037         {
00038             // Construct bounding rectangle of text, assuming text is centered in client area
00039             if (GetClientRect(hWnd, &rectControl))
00040             {
00041                 hWndScreen = GetDesktopWindow();
00042                 rectText->left = (rectControl.right - sizeText.cx) / 2;
00043                 rectText->top = (rectControl.bottom - sizeText.cy) / 2;
00044                 rectText->right = rectText->left + sizeText.cx;
00045                 rectText->bottom = rectText->top + sizeText.cy;
00046                 result = true;
00047             }
00048         }
00049         SelectObject(hDC, hOldFont);
00050         ReleaseDC(hWnd, hDC);
00051     }
00052 
00053     return result;
00054 }
00055 
00056 LRESULT CALLBACK _HyperlinkParentProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
00057 {
00058     WNDPROC origProc = (WNDPROC)GetProp(hWnd, hyperLinkOriginalProc);
00059 
00060     switch (message)
00061     {
00062     case WM_CTLCOLORSTATIC:
00063         {
00064             HDC hDC = (HDC)wParam;
00065             HWND hCtrl = (HWND)lParam;
00066 
00067             // Change the color of the static text to hyperlink color (blue).
00068             if (GetProp(hCtrl, hyperLinkFromStatic) != NULL)
00069             {
00070                 LRESULT result = CallWindowProc(origProc, hWnd, message, wParam, lParam);
00071                 SetTextColor(hDC, RGB(0, 0, 192));
00072                 return result;
00073             }
00074 
00075             break;
00076         }
00077     case WM_DESTROY:
00078         {
00079             SetWindowLong(hWnd, GWL_WNDPROC, (LONG)origProc);
00080             RemoveProp(hWnd, hyperLinkOriginalProc);
00081             break;
00082         }
00083     }
00084 
00085     return CallWindowProc(origProc, hWnd, message, wParam, lParam);
00086 }
00087 
00088 LRESULT CALLBACK _HyperlinkProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
00089 {
00090     WNDPROC origProc = (WNDPROC)GetProp(hWnd, hyperLinkOriginalProc);
00091 
00092     switch (message)
00093     {
00094     case WM_MOUSEMOVE:
00095         {
00096             if (GetCapture() != hWnd)
00097             {
00098                 RECT rect;
00099                 if (!GetTextRect(hWnd, &rect))
00100                     GetClientRect(hWnd, &rect);
00101 
00102                 POINT pt = { LOWORD(lParam), HIWORD(lParam) };
00103                 if (PtInRect(&rect, pt))
00104                 {
00105                     HFONT hFont = (HFONT)GetProp(hWnd, hyperLinkUnderlineFont);
00106                     SendMessage(hWnd, WM_SETFONT, (WPARAM)hFont, FALSE);
00107                     InvalidateRect(hWnd, NULL, FALSE);
00108                     SetCapture(hWnd);
00109                     HCURSOR hCursor = LoadCursor(NULL, MAKEINTRESOURCE(IDC_HAND));
00110                     if (NULL == hCursor)
00111                         hCursor = LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW));
00112                     SetCursor(hCursor);
00113                 }
00114             }
00115             else
00116             {
00117                 RECT rect;
00118                 if (!GetTextRect(hWnd, &rect))
00119                     GetClientRect(hWnd, &rect);
00120 
00121                 POINT pt = { LOWORD(lParam), HIWORD(lParam) };
00122                 if (!PtInRect(&rect, pt))
00123                 {
00124                     HFONT hFont = (HFONT)GetProp(hWnd, hyperLinkOriginalFont);
00125                     SendMessage(hWnd, WM_SETFONT, (WPARAM)hFont, FALSE);
00126                     InvalidateRect(hWnd, NULL, FALSE);
00127                     ReleaseCapture();
00128                 }
00129             }
00130             break;
00131         }
00132     case WM_DESTROY:
00133         {
00134             SetWindowLong(hWnd, GWL_WNDPROC, (LONG)origProc);
00135             RemoveProp(hWnd, hyperLinkOriginalProc);
00136 
00137             HFONT hOrigFont = (HFONT)GetProp(hWnd, hyperLinkOriginalFont);
00138             SendMessage(hWnd, WM_SETFONT, (WPARAM) hOrigFont, 0);
00139             RemoveProp(hWnd, hyperLinkOriginalFont);
00140 
00141             HFONT hFont = (HFONT)GetProp(hWnd, hyperLinkUnderlineFont);
00142             DeleteObject(hFont);
00143             RemoveProp(hWnd, hyperLinkUnderlineFont);
00144 
00145             RemoveProp(hWnd, hyperLinkFromStatic);
00146 
00147             break;
00148         }
00149     }
00150 
00151     return CallWindowProc(origProc, hWnd, message, wParam, lParam);
00152 }
00153 
00154 BOOL MakeHyperlinkFromStaticCtrl(HWND hDlg, UINT ctrlID)
00155 {
00156     BOOL result = FALSE;
00157 
00158     HWND hCtrl = GetDlgItem(hDlg, ctrlID);
00159     if (hCtrl)
00160     {
00161         // Subclass the parent so we can color the controls as we desire.
00162         HWND hParent = GetParent(hCtrl);
00163         if (hParent)
00164         {
00165             WNDPROC origProc = (WNDPROC)GetWindowLong(hParent, GWL_WNDPROC);
00166             if (origProc != _HyperlinkParentProc)
00167             {
00168                 SetProp(hParent, hyperLinkOriginalProc, (HANDLE)origProc);
00169                 SetWindowLong(hParent, GWL_WNDPROC, (LONG)(WNDPROC)_HyperlinkParentProc);
00170             }
00171         }
00172 
00173         // Make sure the control will send notifications.
00174         DWORD dwStyle = GetWindowLong(hCtrl, GWL_STYLE);
00175         SetWindowLong(hCtrl, GWL_STYLE, dwStyle | SS_NOTIFY);
00176 
00177         // Subclass the existing control.
00178         WNDPROC origProc = (WNDPROC)GetWindowLong(hCtrl, GWL_WNDPROC);
00179         SetProp(hCtrl, hyperLinkOriginalProc, (HANDLE)origProc);
00180         SetWindowLong(hCtrl, GWL_WNDPROC, (LONG)(WNDPROC)_HyperlinkProc);
00181 
00182         // Create an updated font by adding an underline.
00183         HFONT hOrigFont = (HFONT) SendMessage(hCtrl, WM_GETFONT, 0, 0);
00184         SetProp(hCtrl, hyperLinkOriginalFont, (HANDLE)hOrigFont);
00185 
00186         LOGFONT lf;
00187         GetObject(hOrigFont, sizeof(lf), &lf);
00188         lf.lfUnderline = TRUE;
00189 
00190         HFONT hFont = CreateFontIndirect(&lf);
00191         SetProp(hCtrl, hyperLinkUnderlineFont, (HANDLE)hFont);
00192 
00193         // Set a flag on the control so we know what color it should be.
00194         SetProp(hCtrl, hyperLinkFromStatic, (HANDLE)1);
00195 
00196         result = TRUE;
00197     }
00198 
00199     return result;
00200 }

Generated on Sat Jan 14 22:30:31 2006 for Celestia by  doxygen 1.4.1