From 1492cd4767bc9c7748455639a8eb4429a2771c34 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Sun, 3 Mar 2013 12:25:29 +0000 Subject: added mechanism of windows subclassing, proof to dynamic plugin unloading git-svn-id: http://svn.miranda-ng.org/main/trunk@3869 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- bin10/lib/mir_core.lib | Bin 30570 -> 31056 bytes bin10/lib/mir_core64.lib | Bin 27910 -> 28358 bytes bin11/lib/mir_core.lib | Bin 30570 -> 31056 bytes bin11/lib/mir_core64.lib | Bin 27910 -> 28358 bytes include/delphi/m_core.inc | 5 ++ include/m_core.h | 6 +++ plugins/SmileyAdd/src/dlgboxsubclass.cpp | 6 +-- src/mir_core/mir_core.def | 2 + src/mir_core/mir_core_10.vcxproj | 1 + src/mir_core/mir_core_10.vcxproj.filters | 3 ++ src/mir_core/mir_core_11.vcxproj | 1 + src/mir_core/mir_core_11.vcxproj.filters | 3 ++ src/mir_core/subclass.cpp | 85 +++++++++++++++++++++++++++++++ 13 files changed, 109 insertions(+), 3 deletions(-) create mode 100644 src/mir_core/subclass.cpp diff --git a/bin10/lib/mir_core.lib b/bin10/lib/mir_core.lib index ea3a307912..4d0f826fed 100644 Binary files a/bin10/lib/mir_core.lib and b/bin10/lib/mir_core.lib differ diff --git a/bin10/lib/mir_core64.lib b/bin10/lib/mir_core64.lib index fd85f605a1..345447d0a2 100644 Binary files a/bin10/lib/mir_core64.lib and b/bin10/lib/mir_core64.lib differ diff --git a/bin11/lib/mir_core.lib b/bin11/lib/mir_core.lib index da4a57eec1..7aa43eb650 100644 Binary files a/bin11/lib/mir_core.lib and b/bin11/lib/mir_core.lib differ diff --git a/bin11/lib/mir_core64.lib b/bin11/lib/mir_core64.lib index 4a378143aa..2b4a861890 100644 Binary files a/bin11/lib/mir_core64.lib and b/bin11/lib/mir_core64.lib differ diff --git a/include/delphi/m_core.inc b/include/delphi/m_core.inc index 283926357a..595e02e16c 100644 --- a/include/delphi/m_core.inc +++ b/include/delphi/m_core.inc @@ -575,6 +575,11 @@ function mir_utf8checkstring(const astr:PAnsiChar):bool;stdcall; /////////////////////////////////////////////////////////////////////////////// +procedure mir_subclassWindow(Wnd: HWND; WndProc: WNDPROC); stdcall; + external CoreDLL name 'mir_subclassWindow'; + +/////////////////////////////////////////////////////////////////////////////// + procedure UnloadCoreModule(); stdcall; external CoreDLL name 'UnloadCoreModule'; diff --git a/include/m_core.h b/include/m_core.h index 62ce2a594c..c1cb2260c6 100644 --- a/include/m_core.h +++ b/include/m_core.h @@ -580,6 +580,12 @@ __forceinline char* mir_utf8decodeA(const char* src) #define mir_utf8encodeT mir_utf8encode #endif +/////////////////////////////////////////////////////////////////////////////// +// Window subclassing + +MIR_CORE_DLL(void) mir_subclassWindow(HWND hWnd, WNDPROC wndProc); +MIR_CORE_DLL(void) KillModuleSubclassing(HMODULE hInst); + /////////////////////////////////////////////////////////////////////////////// MIR_CORE_DLL(void) UnloadCoreModule(void); diff --git a/plugins/SmileyAdd/src/dlgboxsubclass.cpp b/plugins/SmileyAdd/src/dlgboxsubclass.cpp index 1970577b48..eee8db0025 100644 --- a/plugins/SmileyAdd/src/dlgboxsubclass.cpp +++ b/plugins/SmileyAdd/src/dlgboxsubclass.cpp @@ -43,7 +43,7 @@ static HHOOK g_hMessageHookPre = NULL; static HANDLE g_hMutex = NULL; static HANDLE g_hHookMsgWnd = NULL; -static LRESULT CALLBACK MessageDlgSubclas(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +static LRESULT CALLBACK MessageDlgSubclass(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); //type definitions @@ -344,7 +344,7 @@ static void MsgWndDetect(HWND hwndDlg, HANDLE hContact, msgData* datm) if (msgwnd != NULL) { - msgwnd->wpOrigWndProc = (WNDPROC)SetWindowLongPtr(hwndDlg, GWLP_WNDPROC, (LONG_PTR)MessageDlgSubclas); + msgwnd->wpOrigWndProc = (WNDPROC)SetWindowLongPtr(hwndDlg, GWLP_WNDPROC, (LONG_PTR)MessageDlgSubclass); msgwnd->CreateSmileyButton(); if (hContact == NULL) SetRichCallback(msgwnd->REdit, msgwnd->hContact, true, true); } @@ -353,7 +353,7 @@ static void MsgWndDetect(HWND hwndDlg, HANDLE hContact, msgData* datm) //global subclass function for all dialogs -static LRESULT CALLBACK MessageDlgSubclas(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +static LRESULT CALLBACK MessageDlgSubclass(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { MsgWndData* dat = IsMsgWnd(hwnd); if (dat == NULL) return 0; diff --git a/src/mir_core/mir_core.def b/src/mir_core/mir_core.def index 3958995c32..3c1174c74b 100644 --- a/src/mir_core/mir_core.def +++ b/src/mir_core/mir_core.def @@ -136,3 +136,5 @@ db_find_first @133 db_find_next @134 Icon_Register @135 Icon_RegisterT @136 +mir_subclassWindow @137 +KillModuleSubclassing @138 diff --git a/src/mir_core/mir_core_10.vcxproj b/src/mir_core/mir_core_10.vcxproj index e88f91294a..a44a146761 100644 --- a/src/mir_core/mir_core_10.vcxproj +++ b/src/mir_core/mir_core_10.vcxproj @@ -41,6 +41,7 @@ + diff --git a/src/mir_core/mir_core_10.vcxproj.filters b/src/mir_core/mir_core_10.vcxproj.filters index 9e472906fb..3c50baf5a8 100644 --- a/src/mir_core/mir_core_10.vcxproj.filters +++ b/src/mir_core/mir_core_10.vcxproj.filters @@ -58,6 +58,9 @@ Source Files + + Source Files + diff --git a/src/mir_core/mir_core_11.vcxproj b/src/mir_core/mir_core_11.vcxproj index 1dd921e912..2a7728f708 100644 --- a/src/mir_core/mir_core_11.vcxproj +++ b/src/mir_core/mir_core_11.vcxproj @@ -41,6 +41,7 @@ + diff --git a/src/mir_core/mir_core_11.vcxproj.filters b/src/mir_core/mir_core_11.vcxproj.filters index 9e472906fb..3c50baf5a8 100644 --- a/src/mir_core/mir_core_11.vcxproj.filters +++ b/src/mir_core/mir_core_11.vcxproj.filters @@ -58,6 +58,9 @@ Source Files + + Source Files + diff --git a/src/mir_core/subclass.cpp b/src/mir_core/subclass.cpp new file mode 100644 index 0000000000..50cc8e3920 --- /dev/null +++ b/src/mir_core/subclass.cpp @@ -0,0 +1,85 @@ +/* +Copyright (C) 2012-13 Miranda NG team (http://miranda-ng.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation version 2 +of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include "commonheaders.h" + +struct MSubclassData +{ + HWND m_hWnd; + + int m_iHooks; + WNDPROC *m_hooks; + WNDPROC m_origWndProc; + + ~MSubclassData() + { + free(m_hooks); + } +}; + +static LIST arSubclass(10, LIST::FTSortFunc(HandleKeySortT)); + +static LRESULT CALLBACK MSubclassWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + MSubclassData *p = arSubclass.find((MSubclassData*)&hwnd); + if (p != NULL) { + for (int i=0; i < p->m_iHooks; i++) { + LRESULT res = p->m_hooks[i](hwnd, uMsg, wParam, lParam); + if (res != 0) + return res; + } + + if (uMsg == WM_DESTROY) { + SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)p->m_origWndProc); + arSubclass.remove(p); + delete p; + } + } + + return DefWindowProc(hwnd, uMsg, wParam, lParam); +} + +MIR_CORE_DLL(void) mir_subclassWindow(HWND hWnd, WNDPROC wndProc) +{ + MSubclassData *p = arSubclass.find((MSubclassData*)&hWnd); + if (p == NULL) { + p = new MSubclassData; + p->m_hWnd = hWnd; + p->m_origWndProc = (WNDPROC)SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)MSubclassWndProc); + p->m_iHooks = 0; + p->m_hooks = (WNDPROC*)malloc( sizeof(WNDPROC)); + arSubclass.insert(p); + } + else p->m_hooks = (WNDPROC*)realloc(p->m_hooks, (p->m_iHooks+1)*sizeof(WNDPROC)); + + p->m_hooks[p->m_iHooks++] = wndProc; +} + +MIR_CORE_DLL(void) KillModuleSubclassing(HMODULE hInst) +{ + for (int i=0; i < arSubclass.getCount(); i++) { + MSubclassData *p = arSubclass[i]; + for (int j=0; j < p->m_iHooks; ) { + if ( GetInstByAddress(p->m_hooks[j]) == hInst) { + for (int k=j+1; k < p->m_iHooks; k++) + p->m_hooks[k-1] = p->m_hooks[k]; + p->m_iHooks--; + } + else j++; + } + } +} -- cgit v1.2.3