Add more thmutil window messages to simplify handling control events.
Sean Hall committed
Oct 27, 2021 at 14:42 UTC
bad2e93524f376cfeb76d5231d4b08510bdad033
9 files changed
+564
-213
src/api/burn/balutil/inc/BAFunctions.h
+34
@@ -86,6 +86,8 @@ enum BA_FUNCTIONS_MESSAGE
86
BA_FUNCTIONS_MESSAGE_ONTHEMELOADED = 1024,
87
BA_FUNCTIONS_MESSAGE_WNDPROC,
88
BA_FUNCTIONS_MESSAGE_ONTHEMECONTROLLOADING,
89
+ BA_FUNCTIONS_MESSAGE_ONTHEMECONTROLWMCOMMAND,
90
+ BA_FUNCTIONS_MESSAGE_ONTHEMECONTROLWMNOTIFY,
91
};
92
93
typedef HRESULT(WINAPI *PFN_BA_FUNCTIONS_PROC)(
@@ -126,6 +128,38 @@ struct BA_FUNCTIONS_ONTHEMECONTROLLOADING_RESULTS
128
WORD wId;
129
};
130
131
+struct BA_FUNCTIONS_ONTHEMECONTROLWMCOMMAND_ARGS
132
+{
133
+ DWORD cbSize;
134
+ WPARAM wParam;
135
+ LPCWSTR wzName;
136
+ WORD wId;
137
+ HWND hWnd;
138
+};
139
+
140
+struct BA_FUNCTIONS_ONTHEMECONTROLWMCOMMAND_RESULTS
141
+{
142
+ DWORD cbSize;
143
+ BOOL fProcessed;
144
+ LRESULT lResult;
145
+};
146
+
147
+struct BA_FUNCTIONS_ONTHEMECONTROLWMNOTIFY_ARGS
148
+{
149
+ DWORD cbSize;
150
+ LPNMHDR lParam;
151
+ LPCWSTR wzName;
152
+ WORD wId;
153
+ HWND hWnd;
154
+};
155
+
156
+struct BA_FUNCTIONS_ONTHEMECONTROLWMNOTIFY_RESULTS
157
+{
158
+ DWORD cbSize;
159
+ BOOL fProcessed;
160
+ LRESULT lResult;
161
+};
162
+
163
struct BA_FUNCTIONS_ONTHEMELOADED_ARGS
164
{
165
DWORD cbSize;
src/api/burn/balutil/inc/BalBaseBAFunctions.h
+24
@@ -850,6 +850,30 @@ public: // IBAFunctions
850
return S_OK;
851
}
852
853
+ virtual STDMETHODIMP OnThemeControlWmCommand(
854
+ __in WPARAM /*wParam*/,
855
+ __in LPCWSTR /*wzName*/,
856
+ __in WORD /*wId*/,
857
+ __in HWND /*hWnd*/,
858
+ __inout BOOL* /*pfProcessed*/,
859
+ __inout LRESULT* /*plResult*/
860
+ )
861
+ {
862
+ return S_OK;
863
+ }
864
+
865
+ virtual STDMETHODIMP OnThemeControlWmNotify(
866
+ __in LPNMHDR /*lParam*/,
867
+ __in LPCWSTR /*wzName*/,
868
+ __in WORD /*wId*/,
869
+ __in HWND /*hWnd*/,
870
+ __inout BOOL* /*pfProcessed*/,
871
+ __inout LRESULT* /*plResult*/
872
+ )
873
+ {
874
+ return S_OK;
875
+ }
876
+
877
protected:
878
CBalBaseBAFunctions(
879
__in HMODULE hModule,
src/api/burn/balutil/inc/BalBaseBAFunctionsProc.h
+24
@@ -33,6 +33,24 @@ static HRESULT BalBaseBAFunctionsProcOnThemeControlLoading(
33
return pBAFunctions->OnThemeControlLoading(pArgs->wzName, &pResults->fProcessed, &pResults->wId);
34
}
35
36
+static HRESULT BalBaseBAFunctionsProcOnThemeControlWmCommand(
37
+ __in IBAFunctions* pBAFunctions,
38
+ __in BA_FUNCTIONS_ONTHEMECONTROLWMCOMMAND_ARGS* pArgs,
39
+ __inout BA_FUNCTIONS_ONTHEMECONTROLWMCOMMAND_RESULTS* pResults
40
+ )
41
+{
42
+ return pBAFunctions->OnThemeControlWmCommand(pArgs->wParam, pArgs->wzName, pArgs->wId, pArgs->hWnd, &pResults->fProcessed, &pResults->lResult);
43
+}
44
+
45
+static HRESULT BalBaseBAFunctionsProcOnThemeControlWmNotify(
46
+ __in IBAFunctions* pBAFunctions,
47
+ __in BA_FUNCTIONS_ONTHEMECONTROLWMNOTIFY_ARGS* pArgs,
48
+ __inout BA_FUNCTIONS_ONTHEMECONTROLWMNOTIFY_RESULTS* pResults
49
+ )
50
+{
51
+ return pBAFunctions->OnThemeControlWmNotify(pArgs->lParam, pArgs->wzName, pArgs->wId, pArgs->hWnd, &pResults->fProcessed, &pResults->lResult);
52
+}
53
+
54
/*******************************************************************
55
BalBaseBAFunctionsProc - requires pvContext to be of type IBAFunctions.
56
Provides a default mapping between the message based BAFunctions interface and
@@ -137,6 +155,12 @@ static HRESULT WINAPI BalBaseBAFunctionsProc(
155
case BA_FUNCTIONS_MESSAGE_ONTHEMECONTROLLOADING:
156
hr = BalBaseBAFunctionsProcOnThemeControlLoading(pBAFunctions, reinterpret_cast<BA_FUNCTIONS_ONTHEMECONTROLLOADING_ARGS*>(pvArgs), reinterpret_cast<BA_FUNCTIONS_ONTHEMECONTROLLOADING_RESULTS*>(pvResults));
157
break;
158
+ case BA_FUNCTIONS_MESSAGE_ONTHEMECONTROLWMCOMMAND:
159
+ hr = BalBaseBAFunctionsProcOnThemeControlWmCommand(pBAFunctions, reinterpret_cast<BA_FUNCTIONS_ONTHEMECONTROLWMCOMMAND_ARGS*>(pvArgs), reinterpret_cast<BA_FUNCTIONS_ONTHEMECONTROLWMCOMMAND_RESULTS*>(pvResults));
160
+ break;
161
+ case BA_FUNCTIONS_MESSAGE_ONTHEMECONTROLWMNOTIFY:
162
+ hr = BalBaseBAFunctionsProcOnThemeControlWmNotify(pBAFunctions, reinterpret_cast<BA_FUNCTIONS_ONTHEMECONTROLWMNOTIFY_ARGS*>(pvArgs), reinterpret_cast<BA_FUNCTIONS_ONTHEMECONTROLWMNOTIFY_RESULTS*>(pvResults));
163
+ break;
164
}
165
}
166
src/api/burn/balutil/inc/IBAFunctions.h
+22
@@ -39,4 +39,26 @@ DECLARE_INTERFACE_IID_(IBAFunctions, IBootstrapperApplication, "0FB445ED-17BD-49
39
__inout BOOL* pfProcessed,
40
__inout WORD* pwId
41
) = 0;
42
+
43
+ // OnThemeControlWmCommand - Called when WM_COMMAND is received for a control.
44
+ //
45
+ STDMETHOD(OnThemeControlWmCommand)(
46
+ __in WPARAM wParam,
47
+ __in LPCWSTR wzName,
48
+ __in WORD wId,
49
+ __in HWND hWnd,
50
+ __inout BOOL* pfProcessed,
51
+ __inout LRESULT* plResult
52
+ ) = 0;
53
+
54
+ // OnThemeControlWmNotify - Called when WM_NOTIFY is received for a control.
55
+ //
56
+ STDMETHOD(OnThemeControlWmNotify)(
57
+ __in LPNMHDR lParam,
58
+ __in LPCWSTR wzName,
59
+ __in WORD wId,
60
+ __in HWND hWnd,
61
+ __inout BOOL* pfProcessed,
62
+ __inout LRESULT* plResult
63
+ ) = 0;
64
};
src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp
+152
-58
@@ -2878,65 +2878,11 @@ private:
2878
pBA->OnShowFailure();
2879
return 0;
2880
2881
- case WM_COMMAND:
2882
- switch (HIWORD(wParam))
2883
- {
2884
- case BN_CLICKED:
2885
- switch (LOWORD(wParam))
2886
- {
2887
- case WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX:
2888
- pBA->OnClickAcceptCheckbox();
2889
- return 0;
2890
-
2891
- case WIXSTDBA_CONTROL_INSTALL_BUTTON:
2892
- pBA->OnClickInstallButton();
2893
- return 0;
2894
-
2895
- case WIXSTDBA_CONTROL_REPAIR_BUTTON:
2896
- pBA->OnClickRepairButton();
2897
- return 0;
2898
-
2899
- case WIXSTDBA_CONTROL_UNINSTALL_BUTTON:
2900
- pBA->OnClickUninstallButton();
2901
- return 0;
2902
-
2903
- case WIXSTDBA_CONTROL_LAUNCH_BUTTON:
2904
- pBA->OnClickLaunchButton();
2905
- return 0;
2906
-
2907
- case WIXSTDBA_CONTROL_SUCCESS_RESTART_BUTTON: __fallthrough;
2908
- case WIXSTDBA_CONTROL_FAILURE_RESTART_BUTTON:
2909
- pBA->OnClickRestartButton();
2910
- return 0;
2911
-
2912
- case WIXSTDBA_CONTROL_PROGRESS_CANCEL_BUTTON:
2913
- pBA->OnClickCloseButton();
2914
- return 0;
2915
- }
2916
- break;
2917
- }
2918
- break;
2881
+ case WM_THMUTIL_CONTROL_WM_COMMAND:
2882
+ return pBA->OnThemeControlWmCommand(reinterpret_cast<THEME_CONTROLWMCOMMAND_ARGS*>(wParam), reinterpret_cast<THEME_CONTROLWMCOMMAND_RESULTS*>(lParam));
2883
2920
- case WM_NOTIFY:
2921
- if (lParam)
2922
- {
2923
- LPNMHDR pnmhdr = reinterpret_cast<LPNMHDR>(lParam);
2924
- switch (pnmhdr->code)
2925
- {
2926
- case NM_CLICK: __fallthrough;
2927
- case NM_RETURN:
2928
- switch (static_cast<DWORD>(pnmhdr->idFrom))
2929
- {
2930
- case WIXSTDBA_CONTROL_EULA_LINK:
2931
- pBA->OnClickEulaLink();
2932
- return 1;
2933
- case WIXSTDBA_CONTROL_FAILURE_LOGFILE_LINK:
2934
- pBA->OnClickLogFileLink();
2935
- return 1;
2936
- }
2937
- }
2938
- }
2939
- break;
2884
+ case WM_THMUTIL_CONTROL_WM_NOTIFY:
2885
+ return pBA->OnThemeControlWmNotify(reinterpret_cast<THEME_CONTROLWMNOTIFY_ARGS*>(wParam), reinterpret_cast<THEME_CONTROLWMNOTIFY_RESULTS*>(lParam));
2886
}
2887
2888
if (pBA && pBA->m_pTaskbarList && uMsg == pBA->m_uTaskbarButtonCreatedMessage)
@@ -3666,6 +3612,154 @@ private:
3612
ReleaseStr(sczLogFile);
3613
}
3614
3615
+ BOOL OnThemeControlWmCommand(
3616
+ __in const THEME_CONTROLWMCOMMAND_ARGS* pArgs,
3617
+ __in THEME_CONTROLWMCOMMAND_RESULTS* pResults
3618
+ )
3619
+ {
3620
+ HRESULT hr = S_OK;
3621
+ BOOL fProcessed = FALSE;
3622
+ BA_FUNCTIONS_ONTHEMECONTROLWMCOMMAND_ARGS themeControlWmCommandArgs = { };
3623
+ BA_FUNCTIONS_ONTHEMECONTROLWMCOMMAND_RESULTS themeControlWmCommandResults = { };
3624
+
3625
+ switch (HIWORD(pArgs->wParam))
3626
+ {
3627
+ case BN_CLICKED:
3628
+ switch (pArgs->pThemeControl->wId)
3629
+ {
3630
+ case WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX:
3631
+ OnClickAcceptCheckbox();
3632
+ fProcessed = TRUE;
3633
+ pResults->lResult = 0;
3634
+ ExitFunction();
3635
+
3636
+ case WIXSTDBA_CONTROL_INSTALL_BUTTON:
3637
+ OnClickInstallButton();
3638
+ fProcessed = TRUE;
3639
+ pResults->lResult = 0;
3640
+ ExitFunction();
3641
+
3642
+ case WIXSTDBA_CONTROL_REPAIR_BUTTON:
3643
+ OnClickRepairButton();
3644
+ fProcessed = TRUE;
3645
+ pResults->lResult = 0;
3646
+ ExitFunction();
3647
+
3648
+ case WIXSTDBA_CONTROL_UNINSTALL_BUTTON:
3649
+ OnClickUninstallButton();
3650
+ fProcessed = TRUE;
3651
+ pResults->lResult = 0;
3652
+ ExitFunction();
3653
+
3654
+ case WIXSTDBA_CONTROL_LAUNCH_BUTTON:
3655
+ OnClickLaunchButton();
3656
+ fProcessed = TRUE;
3657
+ pResults->lResult = 0;
3658
+ ExitFunction();
3659
+
3660
+ case WIXSTDBA_CONTROL_SUCCESS_RESTART_BUTTON: __fallthrough;
3661
+ case WIXSTDBA_CONTROL_FAILURE_RESTART_BUTTON:
3662
+ OnClickRestartButton();
3663
+ fProcessed = TRUE;
3664
+ pResults->lResult = 0;
3665
+ ExitFunction();
3666
+
3667
+ case WIXSTDBA_CONTROL_PROGRESS_CANCEL_BUTTON:
3668
+ OnClickCloseButton();
3669
+ fProcessed = TRUE;
3670
+ pResults->lResult = 0;
3671
+ ExitFunction();
3672
+ }
3673
+ break;
3674
+ }
3675
+
3676
+ if (m_pfnBAFunctionsProc)
3677
+ {
3678
+ themeControlWmCommandArgs.cbSize = sizeof(themeControlWmCommandArgs);
3679
+ themeControlWmCommandArgs.wParam = pArgs->wParam;
3680
+ themeControlWmCommandArgs.wzName = pArgs->pThemeControl->sczName;
3681
+ themeControlWmCommandArgs.wId = pArgs->pThemeControl->wId;
3682
+ themeControlWmCommandArgs.hWnd = pArgs->pThemeControl->hWnd;
3683
+
3684
+ themeControlWmCommandResults.cbSize = sizeof(themeControlWmCommandResults);
3685
+ themeControlWmCommandResults.lResult = pResults->lResult;
3686
+
3687
+ hr = m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONTHEMECONTROLWMCOMMAND, &themeControlWmCommandArgs, &themeControlWmCommandResults, m_pvBAFunctionsProcContext);
3688
+ if (E_NOTIMPL != hr)
3689
+ {
3690
+ BalExitOnFailure(hr, "BAFunctions OnThemeControlWmCommand failed.");
3691
+
3692
+ if (themeControlWmCommandResults.fProcessed)
3693
+ {
3694
+ fProcessed = TRUE;
3695
+ pResults->lResult = themeControlWmCommandResults.lResult;
3696
+ ExitFunction();
3697
+ }
3698
+ }
3699
+ }
3700
+
3701
+LExit:
3702
+ return fProcessed;
3703
+ }
3704
+
3705
+ BOOL OnThemeControlWmNotify(
3706
+ __in const THEME_CONTROLWMNOTIFY_ARGS* pArgs,
3707
+ __in THEME_CONTROLWMNOTIFY_RESULTS* pResults
3708
+ )
3709
+ {
3710
+ HRESULT hr = S_OK;
3711
+ BOOL fProcessed = FALSE;
3712
+ BA_FUNCTIONS_ONTHEMECONTROLWMNOTIFY_ARGS themeControlWmNotifyArgs = { };
3713
+ BA_FUNCTIONS_ONTHEMECONTROLWMNOTIFY_RESULTS themeControlWmNotifyResults = { };
3714
+
3715
+ switch (pArgs->lParam->code)
3716
+ {
3717
+ case NM_CLICK: __fallthrough;
3718
+ case NM_RETURN:
3719
+ switch (pArgs->pThemeControl->wId)
3720
+ {
3721
+ case WIXSTDBA_CONTROL_EULA_LINK:
3722
+ OnClickEulaLink();
3723
+ fProcessed = TRUE;
3724
+ pResults->lResult = 1;
3725
+ ExitFunction();
3726
+ case WIXSTDBA_CONTROL_FAILURE_LOGFILE_LINK:
3727
+ OnClickLogFileLink();
3728
+ fProcessed = TRUE;
3729
+ pResults->lResult = 1;
3730
+ ExitFunction();
3731
+ }
3732
+ }
3733
+
3734
+ if (m_pfnBAFunctionsProc)
3735
+ {
3736
+ themeControlWmNotifyArgs.cbSize = sizeof(themeControlWmNotifyArgs);
3737
+ themeControlWmNotifyArgs.lParam = pArgs->lParam;
3738
+ themeControlWmNotifyArgs.wzName = pArgs->pThemeControl->sczName;
3739
+ themeControlWmNotifyArgs.wId = pArgs->pThemeControl->wId;
3740
+ themeControlWmNotifyArgs.hWnd = pArgs->pThemeControl->hWnd;
3741
+
3742
+ themeControlWmNotifyResults.cbSize = sizeof(themeControlWmNotifyResults);
3743
+ themeControlWmNotifyResults.lResult = pResults->lResult;
3744
+
3745
+ hr = m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONTHEMECONTROLWMCOMMAND, &themeControlWmNotifyArgs, &themeControlWmNotifyResults, m_pvBAFunctionsProcContext);
3746
+ if (E_NOTIMPL != hr)
3747
+ {
3748
+ BalExitOnFailure(hr, "BAFunctions OnThemeControlWmNotify failed.");
3749
+
3750
+ if (themeControlWmNotifyResults.fProcessed)
3751
+ {
3752
+ fProcessed = TRUE;
3753
+ pResults->lResult = themeControlWmNotifyResults.lResult;
3754
+ ExitFunction();
3755
+ }
3756
+ }
3757
+ }
3758
+
3759
+LExit:
3760
+ return fProcessed;
3761
+ }
3762
+
3763
3764
//
3765
// SetState
src/libs/dutil/WixToolset.DUtil/inc/thmutil.h
+34
@@ -103,6 +103,14 @@ typedef enum _WM_THMUTIL
103
// wparam is THEME_LOADINGCONTROL_ARGS* and lparam is THEME_LOADINGCONTROL_RESULTS*.
104
// Return code is TRUE if it was processed.
105
WM_THMUTIL_LOADING_CONTROL = WM_APP - 1,
106
+ // Sent when WM_COMMAND is received for a control.
107
+ // wparam is THEME_CONTROLWMCOMMAND_ARGS* and lparam is THEME_CONTROLWMCOMMAND_RESULTS*.
108
+ // Return code is TRUE if it was processed.
109
+ WM_THMUTIL_CONTROL_WM_COMMAND = WM_APP - 2,
110
+ // Sent when WM_NOTIFY is received for a control.
111
+ // wparam is THEME_CONTROLWMNOTIFY_ARGS* and lparam is THEME_CONTROLWMNOTIFY_RESULTS*.
112
+ // Return code is TRUE to prevent further processing of the message.
113
+ WM_THMUTIL_CONTROL_WM_NOTIFY = WM_APP - 3,
114
} WM_THMUTIL;
115
116
struct THEME_COLUMN
@@ -397,6 +405,32 @@ struct THEME
405
LPVOID pvVariableContext;
406
};
407
408
+typedef struct _THEME_CONTROLWMCOMMAND_ARGS
409
+{
410
+ DWORD cbSize;
411
+ WPARAM wParam;
412
+ const THEME_CONTROL* pThemeControl;
413
+} THEME_CONTROLWMCOMMAND_ARGS;
414
+
415
+typedef struct _THEME_CONTROLWMCOMMAND_RESULTS
416
+{
417
+ DWORD cbSize;
418
+ LRESULT lResult;
419
+} THEME_CONTROLWMCOMMAND_RESULTS;
420
+
421
+typedef struct _THEME_CONTROLWMNOTIFY_ARGS
422
+{
423
+ DWORD cbSize;
424
+ LPNMHDR lParam;
425
+ const THEME_CONTROL* pThemeControl;
426
+} THEME_CONTROLWMNOTIFY_ARGS;
427
+
428
+typedef struct _THEME_CONTROLWMNOTIFY_RESULTS
429
+{
430
+ DWORD cbSize;
431
+ LRESULT lResult;
432
+} THEME_CONTROLWMNOTIFY_RESULTS;
433
+
434
typedef struct _THEME_LOADINGCONTROL_ARGS
435
{
436
DWORD cbSize;
src/libs/dutil/WixToolset.DUtil/thmutil.cpp
+213
-89
@@ -421,12 +421,10 @@ static void CALLBACK OnBillboardTimer(
421
);
422
static void OnBrowseDirectory(
423
__in THEME* pTheme,
424
- __in HWND hWnd,
424
__in const THEME_ACTION* pAction
425
);
426
static BOOL OnButtonClicked(
427
__in THEME* pTheme,
429
- __in HWND hWnd,
428
__in const THEME_CONTROL* pControl
429
);
430
static BOOL OnDpiChanged(
@@ -434,20 +432,37 @@ static BOOL OnDpiChanged(
432
__in WPARAM wParam,
433
__in LPARAM lParam
434
);
435
+static BOOL OnHypertextClicked(
436
+ __in THEME* pTheme,
437
+ __in const THEME_CONTROL* pThemeControl,
438
+ __in PNMLINK pnmlink
439
+ );
440
static void OnNcCreate(
441
__in THEME* pTheme,
442
__in HWND hWnd,
443
__in LPARAM lParam
444
);
442
-static HRESULT OnRichEditEnLink(
443
- __in LPARAM lParam,
444
- __in HWND hWndRichEdit,
445
- __in HWND hWnd
445
+static BOOL OnNotifyEnLink(
446
+ __in THEME* pTheme,
447
+ __in const THEME_CONTROL* pThemeControl,
448
+ __in ENLINK* link
449
);
447
-static BOOL ControlIsType(
448
- __in const THEME* pTheme,
449
- __in DWORD dwControl,
450
- __in THEME_CONTROL_TYPE type
450
+static BOOL OnNotifyEnMsgFilter(
451
+ __in THEME* pTheme,
452
+ __in const THEME_CONTROL* pThemeControl,
453
+ __in MSGFILTER* msgFilter
454
+ );
455
+static BOOL OnWmCommand(
456
+ __in THEME* pTheme,
457
+ __in WPARAM wParam,
458
+ __in const THEME_CONTROL* pThemeControl,
459
+ __inout LRESULT* plResult
460
+ );
461
+static BOOL OnWmNotify(
462
+ __in THEME* pTheme,
463
+ __in LPNMHDR lParam,
464
+ __in const THEME_CONTROL* pThemeControl,
465
+ __inout LRESULT* plResult
466
);
467
static const THEME_CONTROL* FindControlFromHWnd(
468
__in const THEME* pTheme,
@@ -5089,7 +5104,6 @@ static void CALLBACK OnBillboardTimer(
5104
5105
static void OnBrowseDirectory(
5106
__in THEME* pTheme,
5092
- __in HWND hWnd,
5107
__in const THEME_ACTION* pAction
5108
)
5109
{
@@ -5098,7 +5112,7 @@ static void OnBrowseDirectory(
5112
BROWSEINFOW browseInfo = { };
5113
PIDLIST_ABSOLUTE pidl = NULL;
5114
5101
- browseInfo.hwndOwner = hWnd;
5115
+ browseInfo.hwndOwner = pTheme->hwndParent;
5116
browseInfo.pszDisplayName = wzPath;
5117
browseInfo.lpszTitle = pTheme->sczCaption;
5118
browseInfo.ulFlags = BIF_RETURNONLYFSDIRS | BIF_USENEWUI;
@@ -5148,7 +5162,6 @@ LExit:
5162
5163
static BOOL OnButtonClicked(
5164
__in THEME* pTheme,
5151
- __in HWND hWnd,
5165
__in const THEME_CONTROL* pControl
5166
)
5167
{
@@ -5191,11 +5204,11 @@ static BOOL OnButtonClicked(
5204
switch (pChosenAction->type)
5205
{
5206
case THEME_ACTION_TYPE_BROWSE_DIRECTORY:
5194
- OnBrowseDirectory(pTheme, hWnd, pChosenAction);
5207
+ OnBrowseDirectory(pTheme, pChosenAction);
5208
break;
5209
5210
case THEME_ACTION_TYPE_CLOSE_WINDOW:
5198
- ::SendMessageW(hWnd, WM_CLOSE, 0, 0);
5211
+ ::SendMessageW(pTheme->hwndParent, WM_CLOSE, 0, 0);
5212
break;
5213
5214
case THEME_ACTION_TYPE_CHANGE_PAGE:
@@ -5272,6 +5285,25 @@ LExit:
5285
return !fIgnored;
5286
}
5287
5288
+static BOOL OnHypertextClicked(
5289
+ __in THEME* pTheme,
5290
+ __in const THEME_CONTROL* /*pThemeControl*/,
5291
+ __in PNMLINK pnmlink
5292
+ )
5293
+{
5294
+ BOOL fProcessed = FALSE;
5295
+ HRESULT hr = S_OK;
5296
+ LITEM litem = pnmlink->item;
5297
+
5298
+ hr = ShelExec(litem.szUrl, NULL, L"open", NULL, SW_SHOWDEFAULT, pTheme->hwndParent, NULL);
5299
+ ThmExitOnFailure(hr, "Failed to launch hypertext link: %ls", litem.szUrl);
5300
+
5301
+ fProcessed = TRUE;
5302
+
5303
+LExit:
5304
+ return fProcessed;
5305
+}
5306
+
5307
static void OnNcCreate(
5308
__in THEME* pTheme,
5309
__in HWND hWnd,
@@ -5291,63 +5323,185 @@ static void OnNcCreate(
5323
}
5324
}
5325
5294
-static HRESULT OnRichEditEnLink(
5295
- __in LPARAM lParam,
5296
- __in HWND hWndRichEdit,
5297
- __in HWND hWnd
5326
+static BOOL OnNotifyEnLink(
5327
+ __in THEME* pTheme,
5328
+ __in const THEME_CONTROL* pThemeControl,
5329
+ __in ENLINK* link
5330
)
5331
{
5332
+ BOOL fProcessed = FALSE;
5333
HRESULT hr = S_OK;
5334
LPWSTR sczLink = NULL;
5302
- ENLINK* link = reinterpret_cast<ENLINK*>(lParam);
5335
+ TEXTRANGEW tr = { };
5336
5304
- switch (link->msg)
5337
+ // Hyperlink clicks from rich-edit control.
5338
+ if (THEME_CONTROL_TYPE_RICHEDIT == pThemeControl->type)
5339
{
5306
- case WM_LBUTTONDOWN:
5340
+ switch (link->msg)
5341
{
5308
- hr = StrAlloc(&sczLink, link->chrg.cpMax - link->chrg.cpMin + 2);
5309
- ThmExitOnFailure(hr, "Failed to allocate string for link.");
5342
+ case WM_LBUTTONDOWN:
5343
+ hr = StrAlloc(&sczLink, (SIZE_T)2 + link->chrg.cpMax - link->chrg.cpMin);
5344
+ ThmExitOnFailure(hr, "Failed to allocate string for link.");
5345
5311
- TEXTRANGEW tr;
5312
- tr.chrg.cpMin = link->chrg.cpMin;
5313
- tr.chrg.cpMax = link->chrg.cpMax;
5314
- tr.lpstrText = sczLink;
5346
+ tr.chrg.cpMin = link->chrg.cpMin;
5347
+ tr.chrg.cpMax = link->chrg.cpMax;
5348
+ tr.lpstrText = sczLink;
5349
5316
- if (0 < ::SendMessageW(hWndRichEdit, EM_GETTEXTRANGE, 0, reinterpret_cast<LPARAM>(&tr)))
5317
- {
5318
- hr = ShelExec(sczLink, NULL, L"open", NULL, SW_SHOWDEFAULT, hWnd, NULL);
5319
- ThmExitOnFailure(hr, "Failed to launch link: %ls", sczLink);
5350
+ if (0 < ::SendMessageW(pThemeControl->hWnd, EM_GETTEXTRANGE, 0, reinterpret_cast<LPARAM>(&tr)))
5351
+ {
5352
+ hr = ShelExec(sczLink, NULL, L"open", NULL, SW_SHOWDEFAULT, pTheme->hwndParent, NULL);
5353
+ ThmExitOnFailure(hr, "Failed to launch link: %ls", sczLink);
5354
+
5355
+ fProcessed = TRUE;
5356
+ }
5357
+
5358
+ break;
5359
+
5360
+ case WM_SETCURSOR:
5361
+ ::SetCursor(vhCursorHand);
5362
+ fProcessed = TRUE;
5363
+
5364
+ break;
5365
}
5321
-
5322
- break;
5366
+ }
5367
+
5368
+LExit:
5369
+ ReleaseStr(sczLink);
5370
+
5371
+ return fProcessed;
5372
+}
5373
+
5374
+static BOOL OnNotifyEnMsgFilter(
5375
+ __in THEME* pTheme,
5376
+ __in const THEME_CONTROL* pThemeControl,
5377
+ __in MSGFILTER* msgFilter
5378
+ )
5379
+{
5380
+ BOOL fProcessed = FALSE;
5381
+
5382
+ // Tab/Shift+Tab support for rich-edit control.
5383
+ if (THEME_CONTROL_TYPE_RICHEDIT == pThemeControl->type)
5384
+ {
5385
+ switch (msgFilter->msg)
5386
+ {
5387
+ case WM_KEYDOWN:
5388
+ if (VK_TAB == msgFilter->wParam)
5389
+ {
5390
+ BOOL fShift = 0x8000 & ::GetKeyState(VK_SHIFT);
5391
+ HWND hwndFocus = ::GetNextDlgTabItem(pTheme->hwndParent, pThemeControl->hWnd, fShift);
5392
+ ::SetFocus(hwndFocus);
5393
+
5394
+ fProcessed = TRUE;
5395
+ }
5396
+ break;
5397
}
5398
+ }
5399
+
5400
+ return fProcessed;
5401
+}
5402
5325
- case WM_SETCURSOR:
5326
- ::SetCursor(vhCursorHand);
5403
+static BOOL OnWmCommand(
5404
+ __in THEME* pTheme,
5405
+ __in WPARAM wParam,
5406
+ __in const THEME_CONTROL* pThemeControl,
5407
+ __inout LRESULT* plResult
5408
+ )
5409
+{
5410
+ BOOL fProcessed = FALSE;
5411
+ THEME_CONTROLWMCOMMAND_ARGS args = { };
5412
+ THEME_CONTROLWMCOMMAND_RESULTS results = { };
5413
+
5414
+ args.cbSize = sizeof(args);
5415
+ args.wParam = wParam;
5416
+ args.pThemeControl = pThemeControl;
5417
+
5418
+ results.cbSize = sizeof(results);
5419
+ results.lResult = *plResult;
5420
+
5421
+ if (::SendMessageW(pTheme->hwndParent, WM_THMUTIL_CONTROL_WM_COMMAND, reinterpret_cast<WPARAM>(&args), reinterpret_cast<LPARAM>(&results)))
5422
+ {
5423
+ fProcessed = TRUE;
5424
+ *plResult = results.lResult;
5425
+ ExitFunction();
5426
+ }
5427
+
5428
+ switch (HIWORD(wParam))
5429
+ {
5430
+ case BN_CLICKED:
5431
+ if (OnButtonClicked(pTheme, pThemeControl))
5432
+ {
5433
+ fProcessed = TRUE;
5434
+ *plResult = 0;
5435
+ ExitFunction();
5436
+ }
5437
break;
5438
}
5439
5440
LExit:
5331
- ReleaseStr(sczLink);
5332
-
5333
- return hr;
5441
+ return fProcessed;
5442
}
5443
5336
-static BOOL ControlIsType(
5337
- __in const THEME* pTheme,
5338
- __in DWORD dwControl,
5339
- __in const THEME_CONTROL_TYPE type
5444
+static BOOL OnWmNotify(
5445
+ __in THEME* pTheme,
5446
+ __in LPNMHDR lParam,
5447
+ __in const THEME_CONTROL* pThemeControl,
5448
+ __inout LRESULT* plResult
5449
)
5450
{
5342
- BOOL fIsType = FALSE;
5343
- HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl);
5344
- if (hWnd)
5451
+ BOOL fProcessed = FALSE;
5452
+ THEME_CONTROLWMNOTIFY_ARGS args = { };
5453
+ THEME_CONTROLWMNOTIFY_RESULTS results = { };
5454
+
5455
+ args.cbSize = sizeof(args);
5456
+ args.lParam = lParam;
5457
+ args.pThemeControl = pThemeControl;
5458
+
5459
+ results.cbSize = sizeof(results);
5460
+ results.lResult = *plResult;
5461
+
5462
+ if (::SendMessageW(pTheme->hwndParent, WM_THMUTIL_CONTROL_WM_NOTIFY, reinterpret_cast<WPARAM>(&args), reinterpret_cast<LPARAM>(&results)))
5463
{
5346
- const THEME_CONTROL* pControl = FindControlFromHWnd(pTheme, hWnd);
5347
- fIsType = (pControl && type == pControl->type);
5464
+ fProcessed = TRUE;
5465
+ *plResult = results.lResult;
5466
+ ExitFunction();
5467
}
5468
5350
- return fIsType;
5469
+ switch (lParam->code)
5470
+ {
5471
+ case EN_MSGFILTER:
5472
+ if (OnNotifyEnMsgFilter(pTheme, pThemeControl, reinterpret_cast<MSGFILTER*>(lParam)))
5473
+ {
5474
+ fProcessed = TRUE;
5475
+ *plResult = 1;
5476
+ ExitFunction();
5477
+ }
5478
+ break;
5479
+
5480
+ case EN_LINK:
5481
+ if (OnNotifyEnLink(pTheme, pThemeControl, reinterpret_cast<ENLINK*>(lParam)))
5482
+ {
5483
+ fProcessed = TRUE;
5484
+ *plResult = 1;
5485
+ ExitFunction();
5486
+ }
5487
+
5488
+ case NM_CLICK: __fallthrough;
5489
+ case NM_RETURN:
5490
+ switch (pThemeControl->type)
5491
+ {
5492
+ case THEME_CONTROL_TYPE_HYPERTEXT:
5493
+ // Clicks on a hypertext/syslink control.
5494
+ if (OnHypertextClicked(pTheme, pThemeControl, reinterpret_cast<PNMLINK>(lParam)))
5495
+ {
5496
+ fProcessed = TRUE;
5497
+ *plResult = 1;
5498
+ ExitFunction();
5499
+ }
5500
+ }
5501
+ }
5502
+
5503
+LExit:
5504
+ return fProcessed;
5505
}
5506
5507
static const THEME_CONTROL* FindControlFromHWnd(
@@ -5780,6 +5934,9 @@ static LRESULT CALLBACK ControlGroupDefWindowProc(
5934
__in LPARAM lParam
5935
)
5936
{
5937
+ LRESULT lres = 0;
5938
+ const THEME_CONTROL* pThemeControl = NULL;
5939
+
5940
if (pTheme)
5941
{
5942
switch (uMsg)
@@ -5827,55 +5984,22 @@ static LRESULT CALLBACK ControlGroupDefWindowProc(
5984
if (lParam)
5985
{
5986
LPNMHDR pnmhdr = reinterpret_cast<LPNMHDR>(lParam);
5830
- switch (pnmhdr->code)
5987
+ pThemeControl = FindControlFromHWnd(pTheme, pnmhdr->hwndFrom);
5988
+ if (pThemeControl && OnWmNotify(pTheme, pnmhdr, pThemeControl, &lres))
5989
{
5832
- // Tab/Shift+Tab support for rich-edit control.
5833
- case EN_MSGFILTER:
5834
- {
5835
- MSGFILTER* msgFilter = reinterpret_cast<MSGFILTER*>(lParam);
5836
- if (WM_KEYDOWN == msgFilter->msg && VK_TAB == msgFilter->wParam)
5837
- {
5838
- BOOL fShift = 0x8000 & ::GetKeyState(VK_SHIFT);
5839
- HWND hwndFocus = ::GetNextDlgTabItem(hWnd, msgFilter->nmhdr.hwndFrom, fShift);
5840
- ::SetFocus(hwndFocus);
5841
- return 1;
5842
- }
5843
- break;
5844
- }
5845
-
5846
- // Hyperlink clicks from rich-edit control.
5847
- case EN_LINK:
5848
- return SUCCEEDED(OnRichEditEnLink(lParam, pnmhdr->hwndFrom, hWnd));
5849
-
5850
- // Clicks on a hypertext/syslink control.
5851
- case NM_CLICK: __fallthrough;
5852
- case NM_RETURN:
5853
- if (ControlIsType(pTheme, static_cast<DWORD>(pnmhdr->idFrom), THEME_CONTROL_TYPE_HYPERTEXT))
5854
- {
5855
- PNMLINK pnmlink = reinterpret_cast<PNMLINK>(lParam);
5856
- LITEM litem = pnmlink->item;
5857
- ShelExec(litem.szUrl, NULL, L"open", NULL, SW_SHOWDEFAULT, hWnd, NULL);
5858
- return 1;
5859
- }
5860
-
5861
- return 0;
5990
+ return lres;
5991
}
5992
}
5993
break;
5994
5995
case WM_COMMAND:
5867
- switch (HIWORD(wParam))
5996
+ if (lParam)
5997
{
5869
- case BN_CLICKED:
5870
- if (lParam)
5998
+ pThemeControl = FindControlFromHWnd(pTheme, (HWND)lParam);
5999
+ if (pThemeControl && OnWmCommand(pTheme, wParam, pThemeControl, &lres))
6000
{
5872
- const THEME_CONTROL* pControl = FindControlFromHWnd(pTheme, (HWND)lParam);
5873
- if (pControl && OnButtonClicked(pTheme, hWnd, pControl))
5874
- {
5875
- return 0;
5876
- }
6001
+ return lres;
6002
}
5878
- break;
6003
}
6004
break;
6005
}
src/samples/thmviewer/thmviewer.cpp
+33
-24
@@ -52,6 +52,10 @@ static BOOL OnThemeLoadingControl(
52
__in const THEME_LOADINGCONTROL_ARGS* pArgs,
53
__in THEME_LOADINGCONTROL_RESULTS* pResults
54
);
55
+static BOOL OnThemeControlWmNotify(
56
+ __in const THEME_CONTROLWMNOTIFY_ARGS* pArgs,
57
+ __in THEME_CONTROLWMNOTIFY_RESULTS* pResults
58
+ );
59
static void CALLBACK ThmviewerTraceError(
60
__in_z LPCSTR szFile,
61
__in int iLine,
@@ -377,32 +381,11 @@ static LRESULT CALLBACK MainWndProc(
381
::PostQuitMessage(0);
382
break;
383
380
- case WM_NOTIFY:
381
- {
382
- NMHDR* pnmhdr = reinterpret_cast<NMHDR*>(lParam);
383
- switch (pnmhdr->code)
384
- {
385
- case TVN_SELCHANGEDW:
386
- {
387
- NMTREEVIEWW* ptv = reinterpret_cast<NMTREEVIEWW*>(lParam);
388
- ::PostThreadMessageW(vdwDisplayThreadId, WM_THMVWR_SHOWPAGE, SW_HIDE, ptv->itemOld.lParam);
389
- ::PostThreadMessageW(vdwDisplayThreadId, WM_THMVWR_SHOWPAGE, SW_SHOW, ptv->itemNew.lParam);
390
- }
391
- break;
392
-
393
- //case NM_DBLCLK:
394
- // TVITEM item = { };
395
- // item.mask = TVIF_PARAM;
396
- // item.hItem = TreeView_GetSelection(pnmhdr->hwndFrom);
397
- // TreeView_GetItem(pnmhdr->hwndFrom, &item);
398
- // ::PostThreadMessageW(vdwDisplayThreadId, WM_THMVWR_SHOWPAGE, SW_SHOW, item.lParam);
399
- // return 1;
400
- }
401
- }
402
- break;
403
-
384
case WM_THMUTIL_LOADING_CONTROL:
385
return OnThemeLoadingControl(reinterpret_cast<THEME_LOADINGCONTROL_ARGS*>(wParam), reinterpret_cast<THEME_LOADINGCONTROL_RESULTS*>(lParam));
386
+
387
+ case WM_THMUTIL_CONTROL_WM_NOTIFY:
388
+ return OnThemeControlWmNotify(reinterpret_cast<THEME_CONTROLWMNOTIFY_ARGS*>(wParam), reinterpret_cast<THEME_CONTROLWMNOTIFY_RESULTS*>(lParam));
389
}
390
391
return ThemeDefWindowProc(vpTheme, hWnd, uMsg, wParam, lParam);
@@ -558,3 +541,29 @@ static BOOL OnThemeLoadingControl(
541
pResults->hr = S_OK;
542
return TRUE;
543
}
544
+
545
+static BOOL OnThemeControlWmNotify(
546
+ __in const THEME_CONTROLWMNOTIFY_ARGS* pArgs,
547
+ __in THEME_CONTROLWMNOTIFY_RESULTS* /*pResults*/
548
+ )
549
+{
550
+ BOOL fProcessed = FALSE;
551
+
552
+ switch (pArgs->lParam->code)
553
+ {
554
+ case TVN_SELCHANGEDW:
555
+ switch (pArgs->pThemeControl->wId)
556
+ {
557
+ case THMVWR_CONTROL_TREE:
558
+ NMTREEVIEWW* ptv = reinterpret_cast<NMTREEVIEWW*>(pArgs->lParam);
559
+ ::PostThreadMessageW(vdwDisplayThreadId, WM_THMVWR_SHOWPAGE, SW_HIDE, ptv->itemOld.lParam);
560
+ ::PostThreadMessageW(vdwDisplayThreadId, WM_THMVWR_SHOWPAGE, SW_SHOW, ptv->itemNew.lParam);
561
+
562
+ fProcessed = TRUE;
563
+ break;
564
+ }
565
+ break;
566
+ }
567
+
568
+ return fProcessed;
569
+}
src/test/burn/TestData/Manual/BafThmutilTesting/BafThmUtilTesting.cpp
+28
-42
@@ -43,62 +43,48 @@ static void CALLBACK BafThmUtilTestingTraceError(
43
class CBafThmUtilTesting : public CBalBaseBAFunctions
44
{
45
public: // IBAFunctions
46
- /*virtual STDMETHODIMP OnThemeLoaded(
47
- THEME* pTheme,
48
- WIX_LOCALIZATION* pWixLoc
46
+ virtual STDMETHODIMP OnThemeControlLoading(
47
+ __in LPCWSTR wzName,
48
+ __inout BOOL* pfProcessed,
49
+ __inout WORD* pwId
50
)
51
{
51
- HRESULT hr = S_OK;
52
-
53
- hr = __super::OnThemeLoaded(pTheme, pWixLoc);
52
+ if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, wzName, -1, L"InstallTestButton", -1))
53
+ {
54
+ *pfProcessed = TRUE;
55
+ *pwId = BAF_CONTROL_INSTALL_TEST_BUTTON;
56
+ }
57
55
- return hr;
56
- }*/
58
+ return S_OK;
59
+ }
60
58
- virtual STDMETHODIMP WndProc(
59
- __in THEME* pTheme,
60
- __in HWND hWnd,
61
- __in UINT uMsg,
61
+ virtual STDMETHODIMP OnThemeControlWmCommand(
62
__in WPARAM wParam,
63
- __in LPARAM lParam,
64
- __inout LRESULT* plRes
63
+ __in LPCWSTR /*wzName*/,
64
+ __in WORD wId,
65
+ __in HWND /*hWnd*/,
66
+ __inout BOOL* pfProcessed,
67
+ __inout LRESULT* plResult
68
)
69
{
67
- switch (uMsg)
70
+ HRESULT hr = S_OK;
71
+
72
+ switch (HIWORD(wParam))
73
{
69
- case WM_COMMAND:
70
- switch (HIWORD(wParam))
74
+ case BN_CLICKED:
75
+ switch (wId)
76
{
72
- case BN_CLICKED:
73
- switch (LOWORD(wParam))
74
- {
75
- case BAF_CONTROL_INSTALL_TEST_BUTTON:
76
- OnShowTheme();
77
- *plRes = 0;
78
- return S_OK;
79
- }
80
-
77
+ case BAF_CONTROL_INSTALL_TEST_BUTTON:
78
+ OnShowTheme();
79
+ *pfProcessed = TRUE;
80
+ *plResult = 0;
81
break;
82
}
83
- break;
84
- }
85
-
86
- return __super::WndProc(pTheme, hWnd, uMsg, wParam, lParam, plRes);
87
- }
83
89
- virtual STDMETHODIMP OnThemeControlLoading(
90
- __in LPCWSTR wzName,
91
- __inout BOOL* pfProcessed,
92
- __inout WORD* pwId
93
- )
94
- {
95
- if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, wzName, -1, L"InstallTestButton", -1))
96
- {
97
- *pfProcessed = TRUE;
98
- *pwId = BAF_CONTROL_INSTALL_TEST_BUTTON;
84
+ break;
85
}
86
101
- return S_OK;
87
+ return hr;
88
}
89
90
private: