msi: Add support for the hyperlink control.

This commit is contained in:
Hans Leidekker 2013-07-26 17:18:57 +02:00 committed by Alexandre Julliard
parent 4f62fb2eec
commit 3169db2b54
1 changed files with 77 additions and 0 deletions

View File

@ -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])