aboutsummaryrefslogtreecommitdiff
path: root/Src/Plugins/General/gen_ml/skinnedwnd.cpp
diff options
context:
space:
mode:
authorJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
committerJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
commit20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Plugins/General/gen_ml/skinnedwnd.cpp
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz
Initial community commit
Diffstat (limited to 'Src/Plugins/General/gen_ml/skinnedwnd.cpp')
-rw-r--r--Src/Plugins/General/gen_ml/skinnedwnd.cpp569
1 files changed, 569 insertions, 0 deletions
diff --git a/Src/Plugins/General/gen_ml/skinnedwnd.cpp b/Src/Plugins/General/gen_ml/skinnedwnd.cpp
new file mode 100644
index 00000000..0e16bb25
--- /dev/null
+++ b/Src/Plugins/General/gen_ml/skinnedwnd.cpp
@@ -0,0 +1,569 @@
+#include "./skinnedwnd.h"
+#include "../winamp/wa_dlg.h"
+#include "../nu/trace.h"
+#include "./mldwm.h"
+#include "../nu/CGlobalAtom.h"
+
+static CGlobalAtom WNDDATAPROPW(L"SWDATA");
+
+static UINT WINAMP_WM_DIRECT_MOUSE_WHEEL = WM_NULL;
+
+
+#ifndef LONGX86
+#ifdef _WIN64
+ #define LONGX86 LONG_PTR
+#else /*_WIN64*/
+ #define LONGX86 LONG
+#endif /*_WIN64*/
+#endif // LONGX86
+
+#define SWS_ATTACHED 0x00010000 // window attached
+#define SWS_UNICODE 0x00020000 // winodow is unicode
+#define SWS_THEMED 0x00040000 // was themed before
+#define SWS_REFLECT 0x00080000 // support message reflection
+#define SWS_DIALOG 0x00100000 // treat this as dialog
+
+#define BORDER_WIDTH 1
+
+extern HRESULT(WINAPI *SetWindowTheme)(HWND hwnd, LPCWSTR pszSubAppName, LPCWSTR pszSubIdList); //xp theme shit
+extern BOOL (__stdcall *IsAppThemed)(void);
+
+
+#define DWM_COMPOSITION_CHECK ((UINT)-1)
+#define DWM_COMPOSITION_DISABLED ((UINT)0)
+#define DWM_COMPOSITION_ENABLED ((UINT)1)
+
+static UINT dwmCompositionEnabled = DWM_COMPOSITION_CHECK;
+
+
+static BOOL CALLBACK SkinChangedNotifyCB(HWND hwnd, LPARAM param)
+{
+ SendMessageW(hwnd, (UINT)WM_ML_IPC, MAKEWPARAM(TRUE, param), (LPARAM)ML_IPC_SKINNEDWND_SKINCHANGED);
+ return TRUE;
+}
+
+SkinnedWnd *SkinnedWnd::GetFromHWND(HWND hwndSkinned)
+{
+ return (hwndSkinned && IsWindow(hwndSkinned)) ? (SkinnedWnd*)GetPropW(hwndSkinned, WNDDATAPROPW) : NULL;
+}
+
+BOOL SkinnedWnd::IsDwmCompositionEnabled()
+{
+ if (DWM_COMPOSITION_CHECK == dwmCompositionEnabled)
+ {
+ dwmCompositionEnabled = DWM_COMPOSITION_DISABLED;
+ BOOL bEnabled;
+ if (S_OK == MlDwm_LoadLibrary() && S_OK == MlDwm_IsCompositionEnabled(&bEnabled) && bEnabled)
+ dwmCompositionEnabled = DWM_COMPOSITION_ENABLED;
+ }
+ return (DWM_COMPOSITION_ENABLED == dwmCompositionEnabled);
+}
+
+SkinnedWnd::SkinnedWnd(BOOL bIsDialog)
+ : hwnd(NULL), style(SWS_NORMAL), uiState(NULL), redrawLock(0),
+ fnWndProc(NULL), wnddata(SKINNEDWND_TYPE_WINDOW | ((bIsDialog) ? SWS_DIALOG : 0))
+{
+ minSize.cx = 0;
+ minSize.cy = 0;
+ maxSize.cx = 0;
+ maxSize.cy = 0;
+
+ if (WM_NULL == WINAMP_WM_DIRECT_MOUSE_WHEEL)
+ WINAMP_WM_DIRECT_MOUSE_WHEEL = RegisterWindowMessageW(L"WINAMP_WM_DIRECT_MOUSE_WHEEL");
+}
+
+SkinnedWnd::~SkinnedWnd(void)
+{
+ if (!hwnd || !IsWindow(hwnd)) return;
+ RemovePropW(hwnd, WNDDATAPROPW);
+ if (fnWndProc)
+ {
+ INT index;
+ index = (SWS_DIALOG & wnddata) ? DWLP_DLGPROC : GWLP_WNDPROC;
+ (SWS_UNICODE & wnddata) ? SetWindowLongPtrW(hwnd, index, (LONGX86)(LONG_PTR)fnWndProc) : SetWindowLongPtrA(hwnd, index, (LONGX86)(LONG_PTR)fnWndProc);
+ }
+ if ((SWS_THEMED & wnddata) && IsAppThemed && IsAppThemed() && SetWindowTheme) SetWindowTheme(hwnd, NULL, NULL);
+}
+
+BOOL SkinnedWnd::IsUnicode(void)
+{
+ return ( 0 != (SWS_UNICODE & wnddata));
+}
+
+BOOL SkinnedWnd::IsAttached(void)
+{
+ return ( 0 != (SWS_ATTACHED & wnddata));
+}
+
+BOOL SkinnedWnd::Attach(HWND hwndToSkin)
+{
+ INT index;
+ if (hwnd) return FALSE;
+
+ hwnd = hwndToSkin;
+ if(!hwnd || GetPropW(hwnd, WNDDATAPROPW)) return FALSE;
+
+ wnddata &= (SKINNEDWND_TYPE_WINDOW | SWS_DIALOG);
+
+ if(IsWindowUnicode(hwnd)) wnddata |= SWS_UNICODE;
+
+ index = (SWS_DIALOG & wnddata) ? DWLP_DLGPROC : GWLP_WNDPROC;
+
+
+ fnWndProc= (WNDPROC)(LONG_PTR)((SWS_UNICODE & wnddata) ? SetWindowLongPtrW(hwnd, index, (LONGX86)(LONG_PTR)WindowProcReal) : SetWindowLongPtrA(hwnd, index, (LONGX86)(LONG_PTR)WindowProcReal));
+ if (!fnWndProc || !SetPropW(hwnd, WNDDATAPROPW, this)) return FALSE;
+
+ RemoveReflector(hwnd); // we will use this refelector
+
+ wnddata |= (SWS_ATTACHED | SWS_REFLECT);
+
+
+ if (S_OK == MlDwm_LoadLibrary())
+ {
+ DWMNCRENDERINGPOLICY ncrp = DWMNCRP_DISABLED;
+ DWORD allow = FALSE;
+ MlDwm_SetWindowAttribute(hwnd, DWMWA_NCRENDERING_POLICY, &ncrp, sizeof(ncrp));
+ MlDwm_SetWindowAttribute(hwnd, DWMWA_ALLOW_NCPAINT, &allow, sizeof(allow));
+ }
+
+ if (IsAppThemed && IsAppThemed() && SetWindowTheme)
+ {
+ SetWindowTheme(hwnd, NULL, L"");
+ wnddata |= SWS_THEMED;
+ }
+
+ uiState =(WORD)SendMessageW(hwnd, WM_QUERYUISTATE, 0, 0L);
+
+ return TRUE;
+}
+
+LRESULT SkinnedWnd::CallPrevWndProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ return (SWS_UNICODE & wnddata) ? CallWindowProcW(fnWndProc, hwnd, uMsg, wParam, lParam) : CallWindowProcA(fnWndProc, hwnd, uMsg, wParam, lParam);
+}
+
+LRESULT SkinnedWnd::CallDefWndProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ return (SWS_UNICODE & wnddata) ? DefWindowProcW(hwnd, uMsg, wParam, lParam) : DefWindowProcA(hwnd, uMsg, wParam, lParam);
+}
+
+void SkinnedWnd::OnSkinChanged(BOOL bNotifyChildren, BOOL bRedraw)
+{
+ if (SWS_USESKINFONT & style)
+ {
+ HFONT skinFont;
+
+ skinFont = (HFONT)MlStockObjects_Get(SKIN_FONT);
+
+ if (NULL == skinFont)
+ skinFont = (HFONT)MlStockObjects_Get(DEFAULT_FONT);
+
+ if (NULL != skinFont)
+ {
+ HFONT windowFont = (HFONT)CallPrevWndProc(WM_GETFONT, 0, 0L);
+ if (skinFont != windowFont)
+ {
+ DisableRedraw();
+
+ SendMessageW(hwnd, WM_SETFONT, (WPARAM)skinFont, MAKELPARAM(0, bRedraw));
+
+ if (FALSE != bRedraw)
+ {
+ SetWindowPos(hwnd, NULL, 0, 0, 0, 0,
+ SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE |
+ SWP_FRAMECHANGED | SWP_NOREDRAW);
+ }
+
+ EnableRedraw(SWR_NONE);
+ }
+ }
+ }
+
+ if (bNotifyChildren)
+ EnumChildWindows(hwnd, SkinChangedNotifyCB, bRedraw);
+
+ SendMessageW(hwnd, (UINT)WM_ML_IPC,
+ MAKEWPARAM(bNotifyChildren, bRedraw),
+ (LPARAM)ML_IPC_SKINNEDWND_SKINUPDATED);
+
+ if (bRedraw)
+ InvalidateRect(hwnd, NULL, TRUE);
+}
+
+void SkinnedWnd::OnSkinUpdated(BOOL bNotifyChildren, BOOL bRedraw)
+{
+}
+
+void SkinnedWnd::SkinChanged(BOOL bNotifyChildren, BOOL bRedraw)
+{
+ OnSkinChanged(bNotifyChildren, bRedraw);
+}
+
+void SkinnedWnd::EnableReflection(BOOL bEnable)
+{
+ wnddata = (wnddata & ~SWS_REFLECT) | ((bEnable) ? SWS_REFLECT : 0);
+}
+
+BOOL SkinnedWnd::SetStyle(UINT newStyle, BOOL bRedraw)
+{
+ style = newStyle;
+
+ if (NULL != hwnd)
+ SkinChanged(FALSE, bRedraw);
+
+ return TRUE;
+}
+
+void SkinnedWnd::SetMinMaxInfo(MLSKINNEDMINMAXINFO *minMax)
+{
+ if (NULL != minMax)
+ {
+ minSize.cx = minMax->min.cx;
+ if (minSize.cx < 0)
+ minSize.cx = 0;
+
+ minSize.cy = minMax->min.cy;
+ if (minSize.cy < 0)
+ minSize.cy = 0;
+
+ maxSize.cx = minMax->max.cx;
+ if (maxSize.cx < 0)
+ maxSize.cx = 0;
+
+ maxSize.cy = minMax->max.cy;
+ if (maxSize.cy < 0)
+ maxSize.cy = 0;
+ }
+ else
+ {
+ memset(&minSize, 0, sizeof(minSize));
+ memset(&maxSize, 0, sizeof(maxSize));
+ }
+}
+
+
+BOOL SkinnedWnd::OnMediaLibraryIPC(INT msg, INT_PTR param, LRESULT *pResult)
+{
+ switch(msg)
+ {
+ case ML_IPC_SKINNEDWND_ISSKINNED: *pResult = IsAttached(); return TRUE;
+ case ML_IPC_SKINNEDWND_SKINCHANGED: SkinChanged(LOWORD(param), HIWORD(param)); *pResult = 1; return TRUE;
+ case ML_IPC_SKINNEDWND_SKINUPDATED: OnSkinUpdated(LOWORD(param), HIWORD(param)); break;
+ case ML_IPC_SKINNEDWND_GETTYPE: *pResult = GetType(); return TRUE;
+ case ML_IPC_SKINNEDWND_ENABLEREFLECTION: EnableReflection((BOOL)param); *pResult = 1; return TRUE;
+ case ML_IPC_SKINNEDWND_GETPREVWNDPROC:
+ if (param) *((BOOL*)param) = (SWS_UNICODE & wnddata);
+ *pResult = (INT_PTR)fnWndProc;
+ return TRUE;
+ case ML_IPC_SKINNEDWND_SETSTYLE: *pResult = style; style = (UINT)param; return TRUE;
+ case ML_IPC_SKINNEDWND_GETSTYLE: *pResult = style; return TRUE;
+ case ML_IPC_SKINNEDWND_SETMINMAXINFO:
+ SetMinMaxInfo((MLSKINNEDMINMAXINFO*)param);
+ *pResult = TRUE;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+INT SkinnedWnd::OnNcHitTest(POINTS pts)
+{
+ return (INT)CallPrevWndProc(WM_NCHITTEST, 0, *(LPARAM*)&pts);
+}
+
+void SkinnedWnd::DrawBorder(HDC hdc, RECT *prc, UINT type, HPEN pen)
+{
+ HPEN penOld;
+ INT o = (BORDER_WIDTH/2) + ((BORDER_WIDTH%2) ? 1 : 0);
+
+ switch(type)
+ {
+ case BORDER_SUNKEN:
+ case BORDER_FLAT:
+ penOld = (HPEN)SelectObject(hdc, pen);
+
+ MoveToEx(hdc, prc->right - o, prc->top, NULL);
+ LineTo(hdc, prc->right - o, prc->bottom);
+ MoveToEx(hdc, prc->right - BORDER_WIDTH, prc->bottom - o, NULL);
+ LineTo(hdc, prc->left - 1, prc->bottom - o);
+
+ if (BORDER_FLAT == type)
+ {
+ MoveToEx(hdc, prc->left + BORDER_WIDTH/2, prc->bottom - BORDER_WIDTH, NULL);
+ LineTo(hdc, prc->left + BORDER_WIDTH/2, prc->top);
+ MoveToEx(hdc, prc->left, prc->top + BORDER_WIDTH/2, NULL);
+ LineTo(hdc, prc->right - BORDER_WIDTH, prc->top + BORDER_WIDTH/2);
+ }
+ SelectObject(hdc, penOld);
+ break;
+ }
+}
+
+UINT SkinnedWnd::GetBorderType(void)
+{
+ DWORD ws = (DWORD)GetWindowLongPtrW(hwnd, GWL_EXSTYLE);
+ if (WS_EX_STATICEDGE & ws) return BORDER_FLAT;
+ else if (WS_EX_CLIENTEDGE & ws) return BORDER_SUNKEN;
+ ws = (DWORD)GetWindowLongPtrW(hwnd, GWL_STYLE);
+ return (WS_BORDER & ws) ? BORDER_FLAT : BORDER_NONE;
+}
+
+void SkinnedWnd::DrawBorder(HDC hdc)
+{
+ UINT borderType = GetBorderType();
+
+ if (BORDER_NONE != borderType)
+ {
+ RECT rc;
+ GetWindowRect(hwnd, &rc);
+ OffsetRect(&rc, -rc.left, -rc.top);
+ DrawBorder(hdc, &rc, borderType, GetBorderPen());
+ }
+}
+
+void SkinnedWnd::OnNcPaint(HRGN rgnUpdate)
+{
+ UINT borderType = GetBorderType();
+ if (BORDER_NONE == borderType) return;
+
+ UINT flags = DCX_PARENTCLIP | DCX_CACHE | DCX_WINDOW | DCX_CLIPSIBLINGS |
+ DCX_INTERSECTUPDATE | DCX_VALIDATE;
+
+ HDC hdc = GetDCEx(hwnd, ((HRGN)NULLREGION != rgnUpdate) ? rgnUpdate : NULL, flags);
+
+ if (NULL == hdc) return;
+
+ DrawBorder(hdc);
+ ReleaseDC(hwnd, hdc);
+}
+
+
+INT SkinnedWnd::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS *pncsp)
+{
+ UINT borderType = GetBorderType();
+ switch(borderType)
+ {
+ case BORDER_SUNKEN:
+ case BORDER_FLAT:
+ if (bCalcValidRects)
+ {
+ SetRect(&pncsp->rgrc[0],
+ pncsp->lppos->x, pncsp->lppos->y,
+ pncsp->lppos->x + pncsp->lppos->cx - BORDER_WIDTH, pncsp->lppos->y + pncsp->lppos->cy - BORDER_WIDTH);
+ }
+ else
+ {
+ GetWindowRect(hwnd, &pncsp->rgrc[0]);
+ pncsp->rgrc[0].right -= BORDER_WIDTH;
+ pncsp->rgrc[0].bottom -= BORDER_WIDTH;
+
+ }
+ if (BORDER_FLAT == borderType)
+ {
+ pncsp->rgrc[0].left += BORDER_WIDTH;
+ pncsp->rgrc[0].top += BORDER_WIDTH;
+ }
+ break;
+ }
+
+ return 0;
+}
+
+void SkinnedWnd::OnPrint(HDC hdc, UINT options)
+{
+ if ((PRF_CHECKVISIBLE & options) && !IsWindowVisible(hwnd)) return;
+ if (PRF_NONCLIENT & options) DrawBorder(hdc);
+ if (PRF_CLIENT & options)
+ {
+ CallPrevWndProc(WM_PRINT, (WPARAM)hdc, (LPARAM)(~(PRF_NONCLIENT | PRF_CHECKVISIBLE) & options));
+ }
+}
+
+HPEN SkinnedWnd::GetBorderPen(void)
+{
+ return (HPEN)MlStockObjects_Get(HILITE_PEN);
+}
+
+
+void SkinnedWnd::OnUpdateUIState(UINT uAction, UINT uState)
+{
+ CallPrevWndProc(WM_UPDATEUISTATE, MAKEWPARAM(uAction, uState), 0L);
+ uiState =(WORD)SendMessageW(hwnd, WM_QUERYUISTATE, 0, 0L);
+}
+
+void SkinnedWnd::OnStyleChanged(INT styleType, STYLESTRUCT *pss)
+{
+ if (0 != redrawLock)
+ {
+ if (0 != (GWL_STYLE & styleType) &&
+ (WS_VISIBLE & pss->styleOld) != (WS_VISIBLE & pss->styleNew))
+ {
+ redrawLock = 0;
+ }
+ }
+
+ CallPrevWndProc(WM_STYLECHANGED, (WPARAM)styleType, (LPARAM)pss);
+}
+
+void SkinnedWnd::OnDwmCompositionChanged(void)
+{
+ dwmCompositionEnabled = DWM_COMPOSITION_CHECK;
+}
+
+void SkinnedWnd::DisableRedraw()
+{
+ if (0 == redrawLock)
+ {
+ UINT windowStyle = (UINT)GetWindowLongPtrW(hwnd, GWL_STYLE);
+ if (0 == (WS_VISIBLE & windowStyle))
+ return;
+
+ CallDefWndProc(WM_SETREDRAW, FALSE, 0L);
+ }
+
+ redrawLock++;
+}
+
+void SkinnedWnd::EnableRedraw(SkinnedWndRedraw redrawFlags)
+{
+ UINT rdwFlags(0);
+
+ if (0 == redrawLock)
+ return;
+
+ redrawLock--;
+ if (0 != redrawLock)
+ return;
+
+ CallDefWndProc(WM_SETREDRAW, TRUE, 0L);
+
+ if (0 != (SWR_INVALIDATE & redrawFlags))
+ {
+ rdwFlags |= RDW_INVALIDATE;
+ if (0 != (SWR_UPDATE & redrawFlags))
+ rdwFlags |= RDW_UPDATENOW;
+ }
+
+ if (0 != (SWR_ERASE & redrawFlags))
+ {
+ rdwFlags |= RDW_ERASE;
+ if (0 != (SWR_UPDATE & redrawFlags))
+ rdwFlags |= RDW_ERASENOW;
+ }
+
+ if (0 != rdwFlags)
+ {
+ if (0 != (SWR_ALLCHILDREN & redrawFlags))
+ rdwFlags |= RDW_ALLCHILDREN;
+
+ RedrawWindow(hwnd, NULL, NULL, rdwFlags);
+ }
+
+}
+
+BOOL SkinnedWnd::OnDirectMouseWheel(INT delta, UINT vtKey, POINTS pts)
+{
+ SendMessageW(hwnd, WM_MOUSEWHEEL, MAKEWPARAM(vtKey, delta), *((LPARAM*)&pts));
+ return TRUE;
+}
+
+void SkinnedWnd::OnGetMinMaxInfo(MINMAXINFO *minMax)
+{
+ if (NULL == minMax)
+ return;
+
+ CallPrevWndProc(WM_GETMINMAXINFO, 0, (LPARAM)minMax);
+
+ if (0 != minSize.cx)
+ minMax->ptMinTrackSize.x = minSize.cx;
+
+ if (0 != minSize.cy)
+ minMax->ptMinTrackSize.y = minSize.cy;
+
+ if (0 != maxSize.cx)
+ minMax->ptMaxTrackSize.x = maxSize.cx;
+
+ if (0 != maxSize.cy)
+ minMax->ptMaxTrackSize.y = maxSize.cy;
+}
+
+LRESULT SkinnedWnd::WindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch(uMsg)
+ {
+ case WM_NCHITTEST: return OnNcHitTest(MAKEPOINTS(lParam));
+ case WM_NCPAINT: OnNcPaint((HRGN)wParam); return 0;
+ case WM_NCCALCSIZE: return OnNcCalcSize((BOOL)wParam, (NCCALCSIZE_PARAMS*)lParam);
+ case WM_PRINT: OnPrint((HDC)wParam, (UINT)lParam); return 0;
+ case WM_UPDATEUISTATE: OnUpdateUIState(LOWORD(wParam), HIWORD(wParam)); return 0;
+ case WM_STYLECHANGED: OnStyleChanged((INT)wParam, (STYLESTRUCT*)lParam); return 0;
+ case WM_SUPPORTREFLECT:
+ {
+ BOOL reflectionSupported = (0 != (SWS_REFLECT & wnddata) && CanReflect((UINT)wParam));
+ if (0 != (SWS_DIALOG & wnddata))
+ {
+ SetWindowLongPtrW(hwnd, DWLP_MSGRESULT, reflectionSupported);
+ return TRUE;
+ }
+ return reflectionSupported;
+ }
+ case WM_ML_IPC:
+ {
+ LRESULT result;
+ if (OnMediaLibraryIPC((INT)lParam, (INT_PTR)wParam, &result))
+ {
+ if (SWS_DIALOG & wnddata)
+ {
+ SetWindowLongPtrW(hwnd, DWLP_MSGRESULT, (LONGX86)result);
+ return TRUE;
+ }
+ return result;
+ }
+ break;
+ }
+
+ case WM_DWMCOMPOSITIONCHANGED: OnDwmCompositionChanged(); return 0;
+ case WM_GETMINMAXINFO: OnGetMinMaxInfo((MINMAXINFO*)lParam); return 0;
+
+ }
+
+ // Reflection
+ if (0 != (SWS_REFLECT & wnddata))
+ {
+ LRESULT result;
+ if (ReflectMessage(hwnd, uMsg, wParam, lParam, (0 != (SWS_DIALOG & wnddata)), &result))
+ return result;
+ }
+
+ if ( 0 == (SWS_NO_DIRECT_MOUSE_WHEEL & style) &&
+ WINAMP_WM_DIRECT_MOUSE_WHEEL == uMsg &&
+ WM_NULL != WINAMP_WM_DIRECT_MOUSE_WHEEL &&
+ FALSE != OnDirectMouseWheel(GET_WHEEL_DELTA_WPARAM(wParam), GET_KEYSTATE_WPARAM(wParam), MAKEPOINTS(lParam)))
+ {
+ if (0 != (SWS_DIALOG & wnddata))
+ SetWindowLongPtrW(hwnd, DWLP_MSGRESULT, TRUE);
+ return TRUE;
+ }
+
+ return CallPrevWndProc(uMsg, wParam, lParam);
+}
+
+LRESULT WINAPI SkinnedWnd::WindowProcReal(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ SkinnedWnd *pWnd = (SkinnedWnd*)GetPropW(hwnd, WNDDATAPROPW);
+ if (!pWnd)
+ return (IsWindowUnicode(hwnd)) ? DefWindowProcW(hwnd, uMsg, wParam, lParam) : DefWindowProcA(hwnd, uMsg, wParam, lParam);
+
+ switch(uMsg)
+ {
+ case WM_NCDESTROY:
+ {
+ WNDPROC fnWndProc = pWnd->fnWndProc;
+ delete(pWnd);
+
+ return IsWindowUnicode(hwnd) ? CallWindowProcW(fnWndProc, hwnd, uMsg, wParam, lParam) : CallWindowProcA(fnWndProc, hwnd, uMsg, wParam, lParam);
+ }
+ break;
+ }
+ return pWnd->WindowProc(uMsg, wParam, lParam);
+} \ No newline at end of file