From 1aaf3408c2d6a47e9778347c43bffc62db75da31 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Sun, 28 Jan 2024 12:10:46 +0300 Subject: AvatarHistory: windowless popups implementation --- plugins/AvatarHistory/src/AvatarHistory.cpp | 3 - plugins/AvatarHistory/src/popup.cpp | 196 +++++++++------------------- plugins/AvatarHistory/src/popup.h | 8 -- 3 files changed, 63 insertions(+), 144 deletions(-) diff --git a/plugins/AvatarHistory/src/AvatarHistory.cpp b/plugins/AvatarHistory/src/AvatarHistory.cpp index 672d1d1ac7..ecedb62cc0 100644 --- a/plugins/AvatarHistory/src/AvatarHistory.cpp +++ b/plugins/AvatarHistory/src/AvatarHistory.cpp @@ -230,8 +230,6 @@ static int ModulesLoaded(WPARAM, LPARAM) hFolder = FoldersRegisterCustomPathW(LPGEN("Avatars"), LPGEN("Avatar History"), PROFILE_PATHW L"\\" CURRENT_PROFILEW L"\\Avatars History"); - InitPopups(); - HookEvent(ME_AV_CONTACTAVATARCHANGED, AvatarChanged); return 0; } @@ -341,7 +339,6 @@ int CMPlugin::Load() int CMPlugin::Unload() { - DeInitPopups(); WindowList_Destroy(hAvatarWindowsList); return 0; } diff --git a/plugins/AvatarHistory/src/popup.cpp b/plugins/AvatarHistory/src/popup.cpp index 069b661ded..cea64c7f25 100644 --- a/plugins/AvatarHistory/src/popup.cpp +++ b/plugins/AvatarHistory/src/popup.cpp @@ -19,57 +19,87 @@ Boston, MA 02111-1307, USA. #include "stdafx.h" -// Prototypes ///////////////////////////////////////////////////////////////////////////////////// +struct PopupDataType +{ + PopupDataType(void *_1, HICON _2) : + plugin_data(_1), + hIcon(_2) + {} -#define WMU_ACTION (WM_USER + 1) + ~PopupDataType() + { + DestroyIcon(hIcon); + } + void *plugin_data; + HICON hIcon; +}; -LRESULT CALLBACK PopupWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +static void DoAction(WPARAM wParam, LPARAM lParam) +{ + if (lParam == POPUP_ACTION_OPENAVATARHISTORY) { + CallServiceSync("AvatarHistory/ShowDialog", wParam, 0); + } + else if (lParam == POPUP_ACTION_OPENHISTORY) { + CallServiceSync(MS_HISTORY_SHOWCONTACTHISTORY, wParam, 0); + } +} -HWND hPopupWindow = nullptr; +// Handle to popup events +static LRESULT CALLBACK PopupDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + PopupDataType *popup = (PopupDataType *)PUGetPluginData(hWnd); + switch (message) { + case WM_COMMAND: + DoAction(WPARAM(popup->plugin_data), opts.popup_left_click_action); -static LRESULT CALLBACK PopupDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); -static LRESULT CALLBACK DumbPopupDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + if (opts.popup_left_click_action != POPUP_ACTION_DONOTHING) + PUDeletePopup(hWnd); + return TRUE; + case WM_CONTEXTMENU: + DoAction(WPARAM(popup->plugin_data), opts.popup_right_click_action); -// Functions ////////////////////////////////////////////////////////////////////////////////////// + if (opts.popup_right_click_action != POPUP_ACTION_DONOTHING) + PUDeletePopup(hWnd); + return TRUE; -// Initializations needed by popups -void InitPopups() -{ - // window needed for popup commands - hPopupWindow = CreateWindowEx(WS_EX_TOOLWINDOW, L"static", _A2W(MODULENAME) L"_PopupWindow", - 0, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, HWND_DESKTOP, - nullptr, g_plugin.getInst(), nullptr); - SetWindowLongPtr(hPopupWindow, GWLP_WNDPROC, (LONG_PTR)PopupWndProc); -} + case UM_FREEPLUGINDATA: + delete popup; + return FALSE; //the return value is ignored + } + return DefWindowProc(hWnd, message, wParam, lParam); +} -// Deinitializations needed by popups -void DeInitPopups() +// Handle to popup events +static LRESULT CALLBACK DumbPopupDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { - if (hPopupWindow) - DestroyWindow(hPopupWindow); -} + switch (message) { + case WM_COMMAND: + PUDeletePopup(hWnd); + return TRUE; + case WM_CONTEXTMENU: + PUDeletePopup(hWnd); + return TRUE; -// Show an error popup -void ShowErrPopup(const wchar_t *description, const wchar_t *title) -{ - ShowPopupEx(NULL, title == nullptr ? _A2W(MODULENAME) L" Error" : title, description, - nullptr, POPUP_TYPE_ERROR, nullptr); -} + case UM_FREEPLUGINDATA: + delete (PopupDataType *)PUGetPluginData(hWnd); + return FALSE; //the return value is ignored + } + return DefWindowProc(hWnd, message, wParam, lParam); +} void ShowTestPopup(MCONTACT hContact, const wchar_t *title, const wchar_t *description, const Options *op) { ShowPopupEx(hContact, title, description, nullptr, POPUP_TYPE_TEST, op); } - void ShowPopup(MCONTACT hContact, const wchar_t *title, const wchar_t *description) { ShowPopupEx(hContact, title, description, (void*)hContact, POPUP_TYPE_NORMAL, &opts); @@ -77,31 +107,19 @@ void ShowPopup(MCONTACT hContact, const wchar_t *title, const wchar_t *descripti void ShowDebugPopup(MCONTACT hContact, const wchar_t *title, const wchar_t *description) { - if (g_plugin.getByte("Debug", 0)) { + if (g_plugin.getByte("Debug", 0)) ShowPopup(hContact, title, description); - } } -typedef struct -{ - void* plugin_data; - HICON hIcon; -} -PopupDataType; - // Show an popup void ShowPopupEx(MCONTACT hContact, const wchar_t *title, const wchar_t *description, void *plugin_data, int type, const Options *op) { // Make popup - POPUPDATAW ppd; - + POPUPDATAW ppd = {}; ppd.lchContact = hContact; ppd.lchIcon = createProtoOverlayedIcon(hContact); - - ppd.PluginData = mir_alloc(sizeof(PopupDataType)); - ((PopupDataType*)ppd.PluginData)->plugin_data = plugin_data; - ((PopupDataType*)ppd.PluginData)->hIcon = ppd.lchIcon; + ppd.PluginData = new PopupDataType(plugin_data, ppd.lchIcon); if (title != nullptr) mir_wstrncpy(ppd.lpwzContactName, title, _countof(ppd.lpwzContactName)); @@ -125,19 +143,15 @@ void ShowPopupEx(MCONTACT hContact, const wchar_t *title, const wchar_t *descrip ppd.colorText = op->popup_text_color; } } - else // if (type == POPUP_TYPE_ERROR) - { + else { // if (type == POPUP_TYPE_ERROR) ppd.colorBack = RGB(200, 0, 0); ppd.colorText = RGB(255, 255, 255); } - if (type == POPUP_TYPE_NORMAL) { + if (type == POPUP_TYPE_NORMAL) ppd.PluginWindowProc = PopupDlgProc; - } else // if (type == POPUP_TYPE_TEST || type == POPUP_TYPE_ERROR) - { ppd.PluginWindowProc = DumbPopupDlgProc; - } if (type == POPUP_TYPE_NORMAL || type == POPUP_TYPE_TEST) { switch (op->popup_delay_type) { @@ -148,93 +162,9 @@ void ShowPopupEx(MCONTACT hContact, const wchar_t *title, const wchar_t *descrip case POPUP_DELAY_PERMANENT: ppd.iSeconds = -1; break; - - case POPUP_DELAY_DEFAULT: - default: - ppd.iSeconds = 0; - break; } } - else // if (type == POPUP_TYPE_ERROR) - { - ppd.iSeconds = 0; - } // Now that every field has been filled, we want to see the popup. PUAddPopupW(&ppd); } - - -// Handle to the hidden windows to handle actions for popup clicks -// wParam has the number of MOTD in case of WMU_SHOW_MOTD_DETAILS -LRESULT CALLBACK PopupWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - if (uMsg == WMU_ACTION) { - if (lParam == POPUP_ACTION_OPENAVATARHISTORY) { - CallService("AvatarHistory/ShowDialog", wParam, 0); - } - else if (lParam == POPUP_ACTION_OPENHISTORY) { - CallService(MS_HISTORY_SHOWCONTACTHISTORY, wParam, 0); - } - } - return DefWindowProc(hWnd, uMsg, wParam, lParam); -} - - -// Handle to popup events -static LRESULT CALLBACK PopupDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - PopupDataType *popup = (PopupDataType*)PUGetPluginData(hWnd); - - switch (message) { - case WM_COMMAND: - PostMessage(hPopupWindow, WMU_ACTION, (WPARAM)popup->plugin_data, opts.popup_left_click_action); - - if (opts.popup_left_click_action != POPUP_ACTION_DONOTHING) - PUDeletePopup(hWnd); - - return TRUE; - - case WM_CONTEXTMENU: - PostMessage(hPopupWindow, WMU_ACTION, (WPARAM)popup->plugin_data, opts.popup_right_click_action); - - if (opts.popup_right_click_action != POPUP_ACTION_DONOTHING) - PUDeletePopup(hWnd); - - return TRUE; - - case UM_FREEPLUGINDATA: - if ((INT_PTR)popup != CALLSERVICE_NOTFOUND) { - DestroyIcon(popup->hIcon); - mir_free(popup); - } - return FALSE; //the return value is ignored - } - - return DefWindowProc(hWnd, message, wParam, lParam); -} - - -// Handle to popup events -static LRESULT CALLBACK DumbPopupDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - switch (message) { - case WM_COMMAND: - PUDeletePopup(hWnd); - return TRUE; - - case WM_CONTEXTMENU: - PUDeletePopup(hWnd); - return TRUE; - - case UM_FREEPLUGINDATA: - PopupDataType* popup = (PopupDataType*)PUGetPluginData(hWnd); - if ((INT_PTR)popup != CALLSERVICE_NOTFOUND) { - DestroyIcon(popup->hIcon); - mir_free(popup); - } - return FALSE; //the return value is ignored - } - - return DefWindowProc(hWnd, message, wParam, lParam); -} diff --git a/plugins/AvatarHistory/src/popup.h b/plugins/AvatarHistory/src/popup.h index bc76524ae2..7c67a4a086 100644 --- a/plugins/AvatarHistory/src/popup.h +++ b/plugins/AvatarHistory/src/popup.h @@ -42,13 +42,6 @@ struct Options { uint16_t popup_right_click_action; }; -// Initializations needed by popups -void InitPopups(); - -// Deinitializations needed by popups -void DeInitPopups(); - - #define POPUP_TYPE_NORMAL 0 #define POPUP_TYPE_TEST 1 #define POPUP_TYPE_ERROR 2 @@ -61,7 +54,6 @@ void ShowDebugPopup(MCONTACT hContact, const wchar_t *title, const wchar_t *desc void ShowTestPopup(MCONTACT hContact,const wchar_t *title, const wchar_t *description, const Options *op); // Show an error popup -void ShowErrPopup(const char *description, const char *title = nullptr); void ShowPopupEx(MCONTACT hContact, const wchar_t *title, const wchar_t *description, void *plugin_data, int type, const Options *op); -- cgit v1.2.3