- // hyperlinks.c 
-   
- #include <windows.h> 
-   
-   
- #ifdef UNICODE 
- #define LONGSTRING_PREFIX L 
- #else // !UNICODE 
- #define LONGSTRING_PREFIX 
- #endif // UNICODE 
-   
-   
- #define PROP_HYPERLINK_STRUCT LONGSTRING_PREFIX"_HyperlinkStruct" 
- #define PROP_HYPERLINKPARENT_STRUCT LONGSTRING_PREFIX"_HyperlinkParentStruct" 
-   
-   
- // standard hand cursor definition 
- #ifndef IDC_HAND 
- #define IDC_HAND 147 
- #endif 
-   
-   
- // hyperlink'ed static text control structure 
- typedef struct hyperlink_s 
- { 
-    HWND hWnd; // static text control window handle 
-    WNDPROC pfnOrigProc; // original static text control window procedure 
-    HFONT font; // underlined hypertext font used for this control 
- } hyperlink_t; 
-   
-   
- // hyperlink parent window structure 
- typedef struct hyperlinkparent_s 
- { 
-    HWND hWnd; // hyperlink parent window handle 
-    WNDPROC pfnOrigProc; // original static text control window parent procedure 
- } hyperlinkparent_t; 
-   
-   
- // hyperlink cursor 
- static HCURSOR hyperlink_cursor = NULL; 
- static LOGFONT hyperlink_logicalfont; 
-   
- // hyperlinks.c function prototypes 
- void ConvertStaticToHyperlink (HWND hWndStatic); 
- static int WINAPI _HyperlinkParentProc (HWND hWnd, unsigned int message, WPARAM wParam, LPARAM lParam); 
- static int WINAPI _HyperlinkProc (HWND hWnd, unsigned int message, WPARAM wParam, LPARAM lParam); 
-   
-   
- void ConvertStaticToHyperlink (HWND hWndStatic) 
- { 
-    // subclass the parent so we can color the controls as we desire 
-   
-    hyperlinkparent_t *hyperlinkparent; 
-    hyperlink_t *hyperlink; 
-   
-    // first off, if the hand cursor isn't loaded yet, do it (this part is done once) 
-    if (hyperlink_cursor == NULL) 
-    { 
-       // since IDC_HAND is not available on all operating systems, we will load the arrow cursor if IDC_HAND is not present. 
-       hyperlink_cursor = LoadCursor (NULL, MAKEINTRESOURCE (IDC_HAND)); 
-       if (hyperlink_cursor == NULL) 
-          hyperlink_cursor = LoadCursor (NULL, MAKEINTRESOURCE (IDC_ARROW)); // fallback cursor 
-    } 
-   
-    // does this control belong to a window ? 
-    if (GetParent (hWndStatic) != NULL) 
-    { 
-       // mallocate space for a new hyperlink parent 
-       hyperlinkparent = (hyperlinkparent_t *) malloc (sizeof (hyperlinkparent_t)); 
-       if (hyperlinkparent == NULL) 
-          return; // on failure, just return 
-   
-       hyperlinkparent->hWnd = GetParent (hWndStatic); // save away the hyperlink parent's window handle 
-       hyperlinkparent->pfnOrigProc = (WNDPROC) GetWindowLong (GetParent (hWndStatic), GWL_WNDPROC); // get its current window procedure 
-   
-       // has this parent NOT been already subclassed by another hyperlink ? 
-       if (hyperlinkparent->pfnOrigProc != (WNDPROC) _HyperlinkParentProc) 
-       { 
-          // save a pointer to the hyperlink structure in the window's properties and subclass it by replacing its window procedure by our own 
-          SetProp (GetParent (hWndStatic), PROP_HYPERLINKPARENT_STRUCT, (HANDLE) hyperlinkparent); 
-          SetWindowLongPtr (GetParent (hWndStatic), GWL_WNDPROC, (long) (WNDPROC) _HyperlinkParentProc); 
-       } 
-    } 
-   
-    // mallocate space for a new hyperlink 
-    hyperlink = (hyperlink_t *) malloc (sizeof (hyperlink_t)); 
-    if (hyperlink == NULL) 
-       return; // on failure, just return 
-   
-    hyperlink->hWnd = hWndStatic; // get the static control's window handle 
-    hyperlink->pfnOrigProc = (WNDPROC) GetWindowLong (hyperlink->hWnd, GWL_WNDPROC); // get the static control's window procedure 
-   
-    // create an updated font by adding an underline 
-    hyperlink->font = (HFONT) SendMessage (hyperlink->hWnd, WM_GETFONT, 0, 0); 
-    memset (&hyperlink_logicalfont, 0, sizeof (hyperlink_logicalfont)); 
-    GetObject (hyperlink->font, sizeof (hyperlink_logicalfont), &hyperlink_logicalfont); 
-    hyperlink_logicalfont.lfUnderline = 1; 
-    hyperlink->font = CreateFontIndirect (&hyperlink_logicalfont); 
-    SendMessage (hyperlink->hWnd, WM_SETFONT, (WPARAM) hyperlink->font, 0); 
-   
-    // make sure the static control will send event notifications to its window procedure 
-    SetWindowLong (hyperlink->hWnd, GWL_STYLE, GetWindowLong (hyperlink->hWnd, GWL_STYLE) | SS_NOTIFY); 
-   
-    // save a pointer to the hyperlink structure in the window's properties and subclass it by replacing its window procedure by our own 
-    SetProp (hyperlink->hWnd, PROP_HYPERLINK_STRUCT, (HANDLE) hyperlink); 
-    SetWindowLongPtr (hyperlink->hWnd, GWL_WNDPROC, (long) (WNDPROC) _HyperlinkProc); 
-   
-    return; // finished transforming the static text control 
- } 
-   
-   
- static int WINAPI _HyperlinkParentProc (HWND hWnd, unsigned int message, WPARAM wParam, LPARAM lParam) 
- { 
-    // this function hooks the hyperlink parent's control drawing messages so as to draw hyperlinks differently from normal static controls 
-   
-    hyperlinkparent_t *hyperlinkparent; 
-    WNDPROC OriginalWindowProc; 
-    LRESULT result; 
-   
-    // get a pointer to the hyperlink structure 
-    hyperlinkparent = (hyperlinkparent_t *) GetProp (hWnd, PROP_HYPERLINKPARENT_STRUCT); 
-    if (hyperlinkparent == NULL) 
-       return (DefWindowProc (hWnd, message, wParam, lParam)); // consistency check 
-   
-    // are we drawing a static control ? 
-    if (message == WM_CTLCOLORSTATIC) 
-    { 
-       result = CallWindowProc (hyperlinkparent->pfnOrigProc, hWnd, message, wParam, lParam); // call the window procedure normally 
-       if ((WNDPROC) GetWindowLong ((HWND) lParam, GWL_WNDPROC) == (WNDPROC) _HyperlinkProc) 
-          SetTextColor ((HDC) wParam, RGB (0, 0, 192)); // but notify the parent to draw this text in blue if it's one of our hyperlinks 
-       return (result); // and return the original window proc return result 
-    } 
-   
-    // else are we destroying ourselves ? 
-    else if (message == WM_DESTROY) 
-    { 
-       OriginalWindowProc = hyperlinkparent->pfnOrigProc; 
-       SetWindowLongPtr (hWnd, GWL_WNDPROC, (long) OriginalWindowProc); // restore the original window procedure 
-       if (hyperlinkparent != NULL) 
-          free (hyperlinkparent); // free the hyperlink parent structure 
-       hyperlinkparent = NULL; 
-       RemoveProp (hWnd, PROP_HYPERLINKPARENT_STRUCT); // and remove the window property where we used to save it 
-       return (OriginalWindowProc (hWnd, message, wParam, lParam)); // now call the freshly restored window procedure to let things go 
-    } 
-   
-    // now call the original window procedure to let things go normally 
-    return (CallWindowProc (hyperlinkparent->pfnOrigProc, hWnd, message, wParam, lParam)); 
- } 
-   
-   
- static int WINAPI _HyperlinkProc (HWND hWnd, unsigned int message, WPARAM wParam, LPARAM lParam) 
- { 
-    // this function hooks the messages directed to the static text control that we turned into a hyperlink 
-   
-    hyperlink_t *hyperlink; 
-    WNDPROC OriginalWindowProc; 
-   
-    // get a pointer to the hyperlink structure 
-    hyperlink = (hyperlink_t *) GetProp (hWnd, PROP_HYPERLINK_STRUCT); 
-    if (hyperlink == NULL) 
-       return (DefWindowProc (hWnd, message, wParam, lParam)); // consistency check 
-   
-    // is the mouse moving inside the static control ? 
-    if (message == WM_SETCURSOR) 
-    { 
-       if (hyperlink_cursor != NULL) 
-          SetCursor (hyperlink_cursor); // set the static control cursor to be the pointing hand, if we have it 
-   
-       return (1); // halt further processing on this message 
-    } 
-   
-    // else are we destroying the static control ? 
-    else if (message == WM_DESTROY) 
-    { 
-       OriginalWindowProc = hyperlink->pfnOrigProc; 
-       SetWindowLongPtr (hWnd, GWL_WNDPROC, (long) OriginalWindowProc); // restore the original static control procedure 
-       if (hyperlink != NULL) 
-          free (hyperlink); // free the hyperlink structure 
-       hyperlink = NULL; 
-       RemoveProp (hWnd, PROP_HYPERLINK_STRUCT); // and remove the static control property where we used to save it 
-       return (OriginalWindowProc (hWnd, message, wParam, lParam)); // now call the freshly restored window procedure to let things go 
-    } 
-   
-    // now call the original static control procedure to let things go normally 
-    return (CallWindowProc (hyperlink->pfnOrigProc, hWnd, message, wParam, lParam)); 
- } 
-