[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