[1/4] msi: Add support for the hyperlink control.
Hans Leidekker
hans at codeweavers.com
Fri Jul 26 10:18:57 CDT 2013
---
dlls/msi/dialog.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 77 insertions(+)
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])
--
1.7.10.4
More information about the wine-patches
mailing list