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

C++ c++;win32将超链接添加到对话框,c++,winapi,hyperlink,dialog,C++,Winapi,Hyperlink,Dialog,我想在我的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 M

我想在我的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    
您可以在Windows XP或更高版本上使用

您可以从.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    
在resource.rc中:

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

在没有任何外部库的情况下进行高亮显示的最佳方法,仍然与任何控件的外观和感觉相同,甚至可以将鼠标光标变成手指指向的图标

/* 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;
            }
        }

SYSLink和MFCLink控件都使整个对话框窗口与任何其他控件一样为空,就像它使所有控件都不可见一样。。不知道为什么..@SSpoke:只是好奇空白对话框是否是用function@LaurieStearn没有我使用的
tab1\u hwnd=CreateDialog(hDLLModule,MAKEINTRESOURCE(IDD\u TAB\u 1),hDlg,DialogPage)默认情况下它是隐藏的,我通过
ShowWindow
ShowWindow(tab1\uhwnd,(当前可见\uu选中\utab==0)?SW SHOW:SW\u HIDE)启用它
找到了一个很好的解决方案,如果有人需要,我可以发布。。它需要子类化,但仍然相当小且可移植。当您将鼠标放在标签上时,如果单击它,只需更改颜色即可
ShellExecute(NULL,“open”,“http://blah.com“,NULL,NULL,SW_SHOWNORMAL)
@SSpoke:很高兴知道,但在这里尝试一下,我会尽快回来的,谢谢。:)为了工作,我必须添加以下行:#pragma comment(链接器,“/manifestdependency:\”type='win32'name='Microsoft.Windows.Common Controls'version='6.0.0.0'processorArchitecture='x86'publicKeyToken='6595b64144ccf1df'language='*\'')漂亮!(此处为winhlp32.exe)。还有另一个很好的解释,来自的错误代码让它变得更强大了。