Module: wine Branch: master Commit: 3169db2b5423c3a4a3710138b738fc7194389a05 URL: http://source.winehq.org/git/wine.git/?a=commit;h=3169db2b5423c3a4a3710138b7...
Author: Hans Leidekker hans@codeweavers.com Date: Fri Jul 26 17:18:57 2013 +0200
msi: Add support for the hyperlink control.
---
dlls/msi/dialog.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 77 insertions(+), 0 deletions(-)
diff --git a/dlls/msi/dialog.c b/dlls/msi/dialog.c index 662d09a..80e2d68 100644 --- a/dlls/msi/dialog.c +++ b/dlls/msi/dialog.c @@ -39,6 +39,7 @@ #include "winreg.h" #include "shlwapi.h" #include "msiserver.h" +#include "shellapi.h"
#include "wine/debug.h" #include "wine/unicode.h" @@ -144,6 +145,7 @@ static const WCHAR szVolumeSelectCombo[] = { 'V','o','l','u','m','e','S','e','l' static const WCHAR szSelectionDescription[] = {'S','e','l','e','c','t','i','o','n','D','e','s','c','r','i','p','t','i','o','n',0}; static const WCHAR szSelectionPath[] = {'S','e','l','e','c','t','i','o','n','P','a','t','h',0}; static const WCHAR szProperty[] = {'P','r','o','p','e','r','t','y',0}; +static const WCHAR szHyperLink[] = {'H','y','p','e','r','L','i','n','k',0};
/* dialog sequencing */
@@ -3306,6 +3308,80 @@ static UINT msi_dialog_volumeselect_combo( msi_dialog *dialog, MSIRECORD *rec ) return ERROR_SUCCESS; }
+static UINT msi_dialog_hyperlink_handler( msi_dialog *dialog, msi_control *control, WPARAM param ) +{ + static const WCHAR hrefW[] = {'h','r','e','f'}; + static const WCHAR openW[] = {'o','p','e','n',0}; + int len, len_href = sizeof(hrefW) / sizeof(hrefW[0]); + const WCHAR *p, *q; + WCHAR quote = 0; + LITEM item; + + item.mask = LIF_ITEMINDEX | LIF_URL; + item.iLink = 0; + item.szUrl[0] = 0; + + SendMessageW( control->hwnd, LM_GETITEM, 0, (LPARAM)&item ); + + p = item.szUrl; + while (*p && *p != '<') p++; + if (!*p++) return ERROR_SUCCESS; + if (toupperW( *p++ ) != 'A' || !isspaceW( *p++ )) return ERROR_SUCCESS; + while (*p && isspaceW( *p )) p++; + + len = strlenW( p ); + if (len > len_href && !memicmpW( p, hrefW, len_href )) + { + p += len_href; + while (*p && isspaceW( *p )) p++; + if (!*p || *p++ != '=') return ERROR_SUCCESS; + while (*p && isspaceW( *p )) p++; + + if (*p == '"' || *p == ''') quote = *p++; + q = p; + if (quote) + { + while (*q && *q != quote) q++; + if (*q != quote) return ERROR_SUCCESS; + } + else + { + while (*q && *q != '>' && !isspaceW( *q )) q++; + if (!*q) return ERROR_SUCCESS; + } + item.szUrl[q - item.szUrl] = 0; + ShellExecuteW( NULL, openW, p, NULL, NULL, SW_SHOWNORMAL ); + } + return ERROR_SUCCESS; +} + +static UINT msi_dialog_hyperlink( msi_dialog *dialog, MSIRECORD *rec ) +{ + msi_control *control; + DWORD style = WS_CHILD | WS_TABSTOP | WS_GROUP; + const WCHAR *text = MSI_RecordGetString( rec, 10 ); + int len = strlenW( text ); + LITEM item; + + control = msi_dialog_add_control( dialog, rec, WC_LINK, style ); + if (!control) + return ERROR_FUNCTION_FAILED; + + control->attributes = MSI_RecordGetInteger( rec, 8 ); + control->handler = msi_dialog_hyperlink_handler; + + item.mask = LIF_ITEMINDEX | LIF_STATE | LIF_URL; + item.iLink = 0; + item.state = LIS_ENABLED; + item.stateMask = LIS_ENABLED; + if (len < L_MAX_URL_LENGTH) strcpyW( item.szUrl, text ); + else item.szUrl[0] = 0; + + SendMessageW( control->hwnd, LM_SETITEM, 0, (LPARAM)&item ); + + return ERROR_SUCCESS; +} + static const struct control_handler msi_dialog_handler[] = { { szText, msi_dialog_text_control }, @@ -3328,6 +3404,7 @@ static const struct control_handler msi_dialog_handler[] = { szDirectoryList, msi_dialog_directory_list }, { szVolumeCostList, msi_dialog_volumecost_list }, { szVolumeSelectCombo, msi_dialog_volumeselect_combo }, + { szHyperLink, msi_dialog_hyperlink } };
#define NUM_CONTROL_TYPES (sizeof msi_dialog_handler/sizeof msi_dialog_handler[0])