123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 |
- #include "main.h"
- #include "./reflectmsg.h"
- #include "./skinnedwnd.h"
- #include "./skinnedmenu.h"
- #include "./skinnedmenuthreadinfo.h"
- BOOL CanReflect(UINT uMsg)
- {
- switch(uMsg)
- {
- case WM_DRAWITEM:
- case WM_NOTIFY:
- case WM_COMMAND:
- case WM_CTLCOLORBTN:
- case WM_CTLCOLOREDIT:
- case WM_CTLCOLORLISTBOX:
- case WM_CTLCOLORSCROLLBAR:
- case WM_CTLCOLORSTATIC:
- case WM_MEASUREITEM:
- return TRUE;
- }
- return FALSE;
- }
- BOOL ReflectMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL bDialog, LRESULT *pResult)
- {
- HWND hwndReflect = NULL;
- switch(uMsg)
- {
- case WM_DRAWITEM:
- hwndReflect = ((LPDRAWITEMSTRUCT)lParam)->hwndItem;
- if (NULL != hwndReflect && ODT_MENU == ((LPDRAWITEMSTRUCT)lParam)->CtlType)
- hwndReflect = SkinnedMenu::WindowFromHandle((HMENU)hwndReflect);
- break;
- case WM_NOTIFY:
- hwndReflect = ((LPNMHDR)lParam)->hwndFrom;
- break;
- case WM_COMMAND:
- case WM_CTLCOLORBTN:
- case WM_CTLCOLOREDIT:
- case WM_CTLCOLORLISTBOX:
- case WM_CTLCOLORSCROLLBAR:
- case WM_CTLCOLORSTATIC:
- hwndReflect =(HWND)lParam;
- break;
- case WM_MEASUREITEM:
- if (0 == wParam && ODT_MENU == ((MEASUREITEMSTRUCT*)lParam)->CtlType)
- {
- SkinnedMenuThreadInfo *threadInfo;
- if (S_OK == SkinnedMenuThreadInfo::GetInstance(FALSE, &threadInfo))
- {
- hwndReflect = SkinnedMenu::WindowFromHandle(threadInfo->GetActiveMeasureMenu());
- threadInfo->Release();
- }
- }
- break;
- }
- // make sure that hwndReflect is a valid hwnd otherwise it can incorrectly lose valid messages
- // when sent as custom version of normally valid ones ie faked wm_command messages where lparam is -1
- if (NULL != hwndReflect &&
- hwnd != hwndReflect &&
- IsWindow(hwndReflect))
- {
- REFLECTPARAM rParam;
- rParam.result = 0;
- rParam.lParam = lParam;
- rParam.hwndFrom = hwnd;
-
- if (REFLECTMESSAGE(hwndReflect, uMsg, wParam, (LPARAM)&rParam))
- {
- *pResult = rParam.result;
- if (bDialog)
- {
- switch(uMsg)
- {
- case WM_CTLCOLORBTN:
- case WM_CTLCOLOREDIT:
- case WM_CTLCOLORLISTBOX:
- case WM_CTLCOLORSCROLLBAR:
- case WM_CTLCOLORSTATIC:
- return TRUE;
- }
- SetWindowLongPtrW(hwnd, DWLP_MSGRESULT, (LONGX86)(LONG_PTR)*pResult);
- *pResult = TRUE;
- }
- return TRUE;
- }
- }
- *pResult = 0;
- return FALSE;
- }
- typedef struct __REFLECTORWND
- {
- BOOL bUnicode;
- BOOL bDialog;
- WNDPROC windowProc;
- }REFLECTORWND;
- static ATOM REFLECTOR = 0;
- static LRESULT CALLBACK Reflector_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
- HRESULT InstallReflector(HWND hwnd)
- {
- if (0 == REFLECTOR)
- {
- REFLECTOR = GlobalAddAtomW(L"WAREFLECTOR");
- if (0 == REFLECTOR) return E_UNEXPECTED;
- }
- if (NULL == hwnd || !IsWindow(hwnd))
- return E_INVALIDARG;
- if (NULL != GetPropW(hwnd, (LPCWSTR)MAKEINTATOM(REFLECTOR)) ||
- NULL != SkinnedWnd::GetFromHWND(hwnd))
- return S_FALSE;
- REFLECTORWND *prw = (REFLECTORWND*)calloc(1, sizeof(REFLECTORWND));
- if (NULL == prw)
- return E_OUTOFMEMORY;
- ZeroMemory(prw, sizeof(REFLECTORWND));
-
- prw->bUnicode = IsWindowUnicode(hwnd);
- prw->windowProc = (WNDPROC)(LONG_PTR)SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONGX86)(LONG_PTR)Reflector_WindowProc);
-
- if (NULL == prw->windowProc ||
- !SetPropW(hwnd, (LPCWSTR)MAKEINTATOM(REFLECTOR), prw))
- {
- RemoveReflector(hwnd);
- return E_FAIL;
- }
- return S_OK;
- }
- BOOL RemoveReflector(HWND hwnd)
- {
- if (!hwnd || !IsWindow(hwnd))
- return FALSE;
-
- REFLECTORWND *prw = (REFLECTORWND*)GetPropW(hwnd, (LPCWSTR)MAKEINTATOM(REFLECTOR));
- RemovePropW(hwnd, (LPCWSTR)MAKEINTATOM(REFLECTOR));
-
- if (NULL == prw)
- return FALSE;
- if (prw->windowProc)
- SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONGX86)(LONG_PTR)prw->windowProc);
-
- free(prw);
- return TRUE;
- }
- static LRESULT CALLBACK Reflector_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- REFLECTORWND *prw = (REFLECTORWND*)GetPropW(hwnd, (LPCWSTR)MAKEINTATOM(REFLECTOR));
- if (NULL == prw || NULL == prw->windowProc)
- {
- return (IsWindowUnicode(hwnd)) ?
- DefWindowProcW(hwnd, uMsg, wParam, lParam) :
- DefWindowProcA(hwnd, uMsg, wParam, lParam);
- }
-
- if (WM_DESTROY == uMsg)
- {
- BOOL unicode = prw->bUnicode;
- WNDPROC windowProc = prw->windowProc;
- RemoveReflector(hwnd);
- return (unicode) ?
- CallWindowProcW(windowProc, hwnd, uMsg, wParam, lParam) :
- CallWindowProcA(windowProc, hwnd, uMsg, wParam, lParam);
- }
- LRESULT result;
- if (ReflectMessage(hwnd, uMsg, wParam, lParam, prw->bDialog, &result))
- return result;
- return (prw->bUnicode) ?
- CallWindowProcW(prw->windowProc, hwnd, uMsg, wParam, lParam) :
- CallWindowProcA(prw->windowProc, hwnd, uMsg, wParam, lParam);
- }
|