123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569 |
- #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);
- }
|