c++ win32 添加超链接到对话框

问题描述 投票:0回答:3

我想向我的 Win32 应用程序(使用 C++ 开发)添加一个“关于”对话框。如何向对话框添加超链接?我正在从资源文件 (.rc) 加载对话框。是否可以从 .rc 文件定义此功能?

我的 .rc 文件现在看起来像这样:

 IDD_ABOUTBOX DIALOGEX 0, 0, 218, 118
 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_CENTER 
 CAPTION "About My App"
 FONT 8, "MS Shell Dlg"
 BEGIN
    ICON            IDI_APP_ICON,IDC_STATIC,13,88,15,15
    LTEXT           "MY url http://www.myurl.com",IDC_STATIC,15,6,194,24,SS_NOPREFIX
    DEFPUSHBUTTON   "OK",IDOK,95,98,50,14,WS_GROUP
 END    
c++ winapi hyperlink dialog
3个回答
11
投票

您可以在 Windows XP 或更高版本上使用 SysLink Control

您可以从 .rc 文件中定义它,如下所示:

在资源.rc 中:

 CONTROL         "<a>Link</a>",IDC_SYSLINK1,"SysLink",WS_TABSTOP,7,7,53,12

在资源.h中:

#define IDC_SYSLINK1                    1001

3
投票

在没有任何外部库的情况下进行突出显示的最佳方法,仍然看起来和感觉与任何控件相同,甚至使鼠标光标变成手指指向图标。

/* Start of HyperLink URL */
#define PROP_ORIGINAL_FONT      TEXT("_Hyperlink_Original_Font_")
#define PROP_ORIGINAL_PROC      TEXT("_Hyperlink_Original_Proc_")
#define PROP_STATIC_HYPERLINK   TEXT("_Hyperlink_From_Static_")
#define PROP_UNDERLINE_FONT     TEXT("_Hyperlink_Underline_Font_")
LRESULT CALLBACK _HyperlinkParentProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK _HyperlinkProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
static void CreateHyperLink(HWND hwndControl);
/* End of HyperLink URL */



static void CreateHyperLink(HWND hwndControl)
{
    // Subclass the parent so we can color the controls as we desire.
    HWND hwndParent = GetParent(hwndControl);
    if (NULL != hwndParent)
    {
        WNDPROC pfnOrigProc = (WNDPROC)GetWindowLong(hwndParent, GWL_WNDPROC);
        if (pfnOrigProc != _HyperlinkParentProc)
        {
            SetProp(hwndParent, PROP_ORIGINAL_PROC, (HANDLE)pfnOrigProc);
            SetWindowLong(hwndParent, GWL_WNDPROC, (LONG)(WNDPROC)_HyperlinkParentProc);
        }
    }

    // Make sure the control will send notifications.
    DWORD dwStyle = GetWindowLong(hwndControl, GWL_STYLE);
    SetWindowLong(hwndControl, GWL_STYLE, dwStyle | SS_NOTIFY);

    // Subclass the existing control.
    WNDPROC pfnOrigProc = (WNDPROC)GetWindowLong(hwndControl, GWL_WNDPROC);
    SetProp(hwndControl, PROP_ORIGINAL_PROC, (HANDLE)pfnOrigProc);
    SetWindowLong(hwndControl, GWL_WNDPROC, (LONG)(WNDPROC)_HyperlinkProc);

    // Create an updated font by adding an underline.
    HFONT hOrigFont = (HFONT)SendMessage(hwndControl, WM_GETFONT, 0, 0);
    SetProp(hwndControl, PROP_ORIGINAL_FONT, (HANDLE)hOrigFont);

    LOGFONT lf;
    GetObject(hOrigFont, sizeof(lf), &lf);
    lf.lfUnderline = TRUE;

    HFONT hFont = CreateFontIndirect(&lf);
    SetProp(hwndControl, PROP_UNDERLINE_FONT, (HANDLE)hFont);

    // Set a flag on the control so we know what color it should be.
    SetProp(hwndControl, PROP_STATIC_HYPERLINK, (HANDLE)1);
}

LRESULT CALLBACK _HyperlinkParentProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    WNDPROC pfnOrigProc = (WNDPROC)GetProp(hwnd, PROP_ORIGINAL_PROC);

    switch (message)
    {
    case WM_CTLCOLORSTATIC:
    {
        HDC hdc = (HDC)wParam;
        HWND hwndCtl = (HWND)lParam;

        BOOL fHyperlink = (NULL != GetProp(hwndCtl, PROP_STATIC_HYPERLINK));
        if (fHyperlink)
        {
            LRESULT lr = CallWindowProc(pfnOrigProc, hwnd, message, wParam, lParam);
            SetTextColor(hdc, RGB(0, 0, 192));
            return lr;
        }

        break;
    }
    case WM_DESTROY:
    {
        SetWindowLong(hwnd, GWL_WNDPROC, (LONG)pfnOrigProc);
        RemoveProp(hwnd, PROP_ORIGINAL_PROC);
        break;
    }
    }
    return CallWindowProc(pfnOrigProc, hwnd, message, wParam, lParam);
}

LRESULT CALLBACK _HyperlinkProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    WNDPROC pfnOrigProc = (WNDPROC)GetProp(hwnd, PROP_ORIGINAL_PROC);

    switch (message)
    {
    case WM_DESTROY:
    {
        SetWindowLong(hwnd, GWL_WNDPROC, (LONG)pfnOrigProc);
        RemoveProp(hwnd, PROP_ORIGINAL_PROC);

        HFONT hOrigFont = (HFONT)GetProp(hwnd, PROP_ORIGINAL_FONT);
        SendMessage(hwnd, WM_SETFONT, (WPARAM)hOrigFont, 0);
        RemoveProp(hwnd, PROP_ORIGINAL_FONT);

        HFONT hFont = (HFONT)GetProp(hwnd, PROP_UNDERLINE_FONT);
        DeleteObject(hFont);
        RemoveProp(hwnd, PROP_UNDERLINE_FONT);

        RemoveProp(hwnd, PROP_STATIC_HYPERLINK);

        break;
    }
    case WM_MOUSEMOVE:
    {
        if (GetCapture() != hwnd)
        {
            HFONT hFont = (HFONT)GetProp(hwnd, PROP_UNDERLINE_FONT);
            SendMessage(hwnd, WM_SETFONT, (WPARAM)hFont, FALSE);
            InvalidateRect(hwnd, NULL, FALSE);
            SetCapture(hwnd);
        }
        else
        {
            RECT rect;
            GetWindowRect(hwnd, &rect);

            POINT pt = { LOWORD(lParam), HIWORD(lParam) };
            ClientToScreen(hwnd, &pt);

            if (!PtInRect(&rect, pt))
            {
                HFONT hFont = (HFONT)GetProp(hwnd, PROP_ORIGINAL_FONT);
                SendMessage(hwnd, WM_SETFONT, (WPARAM)hFont, FALSE);
                InvalidateRect(hwnd, NULL, FALSE);
                ReleaseCapture();
            }
        }
        break;
    }
    case WM_SETCURSOR:
    {
        // Since IDC_HAND is not available on all operating systems,
        // we will load the arrow cursor if IDC_HAND is not present.
        HCURSOR hCursor = LoadCursor(NULL, IDC_HAND);
        if (NULL == hCursor)
            hCursor = LoadCursor(NULL, IDC_ARROW);
        SetCursor(hCursor);
        return TRUE;
    }
    }

    return CallWindowProc(pfnOrigProc, hwnd, message, wParam, lParam);
}

使用方法如下:

CreateHyperLink(GetDlgItem(Dialog_HWND_GOES_HERE, STATIC_TEXT_IDENIFIER_GOES_HERE));

在主对话框子类中可以单击静态标签的位置执行类似的操作..

        if (HIWORD(wParam) == BN_CLICKED) { //Buttons, checkboxs, labels, static labels clicked
            switch (LOWORD(wParam))
            {
                case STATIC_TEXT_IDENIFIER_GOES_HERE:
                    ShellExecute(NULL, "open", "http://www.google.com", NULL, NULL, SW_SHOWNORMAL);
                    break;
            }
        }

0
投票

我知道这个问题已经很老了,但希望这个答案可以帮助任何想要直接在

.rc
文件中定义超链接的人。由于
.rc
文件不支持某些转义序列,例如
\"
,因此您必须使用
""
(双引号)。像这样:

CONTROL "<a href=""<LINK>"">Click Here</a>", IDC_SYSLINK, "SysLink", WS_TABSTOP, 10, 10, 40, 40
© www.soinside.com 2019 - 2024. All rights reserved.