From bad2e93524f376cfeb76d5231d4b08510bdad033 Mon Sep 17 00:00:00 2001 From: Sean Hall <r.sean.hall@gmail.com> Date: Wed, 27 Oct 2021 14:42:32 -0500 Subject: Add more thmutil window messages to simplify handling control events. --- src/api/burn/balutil/inc/BAFunctions.h | 34 +++ src/api/burn/balutil/inc/BalBaseBAFunctions.h | 24 ++ src/api/burn/balutil/inc/BalBaseBAFunctionsProc.h | 24 ++ src/api/burn/balutil/inc/IBAFunctions.h | 22 ++ .../WixStandardBootstrapperApplication.cpp | 210 ++++++++++---- src/libs/dutil/WixToolset.DUtil/inc/thmutil.h | 34 +++ src/libs/dutil/WixToolset.DUtil/thmutil.cpp | 302 +++++++++++++++------ src/samples/thmviewer/thmviewer.cpp | 57 ++-- .../Manual/BafThmutilTesting/BafThmUtilTesting.cpp | 70 ++--- 9 files changed, 564 insertions(+), 213 deletions(-) (limited to 'src') diff --git a/src/api/burn/balutil/inc/BAFunctions.h b/src/api/burn/balutil/inc/BAFunctions.h index 2a34aaad..ab6ea4d7 100644 --- a/src/api/burn/balutil/inc/BAFunctions.h +++ b/src/api/burn/balutil/inc/BAFunctions.h @@ -86,6 +86,8 @@ enum BA_FUNCTIONS_MESSAGE BA_FUNCTIONS_MESSAGE_ONTHEMELOADED = 1024, BA_FUNCTIONS_MESSAGE_WNDPROC, BA_FUNCTIONS_MESSAGE_ONTHEMECONTROLLOADING, + BA_FUNCTIONS_MESSAGE_ONTHEMECONTROLWMCOMMAND, + BA_FUNCTIONS_MESSAGE_ONTHEMECONTROLWMNOTIFY, }; typedef HRESULT(WINAPI *PFN_BA_FUNCTIONS_PROC)( @@ -126,6 +128,38 @@ struct BA_FUNCTIONS_ONTHEMECONTROLLOADING_RESULTS WORD wId; }; +struct BA_FUNCTIONS_ONTHEMECONTROLWMCOMMAND_ARGS +{ + DWORD cbSize; + WPARAM wParam; + LPCWSTR wzName; + WORD wId; + HWND hWnd; +}; + +struct BA_FUNCTIONS_ONTHEMECONTROLWMCOMMAND_RESULTS +{ + DWORD cbSize; + BOOL fProcessed; + LRESULT lResult; +}; + +struct BA_FUNCTIONS_ONTHEMECONTROLWMNOTIFY_ARGS +{ + DWORD cbSize; + LPNMHDR lParam; + LPCWSTR wzName; + WORD wId; + HWND hWnd; +}; + +struct BA_FUNCTIONS_ONTHEMECONTROLWMNOTIFY_RESULTS +{ + DWORD cbSize; + BOOL fProcessed; + LRESULT lResult; +}; + struct BA_FUNCTIONS_ONTHEMELOADED_ARGS { DWORD cbSize; diff --git a/src/api/burn/balutil/inc/BalBaseBAFunctions.h b/src/api/burn/balutil/inc/BalBaseBAFunctions.h index c2c8a6dc..f6c33f58 100644 --- a/src/api/burn/balutil/inc/BalBaseBAFunctions.h +++ b/src/api/burn/balutil/inc/BalBaseBAFunctions.h @@ -850,6 +850,30 @@ public: // IBAFunctions return S_OK; } + virtual STDMETHODIMP OnThemeControlWmCommand( + __in WPARAM /*wParam*/, + __in LPCWSTR /*wzName*/, + __in WORD /*wId*/, + __in HWND /*hWnd*/, + __inout BOOL* /*pfProcessed*/, + __inout LRESULT* /*plResult*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnThemeControlWmNotify( + __in LPNMHDR /*lParam*/, + __in LPCWSTR /*wzName*/, + __in WORD /*wId*/, + __in HWND /*hWnd*/, + __inout BOOL* /*pfProcessed*/, + __inout LRESULT* /*plResult*/ + ) + { + return S_OK; + } + protected: CBalBaseBAFunctions( __in HMODULE hModule, diff --git a/src/api/burn/balutil/inc/BalBaseBAFunctionsProc.h b/src/api/burn/balutil/inc/BalBaseBAFunctionsProc.h index efe22ddd..1d51c5b6 100644 --- a/src/api/burn/balutil/inc/BalBaseBAFunctionsProc.h +++ b/src/api/burn/balutil/inc/BalBaseBAFunctionsProc.h @@ -33,6 +33,24 @@ static HRESULT BalBaseBAFunctionsProcOnThemeControlLoading( return pBAFunctions->OnThemeControlLoading(pArgs->wzName, &pResults->fProcessed, &pResults->wId); } +static HRESULT BalBaseBAFunctionsProcOnThemeControlWmCommand( + __in IBAFunctions* pBAFunctions, + __in BA_FUNCTIONS_ONTHEMECONTROLWMCOMMAND_ARGS* pArgs, + __inout BA_FUNCTIONS_ONTHEMECONTROLWMCOMMAND_RESULTS* pResults + ) +{ + return pBAFunctions->OnThemeControlWmCommand(pArgs->wParam, pArgs->wzName, pArgs->wId, pArgs->hWnd, &pResults->fProcessed, &pResults->lResult); +} + +static HRESULT BalBaseBAFunctionsProcOnThemeControlWmNotify( + __in IBAFunctions* pBAFunctions, + __in BA_FUNCTIONS_ONTHEMECONTROLWMNOTIFY_ARGS* pArgs, + __inout BA_FUNCTIONS_ONTHEMECONTROLWMNOTIFY_RESULTS* pResults + ) +{ + return pBAFunctions->OnThemeControlWmNotify(pArgs->lParam, pArgs->wzName, pArgs->wId, pArgs->hWnd, &pResults->fProcessed, &pResults->lResult); +} + /******************************************************************* BalBaseBAFunctionsProc - requires pvContext to be of type IBAFunctions. Provides a default mapping between the message based BAFunctions interface and @@ -137,6 +155,12 @@ static HRESULT WINAPI BalBaseBAFunctionsProc( case BA_FUNCTIONS_MESSAGE_ONTHEMECONTROLLOADING: hr = BalBaseBAFunctionsProcOnThemeControlLoading(pBAFunctions, reinterpret_cast<BA_FUNCTIONS_ONTHEMECONTROLLOADING_ARGS*>(pvArgs), reinterpret_cast<BA_FUNCTIONS_ONTHEMECONTROLLOADING_RESULTS*>(pvResults)); break; + case BA_FUNCTIONS_MESSAGE_ONTHEMECONTROLWMCOMMAND: + hr = BalBaseBAFunctionsProcOnThemeControlWmCommand(pBAFunctions, reinterpret_cast<BA_FUNCTIONS_ONTHEMECONTROLWMCOMMAND_ARGS*>(pvArgs), reinterpret_cast<BA_FUNCTIONS_ONTHEMECONTROLWMCOMMAND_RESULTS*>(pvResults)); + break; + case BA_FUNCTIONS_MESSAGE_ONTHEMECONTROLWMNOTIFY: + hr = BalBaseBAFunctionsProcOnThemeControlWmNotify(pBAFunctions, reinterpret_cast<BA_FUNCTIONS_ONTHEMECONTROLWMNOTIFY_ARGS*>(pvArgs), reinterpret_cast<BA_FUNCTIONS_ONTHEMECONTROLWMNOTIFY_RESULTS*>(pvResults)); + break; } } diff --git a/src/api/burn/balutil/inc/IBAFunctions.h b/src/api/burn/balutil/inc/IBAFunctions.h index d41b7c9b..63395e1e 100644 --- a/src/api/burn/balutil/inc/IBAFunctions.h +++ b/src/api/burn/balutil/inc/IBAFunctions.h @@ -39,4 +39,26 @@ DECLARE_INTERFACE_IID_(IBAFunctions, IBootstrapperApplication, "0FB445ED-17BD-49 __inout BOOL* pfProcessed, __inout WORD* pwId ) = 0; + + // OnThemeControlWmCommand - Called when WM_COMMAND is received for a control. + // + STDMETHOD(OnThemeControlWmCommand)( + __in WPARAM wParam, + __in LPCWSTR wzName, + __in WORD wId, + __in HWND hWnd, + __inout BOOL* pfProcessed, + __inout LRESULT* plResult + ) = 0; + + // OnThemeControlWmNotify - Called when WM_NOTIFY is received for a control. + // + STDMETHOD(OnThemeControlWmNotify)( + __in LPNMHDR lParam, + __in LPCWSTR wzName, + __in WORD wId, + __in HWND hWnd, + __inout BOOL* pfProcessed, + __inout LRESULT* plResult + ) = 0; }; diff --git a/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp b/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp index 8cdd31ce..2283880c 100644 --- a/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp +++ b/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp @@ -2878,65 +2878,11 @@ private: pBA->OnShowFailure(); return 0; - case WM_COMMAND: - switch (HIWORD(wParam)) - { - case BN_CLICKED: - switch (LOWORD(wParam)) - { - case WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX: - pBA->OnClickAcceptCheckbox(); - return 0; - - case WIXSTDBA_CONTROL_INSTALL_BUTTON: - pBA->OnClickInstallButton(); - return 0; - - case WIXSTDBA_CONTROL_REPAIR_BUTTON: - pBA->OnClickRepairButton(); - return 0; - - case WIXSTDBA_CONTROL_UNINSTALL_BUTTON: - pBA->OnClickUninstallButton(); - return 0; - - case WIXSTDBA_CONTROL_LAUNCH_BUTTON: - pBA->OnClickLaunchButton(); - return 0; - - case WIXSTDBA_CONTROL_SUCCESS_RESTART_BUTTON: __fallthrough; - case WIXSTDBA_CONTROL_FAILURE_RESTART_BUTTON: - pBA->OnClickRestartButton(); - return 0; - - case WIXSTDBA_CONTROL_PROGRESS_CANCEL_BUTTON: - pBA->OnClickCloseButton(); - return 0; - } - break; - } - break; + case WM_THMUTIL_CONTROL_WM_COMMAND: + return pBA->OnThemeControlWmCommand(reinterpret_cast<THEME_CONTROLWMCOMMAND_ARGS*>(wParam), reinterpret_cast<THEME_CONTROLWMCOMMAND_RESULTS*>(lParam)); - case WM_NOTIFY: - if (lParam) - { - LPNMHDR pnmhdr = reinterpret_cast<LPNMHDR>(lParam); - switch (pnmhdr->code) - { - case NM_CLICK: __fallthrough; - case NM_RETURN: - switch (static_cast<DWORD>(pnmhdr->idFrom)) - { - case WIXSTDBA_CONTROL_EULA_LINK: - pBA->OnClickEulaLink(); - return 1; - case WIXSTDBA_CONTROL_FAILURE_LOGFILE_LINK: - pBA->OnClickLogFileLink(); - return 1; - } - } - } - break; + case WM_THMUTIL_CONTROL_WM_NOTIFY: + return pBA->OnThemeControlWmNotify(reinterpret_cast<THEME_CONTROLWMNOTIFY_ARGS*>(wParam), reinterpret_cast<THEME_CONTROLWMNOTIFY_RESULTS*>(lParam)); } if (pBA && pBA->m_pTaskbarList && uMsg == pBA->m_uTaskbarButtonCreatedMessage) @@ -3666,6 +3612,154 @@ private: ReleaseStr(sczLogFile); } + BOOL OnThemeControlWmCommand( + __in const THEME_CONTROLWMCOMMAND_ARGS* pArgs, + __in THEME_CONTROLWMCOMMAND_RESULTS* pResults + ) + { + HRESULT hr = S_OK; + BOOL fProcessed = FALSE; + BA_FUNCTIONS_ONTHEMECONTROLWMCOMMAND_ARGS themeControlWmCommandArgs = { }; + BA_FUNCTIONS_ONTHEMECONTROLWMCOMMAND_RESULTS themeControlWmCommandResults = { }; + + switch (HIWORD(pArgs->wParam)) + { + case BN_CLICKED: + switch (pArgs->pThemeControl->wId) + { + case WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX: + OnClickAcceptCheckbox(); + fProcessed = TRUE; + pResults->lResult = 0; + ExitFunction(); + + case WIXSTDBA_CONTROL_INSTALL_BUTTON: + OnClickInstallButton(); + fProcessed = TRUE; + pResults->lResult = 0; + ExitFunction(); + + case WIXSTDBA_CONTROL_REPAIR_BUTTON: + OnClickRepairButton(); + fProcessed = TRUE; + pResults->lResult = 0; + ExitFunction(); + + case WIXSTDBA_CONTROL_UNINSTALL_BUTTON: + OnClickUninstallButton(); + fProcessed = TRUE; + pResults->lResult = 0; + ExitFunction(); + + case WIXSTDBA_CONTROL_LAUNCH_BUTTON: + OnClickLaunchButton(); + fProcessed = TRUE; + pResults->lResult = 0; + ExitFunction(); + + case WIXSTDBA_CONTROL_SUCCESS_RESTART_BUTTON: __fallthrough; + case WIXSTDBA_CONTROL_FAILURE_RESTART_BUTTON: + OnClickRestartButton(); + fProcessed = TRUE; + pResults->lResult = 0; + ExitFunction(); + + case WIXSTDBA_CONTROL_PROGRESS_CANCEL_BUTTON: + OnClickCloseButton(); + fProcessed = TRUE; + pResults->lResult = 0; + ExitFunction(); + } + break; + } + + if (m_pfnBAFunctionsProc) + { + themeControlWmCommandArgs.cbSize = sizeof(themeControlWmCommandArgs); + themeControlWmCommandArgs.wParam = pArgs->wParam; + themeControlWmCommandArgs.wzName = pArgs->pThemeControl->sczName; + themeControlWmCommandArgs.wId = pArgs->pThemeControl->wId; + themeControlWmCommandArgs.hWnd = pArgs->pThemeControl->hWnd; + + themeControlWmCommandResults.cbSize = sizeof(themeControlWmCommandResults); + themeControlWmCommandResults.lResult = pResults->lResult; + + hr = m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONTHEMECONTROLWMCOMMAND, &themeControlWmCommandArgs, &themeControlWmCommandResults, m_pvBAFunctionsProcContext); + if (E_NOTIMPL != hr) + { + BalExitOnFailure(hr, "BAFunctions OnThemeControlWmCommand failed."); + + if (themeControlWmCommandResults.fProcessed) + { + fProcessed = TRUE; + pResults->lResult = themeControlWmCommandResults.lResult; + ExitFunction(); + } + } + } + +LExit: + return fProcessed; + } + + BOOL OnThemeControlWmNotify( + __in const THEME_CONTROLWMNOTIFY_ARGS* pArgs, + __in THEME_CONTROLWMNOTIFY_RESULTS* pResults + ) + { + HRESULT hr = S_OK; + BOOL fProcessed = FALSE; + BA_FUNCTIONS_ONTHEMECONTROLWMNOTIFY_ARGS themeControlWmNotifyArgs = { }; + BA_FUNCTIONS_ONTHEMECONTROLWMNOTIFY_RESULTS themeControlWmNotifyResults = { }; + + switch (pArgs->lParam->code) + { + case NM_CLICK: __fallthrough; + case NM_RETURN: + switch (pArgs->pThemeControl->wId) + { + case WIXSTDBA_CONTROL_EULA_LINK: + OnClickEulaLink(); + fProcessed = TRUE; + pResults->lResult = 1; + ExitFunction(); + case WIXSTDBA_CONTROL_FAILURE_LOGFILE_LINK: + OnClickLogFileLink(); + fProcessed = TRUE; + pResults->lResult = 1; + ExitFunction(); + } + } + + if (m_pfnBAFunctionsProc) + { + themeControlWmNotifyArgs.cbSize = sizeof(themeControlWmNotifyArgs); + themeControlWmNotifyArgs.lParam = pArgs->lParam; + themeControlWmNotifyArgs.wzName = pArgs->pThemeControl->sczName; + themeControlWmNotifyArgs.wId = pArgs->pThemeControl->wId; + themeControlWmNotifyArgs.hWnd = pArgs->pThemeControl->hWnd; + + themeControlWmNotifyResults.cbSize = sizeof(themeControlWmNotifyResults); + themeControlWmNotifyResults.lResult = pResults->lResult; + + hr = m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONTHEMECONTROLWMCOMMAND, &themeControlWmNotifyArgs, &themeControlWmNotifyResults, m_pvBAFunctionsProcContext); + if (E_NOTIMPL != hr) + { + BalExitOnFailure(hr, "BAFunctions OnThemeControlWmNotify failed."); + + if (themeControlWmNotifyResults.fProcessed) + { + fProcessed = TRUE; + pResults->lResult = themeControlWmNotifyResults.lResult; + ExitFunction(); + } + } + } + +LExit: + return fProcessed; + } + // // SetState diff --git a/src/libs/dutil/WixToolset.DUtil/inc/thmutil.h b/src/libs/dutil/WixToolset.DUtil/inc/thmutil.h index dc554219..9557c11c 100644 --- a/src/libs/dutil/WixToolset.DUtil/inc/thmutil.h +++ b/src/libs/dutil/WixToolset.DUtil/inc/thmutil.h @@ -103,6 +103,14 @@ typedef enum _WM_THMUTIL // wparam is THEME_LOADINGCONTROL_ARGS* and lparam is THEME_LOADINGCONTROL_RESULTS*. // Return code is TRUE if it was processed. WM_THMUTIL_LOADING_CONTROL = WM_APP - 1, + // Sent when WM_COMMAND is received for a control. + // wparam is THEME_CONTROLWMCOMMAND_ARGS* and lparam is THEME_CONTROLWMCOMMAND_RESULTS*. + // Return code is TRUE if it was processed. + WM_THMUTIL_CONTROL_WM_COMMAND = WM_APP - 2, + // Sent when WM_NOTIFY is received for a control. + // wparam is THEME_CONTROLWMNOTIFY_ARGS* and lparam is THEME_CONTROLWMNOTIFY_RESULTS*. + // Return code is TRUE to prevent further processing of the message. + WM_THMUTIL_CONTROL_WM_NOTIFY = WM_APP - 3, } WM_THMUTIL; struct THEME_COLUMN @@ -397,6 +405,32 @@ struct THEME LPVOID pvVariableContext; }; +typedef struct _THEME_CONTROLWMCOMMAND_ARGS +{ + DWORD cbSize; + WPARAM wParam; + const THEME_CONTROL* pThemeControl; +} THEME_CONTROLWMCOMMAND_ARGS; + +typedef struct _THEME_CONTROLWMCOMMAND_RESULTS +{ + DWORD cbSize; + LRESULT lResult; +} THEME_CONTROLWMCOMMAND_RESULTS; + +typedef struct _THEME_CONTROLWMNOTIFY_ARGS +{ + DWORD cbSize; + LPNMHDR lParam; + const THEME_CONTROL* pThemeControl; +} THEME_CONTROLWMNOTIFY_ARGS; + +typedef struct _THEME_CONTROLWMNOTIFY_RESULTS +{ + DWORD cbSize; + LRESULT lResult; +} THEME_CONTROLWMNOTIFY_RESULTS; + typedef struct _THEME_LOADINGCONTROL_ARGS { DWORD cbSize; diff --git a/src/libs/dutil/WixToolset.DUtil/thmutil.cpp b/src/libs/dutil/WixToolset.DUtil/thmutil.cpp index d796bbaf..a3c5d80c 100644 --- a/src/libs/dutil/WixToolset.DUtil/thmutil.cpp +++ b/src/libs/dutil/WixToolset.DUtil/thmutil.cpp @@ -421,12 +421,10 @@ static void CALLBACK OnBillboardTimer( ); static void OnBrowseDirectory( __in THEME* pTheme, - __in HWND hWnd, __in const THEME_ACTION* pAction ); static BOOL OnButtonClicked( __in THEME* pTheme, - __in HWND hWnd, __in const THEME_CONTROL* pControl ); static BOOL OnDpiChanged( @@ -434,20 +432,37 @@ static BOOL OnDpiChanged( __in WPARAM wParam, __in LPARAM lParam ); +static BOOL OnHypertextClicked( + __in THEME* pTheme, + __in const THEME_CONTROL* pThemeControl, + __in PNMLINK pnmlink + ); static void OnNcCreate( __in THEME* pTheme, __in HWND hWnd, __in LPARAM lParam ); -static HRESULT OnRichEditEnLink( - __in LPARAM lParam, - __in HWND hWndRichEdit, - __in HWND hWnd +static BOOL OnNotifyEnLink( + __in THEME* pTheme, + __in const THEME_CONTROL* pThemeControl, + __in ENLINK* link ); -static BOOL ControlIsType( - __in const THEME* pTheme, - __in DWORD dwControl, - __in THEME_CONTROL_TYPE type +static BOOL OnNotifyEnMsgFilter( + __in THEME* pTheme, + __in const THEME_CONTROL* pThemeControl, + __in MSGFILTER* msgFilter + ); +static BOOL OnWmCommand( + __in THEME* pTheme, + __in WPARAM wParam, + __in const THEME_CONTROL* pThemeControl, + __inout LRESULT* plResult + ); +static BOOL OnWmNotify( + __in THEME* pTheme, + __in LPNMHDR lParam, + __in const THEME_CONTROL* pThemeControl, + __inout LRESULT* plResult ); static const THEME_CONTROL* FindControlFromHWnd( __in const THEME* pTheme, @@ -5089,7 +5104,6 @@ static void CALLBACK OnBillboardTimer( static void OnBrowseDirectory( __in THEME* pTheme, - __in HWND hWnd, __in const THEME_ACTION* pAction ) { @@ -5098,7 +5112,7 @@ static void OnBrowseDirectory( BROWSEINFOW browseInfo = { }; PIDLIST_ABSOLUTE pidl = NULL; - browseInfo.hwndOwner = hWnd; + browseInfo.hwndOwner = pTheme->hwndParent; browseInfo.pszDisplayName = wzPath; browseInfo.lpszTitle = pTheme->sczCaption; browseInfo.ulFlags = BIF_RETURNONLYFSDIRS | BIF_USENEWUI; @@ -5148,7 +5162,6 @@ LExit: static BOOL OnButtonClicked( __in THEME* pTheme, - __in HWND hWnd, __in const THEME_CONTROL* pControl ) { @@ -5191,11 +5204,11 @@ static BOOL OnButtonClicked( switch (pChosenAction->type) { case THEME_ACTION_TYPE_BROWSE_DIRECTORY: - OnBrowseDirectory(pTheme, hWnd, pChosenAction); + OnBrowseDirectory(pTheme, pChosenAction); break; case THEME_ACTION_TYPE_CLOSE_WINDOW: - ::SendMessageW(hWnd, WM_CLOSE, 0, 0); + ::SendMessageW(pTheme->hwndParent, WM_CLOSE, 0, 0); break; case THEME_ACTION_TYPE_CHANGE_PAGE: @@ -5272,6 +5285,25 @@ LExit: return !fIgnored; } +static BOOL OnHypertextClicked( + __in THEME* pTheme, + __in const THEME_CONTROL* /*pThemeControl*/, + __in PNMLINK pnmlink + ) +{ + BOOL fProcessed = FALSE; + HRESULT hr = S_OK; + LITEM litem = pnmlink->item; + + hr = ShelExec(litem.szUrl, NULL, L"open", NULL, SW_SHOWDEFAULT, pTheme->hwndParent, NULL); + ThmExitOnFailure(hr, "Failed to launch hypertext link: %ls", litem.szUrl); + + fProcessed = TRUE; + +LExit: + return fProcessed; +} + static void OnNcCreate( __in THEME* pTheme, __in HWND hWnd, @@ -5291,63 +5323,185 @@ static void OnNcCreate( } } -static HRESULT OnRichEditEnLink( - __in LPARAM lParam, - __in HWND hWndRichEdit, - __in HWND hWnd +static BOOL OnNotifyEnLink( + __in THEME* pTheme, + __in const THEME_CONTROL* pThemeControl, + __in ENLINK* link ) { + BOOL fProcessed = FALSE; HRESULT hr = S_OK; LPWSTR sczLink = NULL; - ENLINK* link = reinterpret_cast<ENLINK*>(lParam); + TEXTRANGEW tr = { }; - switch (link->msg) + // Hyperlink clicks from rich-edit control. + if (THEME_CONTROL_TYPE_RICHEDIT == pThemeControl->type) { - case WM_LBUTTONDOWN: + switch (link->msg) { - hr = StrAlloc(&sczLink, link->chrg.cpMax - link->chrg.cpMin + 2); - ThmExitOnFailure(hr, "Failed to allocate string for link."); + case WM_LBUTTONDOWN: + hr = StrAlloc(&sczLink, (SIZE_T)2 + link->chrg.cpMax - link->chrg.cpMin); + ThmExitOnFailure(hr, "Failed to allocate string for link."); - TEXTRANGEW tr; - tr.chrg.cpMin = link->chrg.cpMin; - tr.chrg.cpMax = link->chrg.cpMax; - tr.lpstrText = sczLink; + tr.chrg.cpMin = link->chrg.cpMin; + tr.chrg.cpMax = link->chrg.cpMax; + tr.lpstrText = sczLink; - if (0 < ::SendMessageW(hWndRichEdit, EM_GETTEXTRANGE, 0, reinterpret_cast<LPARAM>(&tr))) - { - hr = ShelExec(sczLink, NULL, L"open", NULL, SW_SHOWDEFAULT, hWnd, NULL); - ThmExitOnFailure(hr, "Failed to launch link: %ls", sczLink); + if (0 < ::SendMessageW(pThemeControl->hWnd, EM_GETTEXTRANGE, 0, reinterpret_cast<LPARAM>(&tr))) + { + hr = ShelExec(sczLink, NULL, L"open", NULL, SW_SHOWDEFAULT, pTheme->hwndParent, NULL); + ThmExitOnFailure(hr, "Failed to launch link: %ls", sczLink); + + fProcessed = TRUE; + } + + break; + + case WM_SETCURSOR: + ::SetCursor(vhCursorHand); + fProcessed = TRUE; + + break; } - - break; + } + +LExit: + ReleaseStr(sczLink); + + return fProcessed; +} + +static BOOL OnNotifyEnMsgFilter( + __in THEME* pTheme, + __in const THEME_CONTROL* pThemeControl, + __in MSGFILTER* msgFilter + ) +{ + BOOL fProcessed = FALSE; + + // Tab/Shift+Tab support for rich-edit control. + if (THEME_CONTROL_TYPE_RICHEDIT == pThemeControl->type) + { + switch (msgFilter->msg) + { + case WM_KEYDOWN: + if (VK_TAB == msgFilter->wParam) + { + BOOL fShift = 0x8000 & ::GetKeyState(VK_SHIFT); + HWND hwndFocus = ::GetNextDlgTabItem(pTheme->hwndParent, pThemeControl->hWnd, fShift); + ::SetFocus(hwndFocus); + + fProcessed = TRUE; + } + break; } + } + + return fProcessed; +} - case WM_SETCURSOR: - ::SetCursor(vhCursorHand); +static BOOL OnWmCommand( + __in THEME* pTheme, + __in WPARAM wParam, + __in const THEME_CONTROL* pThemeControl, + __inout LRESULT* plResult + ) +{ + BOOL fProcessed = FALSE; + THEME_CONTROLWMCOMMAND_ARGS args = { }; + THEME_CONTROLWMCOMMAND_RESULTS results = { }; + + args.cbSize = sizeof(args); + args.wParam = wParam; + args.pThemeControl = pThemeControl; + + results.cbSize = sizeof(results); + results.lResult = *plResult; + + if (::SendMessageW(pTheme->hwndParent, WM_THMUTIL_CONTROL_WM_COMMAND, reinterpret_cast<WPARAM>(&args), reinterpret_cast<LPARAM>(&results))) + { + fProcessed = TRUE; + *plResult = results.lResult; + ExitFunction(); + } + + switch (HIWORD(wParam)) + { + case BN_CLICKED: + if (OnButtonClicked(pTheme, pThemeControl)) + { + fProcessed = TRUE; + *plResult = 0; + ExitFunction(); + } break; } LExit: - ReleaseStr(sczLink); - - return hr; + return fProcessed; } -static BOOL ControlIsType( - __in const THEME* pTheme, - __in DWORD dwControl, - __in const THEME_CONTROL_TYPE type +static BOOL OnWmNotify( + __in THEME* pTheme, + __in LPNMHDR lParam, + __in const THEME_CONTROL* pThemeControl, + __inout LRESULT* plResult ) { - BOOL fIsType = FALSE; - HWND hWnd = ::GetDlgItem(pTheme->hwndParent, dwControl); - if (hWnd) + BOOL fProcessed = FALSE; + THEME_CONTROLWMNOTIFY_ARGS args = { }; + THEME_CONTROLWMNOTIFY_RESULTS results = { }; + + args.cbSize = sizeof(args); + args.lParam = lParam; + args.pThemeControl = pThemeControl; + + results.cbSize = sizeof(results); + results.lResult = *plResult; + + if (::SendMessageW(pTheme->hwndParent, WM_THMUTIL_CONTROL_WM_NOTIFY, reinterpret_cast<WPARAM>(&args), reinterpret_cast<LPARAM>(&results))) { - const THEME_CONTROL* pControl = FindControlFromHWnd(pTheme, hWnd); - fIsType = (pControl && type == pControl->type); + fProcessed = TRUE; + *plResult = results.lResult; + ExitFunction(); } - return fIsType; + switch (lParam->code) + { + case EN_MSGFILTER: + if (OnNotifyEnMsgFilter(pTheme, pThemeControl, reinterpret_cast<MSGFILTER*>(lParam))) + { + fProcessed = TRUE; + *plResult = 1; + ExitFunction(); + } + break; + + case EN_LINK: + if (OnNotifyEnLink(pTheme, pThemeControl, reinterpret_cast<ENLINK*>(lParam))) + { + fProcessed = TRUE; + *plResult = 1; + ExitFunction(); + } + + case NM_CLICK: __fallthrough; + case NM_RETURN: + switch (pThemeControl->type) + { + case THEME_CONTROL_TYPE_HYPERTEXT: + // Clicks on a hypertext/syslink control. + if (OnHypertextClicked(pTheme, pThemeControl, reinterpret_cast<PNMLINK>(lParam))) + { + fProcessed = TRUE; + *plResult = 1; + ExitFunction(); + } + } + } + +LExit: + return fProcessed; } static const THEME_CONTROL* FindControlFromHWnd( @@ -5780,6 +5934,9 @@ static LRESULT CALLBACK ControlGroupDefWindowProc( __in LPARAM lParam ) { + LRESULT lres = 0; + const THEME_CONTROL* pThemeControl = NULL; + if (pTheme) { switch (uMsg) @@ -5827,55 +5984,22 @@ static LRESULT CALLBACK ControlGroupDefWindowProc( if (lParam) { LPNMHDR pnmhdr = reinterpret_cast<LPNMHDR>(lParam); - switch (pnmhdr->code) + pThemeControl = FindControlFromHWnd(pTheme, pnmhdr->hwndFrom); + if (pThemeControl && OnWmNotify(pTheme, pnmhdr, pThemeControl, &lres)) { - // Tab/Shift+Tab support for rich-edit control. - case EN_MSGFILTER: - { - MSGFILTER* msgFilter = reinterpret_cast<MSGFILTER*>(lParam); - if (WM_KEYDOWN == msgFilter->msg && VK_TAB == msgFilter->wParam) - { - BOOL fShift = 0x8000 & ::GetKeyState(VK_SHIFT); - HWND hwndFocus = ::GetNextDlgTabItem(hWnd, msgFilter->nmhdr.hwndFrom, fShift); - ::SetFocus(hwndFocus); - return 1; - } - break; - } - - // Hyperlink clicks from rich-edit control. - case EN_LINK: - return SUCCEEDED(OnRichEditEnLink(lParam, pnmhdr->hwndFrom, hWnd)); - - // Clicks on a hypertext/syslink control. - case NM_CLICK: __fallthrough; - case NM_RETURN: - if (ControlIsType(pTheme, static_cast<DWORD>(pnmhdr->idFrom), THEME_CONTROL_TYPE_HYPERTEXT)) - { - PNMLINK pnmlink = reinterpret_cast<PNMLINK>(lParam); - LITEM litem = pnmlink->item; - ShelExec(litem.szUrl, NULL, L"open", NULL, SW_SHOWDEFAULT, hWnd, NULL); - return 1; - } - - return 0; + return lres; } } break; case WM_COMMAND: - switch (HIWORD(wParam)) + if (lParam) { - case BN_CLICKED: - if (lParam) + pThemeControl = FindControlFromHWnd(pTheme, (HWND)lParam); + if (pThemeControl && OnWmCommand(pTheme, wParam, pThemeControl, &lres)) { - const THEME_CONTROL* pControl = FindControlFromHWnd(pTheme, (HWND)lParam); - if (pControl && OnButtonClicked(pTheme, hWnd, pControl)) - { - return 0; - } + return lres; } - break; } break; } diff --git a/src/samples/thmviewer/thmviewer.cpp b/src/samples/thmviewer/thmviewer.cpp index cffa3851..e593d6ad 100644 --- a/src/samples/thmviewer/thmviewer.cpp +++ b/src/samples/thmviewer/thmviewer.cpp @@ -52,6 +52,10 @@ static BOOL OnThemeLoadingControl( __in const THEME_LOADINGCONTROL_ARGS* pArgs, __in THEME_LOADINGCONTROL_RESULTS* pResults ); +static BOOL OnThemeControlWmNotify( + __in const THEME_CONTROLWMNOTIFY_ARGS* pArgs, + __in THEME_CONTROLWMNOTIFY_RESULTS* pResults + ); static void CALLBACK ThmviewerTraceError( __in_z LPCSTR szFile, __in int iLine, @@ -377,32 +381,11 @@ static LRESULT CALLBACK MainWndProc( ::PostQuitMessage(0); break; - case WM_NOTIFY: - { - NMHDR* pnmhdr = reinterpret_cast<NMHDR*>(lParam); - switch (pnmhdr->code) - { - case TVN_SELCHANGEDW: - { - NMTREEVIEWW* ptv = reinterpret_cast<NMTREEVIEWW*>(lParam); - ::PostThreadMessageW(vdwDisplayThreadId, WM_THMVWR_SHOWPAGE, SW_HIDE, ptv->itemOld.lParam); - ::PostThreadMessageW(vdwDisplayThreadId, WM_THMVWR_SHOWPAGE, SW_SHOW, ptv->itemNew.lParam); - } - break; - - //case NM_DBLCLK: - // TVITEM item = { }; - // item.mask = TVIF_PARAM; - // item.hItem = TreeView_GetSelection(pnmhdr->hwndFrom); - // TreeView_GetItem(pnmhdr->hwndFrom, &item); - // ::PostThreadMessageW(vdwDisplayThreadId, WM_THMVWR_SHOWPAGE, SW_SHOW, item.lParam); - // return 1; - } - } - break; - case WM_THMUTIL_LOADING_CONTROL: return OnThemeLoadingControl(reinterpret_cast<THEME_LOADINGCONTROL_ARGS*>(wParam), reinterpret_cast<THEME_LOADINGCONTROL_RESULTS*>(lParam)); + + case WM_THMUTIL_CONTROL_WM_NOTIFY: + return OnThemeControlWmNotify(reinterpret_cast<THEME_CONTROLWMNOTIFY_ARGS*>(wParam), reinterpret_cast<THEME_CONTROLWMNOTIFY_RESULTS*>(lParam)); } return ThemeDefWindowProc(vpTheme, hWnd, uMsg, wParam, lParam); @@ -558,3 +541,29 @@ static BOOL OnThemeLoadingControl( pResults->hr = S_OK; return TRUE; } + +static BOOL OnThemeControlWmNotify( + __in const THEME_CONTROLWMNOTIFY_ARGS* pArgs, + __in THEME_CONTROLWMNOTIFY_RESULTS* /*pResults*/ + ) +{ + BOOL fProcessed = FALSE; + + switch (pArgs->lParam->code) + { + case TVN_SELCHANGEDW: + switch (pArgs->pThemeControl->wId) + { + case THMVWR_CONTROL_TREE: + NMTREEVIEWW* ptv = reinterpret_cast<NMTREEVIEWW*>(pArgs->lParam); + ::PostThreadMessageW(vdwDisplayThreadId, WM_THMVWR_SHOWPAGE, SW_HIDE, ptv->itemOld.lParam); + ::PostThreadMessageW(vdwDisplayThreadId, WM_THMVWR_SHOWPAGE, SW_SHOW, ptv->itemNew.lParam); + + fProcessed = TRUE; + break; + } + break; + } + + return fProcessed; +} diff --git a/src/test/burn/TestData/Manual/BafThmutilTesting/BafThmUtilTesting.cpp b/src/test/burn/TestData/Manual/BafThmutilTesting/BafThmUtilTesting.cpp index b35b4e02..a5bcba3e 100644 --- a/src/test/burn/TestData/Manual/BafThmutilTesting/BafThmUtilTesting.cpp +++ b/src/test/burn/TestData/Manual/BafThmutilTesting/BafThmUtilTesting.cpp @@ -43,62 +43,48 @@ static void CALLBACK BafThmUtilTestingTraceError( class CBafThmUtilTesting : public CBalBaseBAFunctions { public: // IBAFunctions - /*virtual STDMETHODIMP OnThemeLoaded( - THEME* pTheme, - WIX_LOCALIZATION* pWixLoc + virtual STDMETHODIMP OnThemeControlLoading( + __in LPCWSTR wzName, + __inout BOOL* pfProcessed, + __inout WORD* pwId ) { - HRESULT hr = S_OK; - - hr = __super::OnThemeLoaded(pTheme, pWixLoc); + if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, wzName, -1, L"InstallTestButton", -1)) + { + *pfProcessed = TRUE; + *pwId = BAF_CONTROL_INSTALL_TEST_BUTTON; + } - return hr; - }*/ + return S_OK; + } - virtual STDMETHODIMP WndProc( - __in THEME* pTheme, - __in HWND hWnd, - __in UINT uMsg, + virtual STDMETHODIMP OnThemeControlWmCommand( __in WPARAM wParam, - __in LPARAM lParam, - __inout LRESULT* plRes + __in LPCWSTR /*wzName*/, + __in WORD wId, + __in HWND /*hWnd*/, + __inout BOOL* pfProcessed, + __inout LRESULT* plResult ) { - switch (uMsg) + HRESULT hr = S_OK; + + switch (HIWORD(wParam)) { - case WM_COMMAND: - switch (HIWORD(wParam)) + case BN_CLICKED: + switch (wId) { - case BN_CLICKED: - switch (LOWORD(wParam)) - { - case BAF_CONTROL_INSTALL_TEST_BUTTON: - OnShowTheme(); - *plRes = 0; - return S_OK; - } - + case BAF_CONTROL_INSTALL_TEST_BUTTON: + OnShowTheme(); + *pfProcessed = TRUE; + *plResult = 0; break; } - break; - } - - return __super::WndProc(pTheme, hWnd, uMsg, wParam, lParam, plRes); - } - virtual STDMETHODIMP OnThemeControlLoading( - __in LPCWSTR wzName, - __inout BOOL* pfProcessed, - __inout WORD* pwId - ) - { - if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, wzName, -1, L"InstallTestButton", -1)) - { - *pfProcessed = TRUE; - *pwId = BAF_CONTROL_INSTALL_TEST_BUTTON; + break; } - return S_OK; + return hr; } private: -- cgit v1.2.3-55-g6feb