diff options
author | Jean-Francois Mauguit <jfmauguit@mac.com> | 2024-09-24 09:03:25 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-24 09:03:25 -0400 |
commit | bab614c421ed7ae329d26bf028c4a3b1d2450f5a (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Winamp/skinWindow.cpp | |
parent | 4bde6044fddf053f31795b9eaccdd2a5a527d21f (diff) | |
parent | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (diff) | |
download | winamp-bab614c421ed7ae329d26bf028c4a3b1d2450f5a.tar.gz |
Merge pull request #5 from WinampDesktop/community
Merge to main
Diffstat (limited to 'Src/Winamp/skinWindow.cpp')
-rw-r--r-- | Src/Winamp/skinWindow.cpp | 1311 |
1 files changed, 1311 insertions, 0 deletions
diff --git a/Src/Winamp/skinWindow.cpp b/Src/Winamp/skinWindow.cpp new file mode 100644 index 00000000..8a4ddc12 --- /dev/null +++ b/Src/Winamp/skinWindow.cpp @@ -0,0 +1,1311 @@ +#include <windowsx.h> + +#include "main.h" +#include "./api.h" +#include "./wa_dlg.h" +#include "./skinWindow.h" +#include "./skinWindowIPC.h" +#include "./wintheme.h" +#include "./draw.h" + +#ifndef ARRAYSIZE +#define ARRAYSIZE(blah) (sizeof(blah)/sizeof(*blah)) +#endif + +#ifndef OCR_NORMAL +#define OCR_NORMAL 32512 +#endif + +#ifndef LONGX86 +#ifdef _WIN64 + #define LONGX86 LONG_PTR +#else /*_WIN64*/ + #define LONGX86 LONG +#endif /*_WIN64*/ +#endif // LONGX86 + +#ifdef __cplusplus + #define SENDMSG(__hwnd, __msgId, __wParam, __lParam) ::SendMessageW((__hwnd), (__msgId), (__wParam), (__lParam)) +#else + #define SENDMSG(__hwnd, __msgId, __wParam, __lParam) SendMessageW((__hwnd), (__msgId), (__wParam), (__lParam)) +#endif // __cplusplus + +#define SENDWAIPC(__ipcMsgId, __param) SENDMSG(hMainWindow, WM_WA_IPC, (WPARAM)(__param), (LPARAM)(__ipcMsgId)) + +#ifndef WM_NCUAHDRAWCAPTION +#define WM_NCUAHDRAWCAPTION 0x00AE +#define WM_NCUAHDRAWFRAME 0x00AF +#endif //WM_NCUAHDRAWCAPTION + +// additional WM_SYSCOMMAND commands +#define SC_DRAGMOVE 0xF012 +#define SC_DRAGSIZE_N 0xF003 +#define SC_DRAGSIZE_S 0xF006 +#define SC_DRAGSIZE_E 0xF002 +#define SC_DRAGSIZE_W 0xF001 +#define SC_DRAGSIZE_NW 0xF004 +#define SC_DRAGSIZE_NE 0xF005 +#define SC_DRAGSIZE_SW 0xF007 +#define SC_DRAGSIZE_SE 0xF008 + +#define MSGRESULT(__hwnd, __result) { SetWindowLongPtrW((__hwnd), DWL_MSGRESULT, ((LONGX86)(LONG_PTR)(__result))); return TRUE; } +#define CSTR_INVARIANT MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT) + +#define RESIZESTEP_CX 25 +#define RESIZESTEP_CY 29 + +static ATOM SKINNEDWND_ATOM = 0; + +// this flags for iternal use +#define SWS_EX_MASK 0xFFFF0000 +#define SWS_EX_ATTACHED 0x00010000 // window attached +#define SWS_EX_UNICODE 0x00020000 // winodow is unicode +#define SWS_EX_THEMED 0x00040000 // was themed before +#define SWS_EX_DIALOG 0x00100000 // treat this as dialog + +#define BORDERWIDTH_LEFT 11 +#define BORDERWIDTH_TOP 20 +#define BORDERWIDTH_RIGHT 8 +#define BORDERWIDTH_BOTTOM 14 + +#define CHILDBORDER_LEFT 1 +#define CHILDBORDER_TOP 1 +#define CHILDBORDER_RIGHT 1 +#define CHILDBORDER_BOTTOM 1 + +#define CLOSEBUTTON_HEIGHT 9 +#define CLOSEBUTTON_WIDTH 9 +#define CLOSEBUTTON_OFFSET_X -11 +#define CLOSEBUTTON_OFFSET_Y 3 + +#define SIZERGRIP_WIDTH 20 +#define SIZERGRIP_HEIGHT 20 + +#define MOVEABLEAREA_HEIGHT 13 + +#define BUTTON_NORMAL 0 +#define BUTTON_PUSHED 1 +#define BUTTON_DISABLED (-1) + +#ifndef TME_NONCLIENT +#define TME_NONCLIENT 0x00000010 +#define WM_NCMOUSELEAVE 0x02A2 +#endif + +#define WAMSG_CLOSE (WM_USER + 101) + +typedef struct __SKINNEDWND +{ + HWND hwnd; + WNDPROC fnWndProc; + DWORD flags; + POINT movingOffset; + INT buttonState; + embedWindowState embedData; +} SKINNEDWND; + +#define GetSkinnedWnd(__hwnd) ((SKINNEDWND*)GetPropW((__hwnd), ((LPCWSTR)MAKEINTATOM(SKINNEDWND_ATOM)))) +#define IsDialog(__skinnedWindow) (0 != (SWS_EX_DIALOG & (__skinnedWindow)->flags)) +#define IsUnicode(__skinnedWindow) (0 != (SWS_EX_UNICODE & (__skinnedWindow)->flags)) + +#define SetWndLongPtr(__skinnedWnd, __index, __data)\ + ((LONG_PTR)(IsUnicode(__skinnedWnd) ? SetWindowLongPtrW((__skinnedWnd)->hwnd, (__index), ((LONGX86)(LONG_PTR)(__data))) :\ + SetWindowLongPtrA((__skinnedWnd)->hwnd, (__index), ((LONGX86)(LONG_PTR)(__data))))) + +#define CallWndProc(__skinnedWnd, __uMsg, __wParam, __lParam)\ + (IsUnicode(__skinnedWnd) ?\ + CallWindowProcW((__skinnedWnd)->fnWndProc, (__skinnedWnd)->hwnd, (__uMsg), (__wParam), (__lParam)) :\ + CallWindowProcA((__skinnedWnd)->fnWndProc, (__skinnedWnd)->hwnd, (__uMsg), (__wParam), (__lParam))) + +#define DefWndProc(__skinnedWnd, __uMsg, __wParam, __lParam)\ + (IsUnicode(__skinnedWnd) ?\ + DefWindowProcW((__skinnedWnd)->hwnd, (__uMsg), (__wParam), (__lParam)) :\ + DefWindowProcA((__skinnedWnd)->hwnd, (__uMsg), (__wParam), (__lParam))) + +void draw_embed_tbar(HWND hwnd, int state, int w); +void SnapWindowToAllWindows(RECT *outrc, HWND hwndNoSnap); + +static LRESULT CALLBACK SkinnedWnd_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + +static void SkinnedWindow_Delete(SKINNEDWND *pWnd) +{ + HWND hDetached = NULL; + if (NULL == pWnd) return; + + hDetached = pWnd->hwnd; + SetWndLongPtr(pWnd, GWLP_USERDATA, NULL); + RemovePropW(pWnd->hwnd, ((LPCWSTR)MAKEINTATOM(SKINNEDWND_ATOM))); + + if (NULL != pWnd->embedData.me) + { + EnterCriticalSection(&embedcs); + embedWindowState *p = embedwndlist; + if (p == &pWnd->embedData) + { + embedwndlist=pWnd->embedData.link; // remove ourselves + embedwndlist_cnt--; + } + else + { + while (p) + { + if (p->link == &pWnd->embedData) + { + p->link=pWnd->embedData.link; + embedwndlist_cnt--; + break; + } + p=p->link; + } + } + LeaveCriticalSection(&embedcs); + } + + if (NULL != pWnd->fnWndProc) + { + SetWndLongPtr(pWnd, GWLP_WNDPROC, pWnd->fnWndProc); + pWnd->fnWndProc = NULL; + } + free(pWnd); + + if (NULL != hDetached) + { + SetWindowPos(hDetached, NULL, 0, 0, 0, 0, + SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_FRAMECHANGED); + } +} + +static SKINNEDWND *SkinnedWindow_Cerate(HWND hwndToSkin) +{ + if (NULL == hwndToSkin || !IsWindow(hwndToSkin)) + return NULL; + + if (NULL != GetSkinnedWnd(hwndToSkin)) + return NULL; + + if (0 == SKINNEDWND_ATOM) + { + SKINNEDWND_ATOM = GlobalAddAtomW(L"WASKINNEDWND"); + if (0 == SKINNEDWND_ATOM) + return NULL; + } + + SKINNEDWND *pWnd = (SKINNEDWND*)calloc(1, sizeof(SKINNEDWND)); + if (NULL == pWnd) + return NULL; + + pWnd->hwnd = hwndToSkin; + if (IsWindowUnicode(hwndToSkin)) pWnd->flags |= SWS_EX_UNICODE; + + WCHAR szName[128] = {0}; + if (GetClassNameW(hwndToSkin, szName, ARRAYSIZE(szName))) + { + if (CSTR_EQUAL == CompareStringW(CSTR_INVARIANT, NORM_IGNORECASE, szName, -1, L"#32770", -1)) + pWnd->flags |= SWS_EX_DIALOG; + } + + pWnd->fnWndProc = (WNDPROC)SetWndLongPtr(pWnd, GWLP_WNDPROC, SkinnedWnd_WindowProc); + if (NULL == pWnd->fnWndProc || !SetPropW(hwndToSkin, ((LPCWSTR)MAKEINTATOM(SKINNEDWND_ATOM)), pWnd)) + { + SkinnedWindow_Delete(pWnd); + return NULL; + } + pWnd->flags |= SWS_EX_ATTACHED; + + if (S_OK == Dwm_LoadLibrary()) + { + DWMNCRENDERINGPOLICY ncrp = DWMNCRP_DISABLED; + DWORD allow = FALSE; + DwmSetWindowAttribute(pWnd->hwnd, DWMWA_NCRENDERING_POLICY, &ncrp, sizeof(ncrp)); + DwmSetWindowAttribute(pWnd->hwnd, DWMWA_ALLOW_NCPAINT, &allow, sizeof(allow)); + } + + if (S_OK == UxTheme_LoadLibrary() && IsAppThemed()) + { + SetWindowTheme(pWnd->hwnd, NULL, L""); + pWnd->flags |= SWS_EX_THEMED; + } + + if (!config_embedwnd_freesize && + 0 == (WS_CHILD & GetWindowLongPtrW(pWnd->hwnd, GWL_STYLE))) + { + RECT rc; + if (GetWindowRect(hwndToSkin, &rc)) + { + LONG w, h; + OffsetRect(&rc, -rc.left, -rc.top); + + w = rc.right + (RESIZESTEP_CX - 1); + w -= w % RESIZESTEP_CX; + h = rc.bottom + (RESIZESTEP_CY - 1); + h -= h % RESIZESTEP_CY; + + if (w != rc.right || h != rc.bottom) + SetWindowPos(hwndToSkin, NULL, 0, 0, w, h, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE); + } + } + + return pWnd; +} + +BOOL SkinWindow(HWND hwndToSkin, REFGUID windowGuid, UINT flagsEx, FFCALLBACK callbackFF) +{ + SKINNEDWND *pWnd = SkinnedWindow_Cerate(hwndToSkin); + + if (NULL == pWnd) + return FALSE; + + pWnd->embedData.me = pWnd->hwnd; + pWnd->embedData.user_ptr = pWnd; + pWnd->embedData.flags |= (EMBED_FLAGS_GUID | flagsEx); + pWnd->embedData.guid = windowGuid; + + pWnd->embedData.callback = callbackFF; + if (NULL != pWnd->embedData.callback) + pWnd->embedData.flags |= EMBED_FLAGS_FFCALLBACK; + + GetWindowRect(pWnd->hwnd, &pWnd->embedData.r); + + EnterCriticalSection(&embedcs); + + pWnd->embedData.link = embedwndlist; + embedwndlist = &pWnd->embedData; + embedwndlist_cnt++; + + LeaveCriticalSection(&embedcs); + + SetWndLongPtr(pWnd, GWLP_USERDATA, &pWnd->embedData); + + return TRUE; +} + +static int SkinnedWindow_GetTextWidth(LPCTSTR pszText, INT cchText) +{ + int w = 0; + while (cchText--) + { + char c = *pszText++; + if (c >= 'a' && c <= 'z') c+='A'-'a'; + + if (c >= 'A' && c <= 'Z' && titlebar_font_widths[c-'A']) + w+=titlebar_font_widths[c-'A']; + else if (c >= '0' && c <= '9' && titlebar_font_widths[c-'0'] && Skin_UseGenNums) + w+=titlebar_font_num_widths[c-'0']; + else if (c == '-' && titlebar_font_widths[10] && Skin_UseGenNums) + w+=titlebar_font_num_widths[10]; + else if (c == ':' && titlebar_font_widths[11] && Skin_UseGenNums) + w+=titlebar_font_num_widths[11]; + else w+=titlebar_font_unknown_width; + + } + return w; +} + +static void SkinnedWindow_DrawText(HDC hdc, HDC hdcSrc, int xp, int yp, LPCTSTR pszText, INT cchText, RECT *prc, BOOL bActive) +{ + int w; + int srcY = 88 + ((bActive) ? 8 : 0); + int srcYnum = 72 + ((bActive) ? 8 : 0); + int bgsrcY = ((bActive) ? 21 : 0); + int bgX = prc->left; + int maxw = prc->right; + while (cchText-- && maxw > 0) + { + char c = *pszText++; + + if (bgX <= xp) + { + int bgW = 25; + if (bgW + bgX > prc->right) bgW = prc->right - bgX; + BitBlt(hdc, bgX, prc->top, bgW, (prc->bottom - prc->top), hdcSrc, 52, bgsrcY, SRCCOPY); + bgX += bgW; + } + + if (c >= 'a' && c <= 'z') c+='A'-'a'; + if (c >= 'A' && c <= 'Z' && titlebar_font_widths[c-'A']) + { + w = titlebar_font_widths[c - 'A']; + if (w > maxw) break; + + if (bgX <= (xp + w)) + { + int bgW = 25; + if (bgW + bgX > prc->right) bgW = prc->right - bgX; + BitBlt(hdc, bgX, prc->top, bgW, (prc->bottom - prc->top), hdcSrc, 52, bgsrcY, SRCCOPY); + bgX += bgW; + } + + BitBlt(hdc, xp, yp, w, 7, hdcSrc, titlebar_font_offsets[c - 'A'], srcY, SRCCOPY); + } + else if (c >= '0' && c <= '9' && titlebar_font_num_widths[c - '0'] && Skin_UseGenNums) + { + w = titlebar_font_num_widths[c - '0']; + if (w > maxw) break; + + if (bgX <= (xp + w)) + { + int bgW = 25; + if (bgW + bgX > prc->right) bgW = prc->right - bgX; + BitBlt(hdc, bgX, prc->top, bgW, (prc->bottom - prc->top), hdcSrc, 52, bgsrcY, SRCCOPY); + bgX += bgW; + } + + BitBlt(hdc, xp, yp, w, 7, hdcSrc, titlebar_font_num_offsets[c - '0'], srcYnum, SRCCOPY); + } + else if (c == '-' && titlebar_font_num_widths[10] && Skin_UseGenNums) + { + w = titlebar_font_num_widths[10]; + if (w > maxw) break; + + if (bgX <= (xp + w)) + { + int bgW = 25; + if (bgW + bgX > prc->right) bgW = prc->right - bgX; + BitBlt(hdc, bgX, prc->top, bgW, (prc->bottom - prc->top), hdcSrc, 52, bgsrcY, SRCCOPY); + bgX += bgW; + } + + BitBlt(hdc, xp, yp, w, 7, hdcSrc, titlebar_font_num_offsets[10], srcYnum, SRCCOPY); + } + else if (c == ':' && titlebar_font_num_widths[11] && Skin_UseGenNums) + { + w = titlebar_font_num_widths[11]; + if (w > maxw) break; + + if (bgX <= (xp + w)) + { + int bgW = 25; + if (bgW + bgX > prc->right) bgW = prc->right - bgX; + BitBlt(hdc, bgX, prc->top, bgW, (prc->bottom - prc->top), hdcSrc, 52, bgsrcY, SRCCOPY); + bgX += bgW; + } + + BitBlt(hdc, xp, yp, w, 7, hdcSrc, titlebar_font_num_offsets[11], srcYnum, SRCCOPY); + } + else + w = titlebar_font_unknown_width; + + xp += w; + maxw -= w; + } +} + +static void SkinnedWindow_DrawCloseButton(HDC hdc, HDC hdcSrc, RECT *prcWindow, BOOL bActive, INT buttonState) +{ + INT srcX, srcY; + + switch(buttonState) + { + case BUTTON_PUSHED: + srcX = 148; srcY = 42; + break; + case BUTTON_NORMAL: + srcX = 144; srcY = 3; + if (!bActive) srcY += 21; + break; + case BUTTON_DISABLED: + default: + srcX = 144; srcY = 3; + break; + } + BitBlt(hdc, prcWindow->right - 11,prcWindow->top + 3, 9, 9, hdcSrc,srcX, srcY, SRCCOPY); +} + +static void SkinnedWindow_DrawCaptionEx(HDC hdc, HDC hdcSrc, LPCTSTR pszText, INT cchText, int state, int w, int h) +{ + state = state ? 0 : 21; + int nt; + int xp=0; + int textw_exact = 0, textw = 0; + int cchTextOrig = cchText; + if (cchText > 0) + { + for(;cchText > 0; cchText--) + { + textw_exact = SkinnedWindow_GetTextWidth(pszText, cchText); + textw = textw_exact + 24; + textw -= textw % 25; + if ((w - textw) > 100) break; + textw = 0; + } + } + + BitBlt(hdc,xp,0,25,20, hdcSrc, 0, state,SRCCOPY); + xp+=25; + nt = (w - 100 - textw)/25; + if (nt > 0) + { + if (nt&1) + { + BitBlt(hdc,xp,0,12,20,hdcSrc,104,state,SRCCOPY); + xp+=12; + } + nt/=2; + while (nt-->0) + { + BitBlt(hdc,xp,0,25,20,hdcSrc,104,state,SRCCOPY); + xp+=25; + } + } + + if (cchText > 0) + { + BitBlt(hdc,xp,0,25,20,hdcSrc,26,state,SRCCOPY); + xp+=25; + nt = textw/25; + if (nt > 0) + { + + RECT rt; + SetRect(&rt, xp, 0, xp + textw, 20); + + SkinnedWindow_DrawText(hdc, hdcSrc, + rt.left + ((cchText == cchTextOrig) ? (textw - textw_exact)/2 : 0), 4, + pszText, cchText, &rt, state); + xp += nt*25; + } + + BitBlt(hdc,xp,0,25,20,hdcSrc,78,state,SRCCOPY); + xp+=25; + } + else + { + nt = (w - 50)/2; + if (nt > 25) nt = 25; + if (nt > 0) + { + BitBlt(hdc,xp, 0, nt,20,hdcSrc,104,state,SRCCOPY); + xp+=nt; + if (nt < 25 && 0 != (w - 50)%2)nt++; + BitBlt(hdc,xp, 0, nt, 20, hdcSrc,104 + (25- nt),state,SRCCOPY); + xp+=nt; + } + } + + nt = (w - 100 - textw)/25; + if (nt > 0) + { + if (nt&1) + { + BitBlt(hdc,xp,0,13,20,hdcSrc,104,state,SRCCOPY); + xp+=13; + } + nt/=2; + while (nt-->0) + { + BitBlt(hdc,xp,0,25,20,hdcSrc,104,state,SRCCOPY); + xp+=25; + } + } + nt = (w - 100 - textw) % 25; + if (nt > 0) + { + BitBlt(hdc,xp,0,nt,20,hdcSrc,104,state,SRCCOPY); + //StretchBlt(hdc,xp,0,nt,20,hdcSrc,104,state,25,20,SRCCOPY); + xp += nt; + } + BitBlt(hdc,xp,0,25,20,hdcSrc,130,state,SRCCOPY); +} + +static void SkinnedWindow_DrawCaption(SKINNEDWND *pWnd, BOOL bActive, POINT *cursor) +{ + RECT rc; + GetWindowRect(pWnd->hwnd, &rc); + OffsetRect(&rc, -rc.left, -rc.top); + + + UINT flags = DCX_PARENTCLIP | DCX_CACHE | DCX_WINDOW | DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | + DCX_INTERSECTUPDATE | DCX_VALIDATE | DCX_NORESETATTRS; + HDC hdc = GetDCEx(pWnd->hwnd, NULL, flags); + if (NULL == hdc) + return; + + do_palmode(hdc); + setSrcBM(embedBM); + + char szTitle[128] = {0}; + INT cchTitle = GetWindowTextA(pWnd->hwnd, szTitle, ARRAYSIZE(szTitle)); + + INT state = pWnd->buttonState; + if (BUTTON_PUSHED == state) + { + if (NULL == cursor || HTCLOSE != SendMessageW(pWnd->hwnd, WM_NCHITTEST, 0, MAKELPARAM(cursor->x, cursor->y))) + state = BUTTON_NORMAL; + } + + SkinnedWindow_DrawCaptionEx(hdc, bmDC, (LPCTSTR)szTitle, cchTitle, bActive ? 1 : (config_hilite?0:1), + rc.right - rc.left, rc.bottom - rc.top); + SkinnedWindow_DrawCloseButton(hdc, bmDC, &rc, bActive, state); + + unsetSrcBM(); + ReleaseDC(pWnd->hwnd, hdc); + +} + +static void SkinnedWindow_DrawBorder(SKINNEDWND *pWnd, HDC hdc, HRGN rgnUpdate, POINT *cursor) +{ + + DWORD style = GetWindowLongPtrW(pWnd->hwnd, GWL_STYLE); + if (0 == (WS_BORDER & style)) + return; + + RECT rc; + GetWindowRect(pWnd->hwnd, &rc); + OffsetRect(&rc, -rc.left, -rc.top); + LONG w = rc.right, h = rc.bottom; + + do_palmode(hdc); + setSrcBM(embedBM); + + if (0 != (WS_CHILD & style)) + { + if (!WADlg_initted()) + WADlg_init(hMainWindow); + COLORREF rgbOld = SetBkColor(hdc, WADlg_getColor(WADLG_HILITE)); + + RECT part; + SetRect(&part, rc.left, rc.top, rc.right, rc.top + CHILDBORDER_TOP); + ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &part, NULL, 0, NULL); + SetRect(&part, rc.right - CHILDBORDER_RIGHT, rc.top + CHILDBORDER_TOP, rc.right, rc.bottom - CHILDBORDER_BOTTOM); + ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &part, NULL, 0, NULL); + SetRect(&part, rc.left, rc.bottom - CHILDBORDER_BOTTOM, rc.right, rc.bottom); + ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &part, NULL, 0, NULL); + SetRect(&part, rc.left, rc.top + CHILDBORDER_TOP, rc.left + CHILDBORDER_LEFT, rc.bottom - CHILDBORDER_BOTTOM); + ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &part, NULL, 0, NULL); + + SetBkColor(hdc, rgbOld); + return; + } + + if (0 != (WS_CAPTION & style)) + { + char szTitle[128] = {0}; + INT cchTitle = GetWindowTextA(pWnd->hwnd, szTitle, ARRAYSIZE(szTitle)); + + INT state = pWnd->buttonState; + if (BUTTON_PUSHED == state) + { + if (NULL == cursor || HTCLOSE != SendMessageW(pWnd->hwnd, WM_NCHITTEST, 0, MAKELPARAM(cursor->x, cursor->y))) + state = BUTTON_NORMAL; + } + + BOOL bActive = (GetActiveWindow()==pWnd->hwnd) ? 1 : ((0 != config_hilite) ? 0 : 1); + SkinnedWindow_DrawCaptionEx(hdc, bmDC, (LPCTSTR)szTitle, cchTitle, bActive, w, h); + if (BUTTON_NORMAL != state) + SkinnedWindow_DrawCloseButton(hdc, bmDC, &rc, bActive, state); + } + + int y=(h-20-38)/29; + int yp=20,x,xp; + while (y-->0) + { + BitBlt(hdc,0,yp,11,29,bmDC,127,42,SRCCOPY); + BitBlt(hdc,w-8,yp,8,29,bmDC,139,42,SRCCOPY); + yp += 29; + } + y=(h-20-38)%29; + if (y) + { + BitBlt(hdc,0,yp,11,y,bmDC,127,42,SRCCOPY); + //StretchBlt(hdc,0,yp,11,y,bmDC,127,42,11,29,SRCCOPY); + BitBlt(hdc,w-8,yp,8,y,bmDC,139,42,SRCCOPY); + //StretchBlt(hdc,w-8,yp,8,y,bmDC,139,42,8,29,SRCCOPY); + yp += y; + } + + // 24 pixel lamity + BitBlt(hdc,0,yp,11,24,bmDC,158,42,SRCCOPY); + BitBlt(hdc,w-8,yp,8,24,bmDC,170,42,SRCCOPY); + yp += 24; + + int realW = (w < 250) ? (w/2) : 125; + BitBlt(hdc,0,yp,realW,14,bmDC,0,42,SRCCOPY); + + x=(w-125*2)/25; + xp=realW; + while (x-->0) + { + BitBlt(hdc,xp,yp,25,14,bmDC,127,72,SRCCOPY); + xp+=25; + } + x=(w-125*2)%25; + if (x > 0) + { + BitBlt(hdc,xp,yp,x,14,bmDC,127,72,SRCCOPY); + //StretchBlt(hdc,xp,yp,x,14,bmDC,127,72,25,14,SRCCOPY); + xp+=x; + } + + if (realW < 125 && 0 != (w%2)) realW++; + BitBlt(hdc,xp,yp,realW,14,bmDC, (125 - realW),57,SRCCOPY); + + if (0 != (EMBED_FLAGS_NORESIZE & pWnd->embedData.flags)) + { + BitBlt(hdc,xp+112,yp+2,7,7,bmDC,118,72,SRCCOPY); + } + + unsetSrcBM(); +} + +static BOOL SkinnedWindow_OnShowWindow(SKINNEDWND *pWnd, BOOL bShow, UINT flags) +{ + if (pWnd->embedData.reparenting) + return TRUE; + + SENDWAIPC(((bShow) ? IPC_CB_ONSHOWWND : IPC_CB_ONHIDEWND), pWnd->hwnd); + return FALSE; +} + +static LRESULT SkinnedWindow_OnNcCalcSize(SKINNEDWND *pWnd, BOOL bCalcValidRects, NCCALCSIZE_PARAMS *pncsp) +{ + + DWORD style = (DWORD)GetWindowLongPtrW(pWnd->hwnd, GWL_STYLE); + + RECT rc; + CopyRect(&rc, &pncsp->rgrc[0]); + CallWndProc(pWnd, WM_NCCALCSIZE, bCalcValidRects, (LPARAM)pncsp); + CopyRect(&pncsp->rgrc[0], &rc); + + if (bCalcValidRects) + SetRect(&pncsp->rgrc[0], pncsp->lppos->x, pncsp->lppos->y, + pncsp->lppos->x + pncsp->lppos->cx, pncsp->lppos->y + pncsp->lppos->cy); + else + { + GetWindowRect(pWnd->hwnd, &pncsp->rgrc[0]); + if (0 != (WS_CHILD & style)) + { + HWND hParent = GetParent(pWnd->hwnd); + if (NULL != hParent) + MapWindowPoints(HWND_DESKTOP, hParent, (POINT*)&pncsp->rgrc[0], 2); + } + } + + if (0 != (WS_BORDER & style)) + { + if (0 != (WS_CHILD & style)) + { + pncsp->rgrc[0].top += CHILDBORDER_TOP; + pncsp->rgrc[0].left += CHILDBORDER_LEFT; + pncsp->rgrc[0].right -= CHILDBORDER_RIGHT; + pncsp->rgrc[0].bottom -= CHILDBORDER_BOTTOM; + } + else + { + pncsp->rgrc[0].top += BORDERWIDTH_TOP; + pncsp->rgrc[0].left += BORDERWIDTH_LEFT; + pncsp->rgrc[0].right -= BORDERWIDTH_RIGHT; + pncsp->rgrc[0].bottom -= BORDERWIDTH_BOTTOM; + } + } + + return 0; +} + +static void SkinnedWindow_OnNcPaint(SKINNEDWND *pWnd, HRGN rgnUpdate) +{ + if (0 == (WS_BORDER & GetWindowLongPtrW(pWnd->hwnd, GWL_STYLE))) + return; + + UINT flags = DCX_PARENTCLIP | DCX_CACHE | DCX_WINDOW | DCX_CLIPSIBLINGS | + DCX_INTERSECTUPDATE | DCX_VALIDATE | DCX_NORESETATTRS; + + HDC hdc = GetDCEx(pWnd->hwnd, ((HRGN)NULLREGION != rgnUpdate) ? rgnUpdate : NULL, flags); + if (NULL == hdc) + return; + POINT pt; + GetCursorPos(&pt); + SkinnedWindow_DrawBorder(pWnd, hdc, rgnUpdate, &pt); + ReleaseDC(pWnd->hwnd, hdc); +} + +static void SkinnedWindow_OnPrint(SKINNEDWND *pWnd, HDC hdc, UINT options) +{ + if ((PRF_CHECKVISIBLE & options) && !IsWindowVisible(pWnd->hwnd)) return; + if (PRF_NONCLIENT & options) + { + POINT pt = {0, 0}; + SkinnedWindow_DrawBorder(pWnd, hdc, (HRGN)NULLREGION, &pt); + } + if (PRF_CLIENT & options) + CallWndProc(pWnd, WM_PRINT, (WPARAM)hdc, (LPARAM)(~(PRF_NONCLIENT | PRF_CHECKVISIBLE) & options)); +} + +static LRESULT SkinnedWindow_OnNcHitTest(SKINNEDWND *pWnd, POINTS pts) +{ + POINT pt; + RECT rw, rt; + POINTSTOPOINT(pt, pts); + + DWORD style = (DWORD)GetWindowLongPtrW(pWnd->hwnd, GWL_STYLE); + + if (0 != (WS_DISABLED & style)) + return HTERROR; + + if (0 != (WS_CHILD & style)) + { + if (0 != (WS_BORDER & style)) + { + GetWindowRect(pWnd->hwnd, &rw); + rw.left += CHILDBORDER_LEFT; + rw.top += CHILDBORDER_TOP; + rw.right -= CHILDBORDER_RIGHT; + rw.bottom -= CHILDBORDER_BOTTOM; + if (PtInRect(&rt, pt)) + return HTBORDER; + } + return HTCLIENT; + } + + GetWindowRect(pWnd->hwnd, &rw); + + if (0 != (WS_CAPTION & style)) + { + SetRect(&rt, rw.left, rw.top, rw.right, rw.top + BORDERWIDTH_TOP); + if (PtInRect(&rt, pt)) // caption + { + SetRect(&rt, rw.right + CLOSEBUTTON_OFFSET_X, rw.top + CLOSEBUTTON_OFFSET_Y, + rw.right + CLOSEBUTTON_OFFSET_X + CLOSEBUTTON_WIDTH, rw.top + CLOSEBUTTON_OFFSET_Y + CLOSEBUTTON_HEIGHT); + if (PtInRect(&rt, pt)) // close button + return HTCLOSE; + return HTCAPTION; + } + } + + if (0 != (WS_BORDER & style)) + { + SetRect(&rt, rw.left, rw.top + BORDERWIDTH_TOP, rw.left + BORDERWIDTH_LEFT, rw.bottom - BORDERWIDTH_BOTTOM); + if (PtInRect(&rt, pt)) + return HTBORDER; // left side (non resizable) + + SetRect(&rt, rw.right - BORDERWIDTH_RIGHT, rw.top + BORDERWIDTH_TOP, rw.right, rw.bottom - SIZERGRIP_HEIGHT); + if (PtInRect(&rt, pt)) + return HTBORDER; // right side (non resizable) + + SetRect(&rt, rw.right - BORDERWIDTH_RIGHT, rw.bottom - SIZERGRIP_HEIGHT, rw.right, rw.bottom); + if (PtInRect(&rt, pt)) + return (0 == (EMBED_FLAGS_NORESIZE & pWnd->embedData.flags)) ? HTBOTTOMRIGHT : HTBORDER; // sizer bottomright + + SetRect(&rt, rw.left, rw.bottom - BORDERWIDTH_BOTTOM, rw.right -SIZERGRIP_WIDTH, rw.bottom); + if (PtInRect(&rt, pt)) + return HTBORDER; // bottom_left + bottom (non resizable) + + SetRect(&rt, rw.right - SIZERGRIP_WIDTH, rw.bottom - BORDERWIDTH_BOTTOM, rw.right, rw.bottom); + if (PtInRect(&rt, pt)) + return (0 == (EMBED_FLAGS_NORESIZE & pWnd->embedData.flags)) ? HTBOTTOMRIGHT : HTBORDER; // sizer bottomright + } + + SetRect(&rt, rw.left, rw.top, rw.right, rw.bottom); + if (PtInRect(&rt, pt)) + return HTCLIENT; // client + + return HTNOWHERE; +} + +static LRESULT SkinnedWindow_OnSetCursor(SKINNEDWND *pWnd, HWND hwndCursor, INT hitTest, UINT uMsg) +{ + HCURSOR hCursor = NULL; + + switch(uMsg) + { + case WM_LBUTTONDOWN: + case WM_RBUTTONDOWN: + case WM_MBUTTONDOWN: + case WM_XBUTTONDOWN: + DisabledWindow_OnMouseClick(pWnd->hwnd); + break; + } + + if (config_usecursors && !disable_skin_cursors) + { + int index = 15+5; // PNormal.cur + switch(hitTest) + { + case HTCAPTION: + { // this is required to emulate old behavior + POINT pt; + RECT rw; + GetCursorPos(&pt); + GetWindowRect(pWnd->hwnd, &rw); + rw.bottom = rw.top + MOVEABLEAREA_HEIGHT; + index = 15 + ((PtInRect(&rw, pt)) ? 2 : 5); // PTBar.cur + } + break; + case HTCLOSE: + index = 15 + 1; // PClose.cur + break; + case HTLEFT: + case HTRIGHT: + case HTTOP: + case HTTOPLEFT: + case HTTOPRIGHT: + case HTBOTTOM: + case HTBOTTOMLEFT: + case HTBOTTOMRIGHT: + index = 15 + 4;// PSize.cur + break; + } + hCursor = Skin_Cursors[index]; + } + + if (NULL != hCursor) + { + SetCursor(hCursor); + return TRUE; + } + return CallWndProc(pWnd, WM_SETCURSOR, (WPARAM)hwndCursor, MAKELPARAM(hitTest, uMsg)); +} + +static LRESULT SkinnedWindow_OnNcActivate(SKINNEDWND *pWnd, BOOL bActivate) +{ + if (0 == (WS_CAPTION & GetWindowLongPtrW(pWnd->hwnd, GWL_STYLE))) + return TRUE; + + POINT pt; + GetCursorPos(&pt); + SkinnedWindow_DrawCaption(pWnd, bActivate, &pt); + return TRUE; +} + +static void SkinnedWindow_OnActivate(SKINNEDWND *pWnd, unsigned int action, BOOL minimized, HWND otherWindow) +{ + if (NULL == pWnd) + return; + + if (NULL != WASABI_API_APP) + { + if (WA_INACTIVE == action) + WASABI_API_APP->ActiveDialog_Unregister(pWnd->hwnd); + else + WASABI_API_APP->ActiveDialog_Register(pWnd->hwnd); + } +} + +static BOOL SkinnedWindow_OnNcLButtonDown(SKINNEDWND *pWnd, INT hitTest, POINTS pts) +{ + switch(hitTest) + { + case HTCLOSE: + { + pWnd->buttonState = BUTTON_PUSHED; + + TRACKMOUSEEVENT tm; + ZeroMemory(&tm, sizeof(TRACKMOUSEEVENT)); + tm.cbSize = sizeof(TRACKMOUSEEVENT); + tm.dwFlags = TME_LEAVE | TME_NONCLIENT; + tm.hwndTrack = pWnd->hwnd; + TrackMouseEvent(&tm); + + RedrawWindow(pWnd->hwnd, NULL, NULL, RDW_INVALIDATE | RDW_FRAME | RDW_UPDATENOW); + } + return TRUE; + case HTCAPTION: + if (IsWindowEnabled(pWnd->hwnd) && + GetActiveWindow() != pWnd->hwnd) + SetActiveWindow(pWnd->hwnd); + { + RECT rw; + if (GetWindowRect(pWnd->hwnd, &rw)) + { + pWnd->movingOffset.x = pts.x - rw.left; + pWnd->movingOffset.y = pts.y - rw.top; + } + } + SendMessageW(pWnd->hwnd, WM_SYSCOMMAND, (SC_MOVE | 0x0002), (*(LPARAM*)&pts)); + return TRUE; + case HTBOTTOM: + case HTBOTTOMLEFT: + case HTBOTTOMRIGHT: + if (IsWindowEnabled(pWnd->hwnd) && + GetActiveWindow() != pWnd->hwnd) + SetActiveWindow(pWnd->hwnd); + SendMessageW(pWnd->hwnd, WM_SYSCOMMAND, SC_SIZE + hitTest - (HTLEFT - WMSZ_LEFT), (*(LPARAM*)&pts)); + return TRUE; + } + return FALSE; +} + +static BOOL SkinnedWindow_OnNcLButtonUp(SKINNEDWND *pWnd, INT hitTest, POINTS pts) +{ + BOOL bProcessed = FALSE; + if (HTCLOSE == hitTest && BUTTON_PUSHED == pWnd->buttonState) + { + SNDMSG(pWnd->hwnd, WM_SYSCOMMAND, SC_CLOSE, *(LPARAM*)&pts); + bProcessed = TRUE; + } + + if (BUTTON_PUSHED == pWnd->buttonState) + { + pWnd->buttonState = BUTTON_NORMAL; + RedrawWindow(pWnd->hwnd, NULL, NULL, RDW_INVALIDATE | RDW_FRAME); + } + + return bProcessed; +} + +static BOOL SkinnedWindow_OnNcRButtonDown(SKINNEDWND *pWnd, INT hitTest, POINTS pts) +{ + return TRUE; +} + +static BOOL SkinnedWindow_OnNcRButtonUp(SKINNEDWND *pWnd, INT hitTest, POINTS pts) +{ + int ret = DoTrackPopup(main_menu, TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD, pts.x, pts.y, pWnd->hwnd); + if (ret) + SendMessageW(hMainWindow,WM_COMMAND,ret,0); + return TRUE; +} + +static void SkinnedWindow_OnNcMouseMove(SKINNEDWND *pWnd, INT hitTest, POINTS pts) +{ + if (BUTTON_PUSHED == pWnd->buttonState && HTCLOSE == hitTest) + { + RedrawWindow(pWnd->hwnd, NULL, NULL, RDW_INVALIDATE | RDW_FRAME); + } +} + +static void SkinnedWindow_OnNcMouseLeave(SKINNEDWND *pWnd) +{ + if (BUTTON_PUSHED == pWnd->buttonState) + { + if(0 != (0x8000 & GetAsyncKeyState(GetSystemMetrics(SM_SWAPBUTTON) ? VK_RBUTTON : VK_LBUTTON))) + { + TRACKMOUSEEVENT tm; + ZeroMemory(&tm, sizeof(TRACKMOUSEEVENT)); + tm.cbSize = sizeof(TRACKMOUSEEVENT); + tm.dwFlags = TME_LEAVE | TME_NONCLIENT; + tm.hwndTrack = pWnd->hwnd; + TrackMouseEvent(&tm); + } + else + { + pWnd->buttonState = BUTTON_NORMAL; + RedrawWindow(pWnd->hwnd, NULL, NULL, RDW_INVALIDATE | RDW_FRAME); + } + } +} + +static void SkinnedWindow_OnWinampCustomClose(SKINNEDWND *pWnd, POINTS pts) +{ + if (0 != pWnd->embedData.reparenting) + return; + + SNDMSG(pWnd->hwnd, WM_SYSCOMMAND, SC_CLOSE, *(LPARAM*)&pts); +} + +static void SkinnedWindow_OnWindowPosChanging(SKINNEDWND *pWnd, WINDOWPOS *pwp) +{ + if (SWP_NOSIZE != ((SWP_NOSIZE | SWP_FRAMECHANGED) & pwp->flags)) + { + if (!config_embedwnd_freesize && + 0 == (WS_CHILD & GetWindowLongPtrW(pWnd->hwnd, GWL_STYLE))) + { + pwp->cx += (RESIZESTEP_CX - 1); + pwp->cx -= pwp->cx % RESIZESTEP_CX; + pwp->cy += (RESIZESTEP_CY - 1); + pwp->cy -= pwp->cy % RESIZESTEP_CY; + } + if (pwp->cx < RESIZESTEP_CX*2) pwp->cx = RESIZESTEP_CX*2; + if (pwp->cy < RESIZESTEP_CY*2) pwp->cy = RESIZESTEP_CY*2; + } + CallWndProc(pWnd, WM_WINDOWPOSCHANGING, 0, (LPARAM)pwp); +} + +static void SkinnedWindow_OnWindowPosChanged(SKINNEDWND *pWnd, WINDOWPOS *pwp) +{ + if ((SWP_NOSIZE | SWP_NOMOVE) != ((SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED) & pwp->flags)) + { + SetRect(&pWnd->embedData.r, pwp->x, pwp->y, pwp->x + pwp->cx, pwp->y + pwp->cy); + } + + CallWndProc(pWnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)pwp); +} + +static void SkinnedWindow_OnMoving(SKINNEDWND *pWnd, RECT *prc) +{ + if (0 == (SWS_EX_NOSNAP & pWnd->flags) && + (0xFFFF != pWnd->movingOffset.x && 0xFFFF != pWnd->movingOffset.y) && + (!!config_snap + (0 != (0x8000 & GetAsyncKeyState(VK_SHIFT))) == 1)) + { + POINT pt; + GetCursorPos(&pt); + INT cx = prc->right - prc->left; + INT cy = prc->bottom - prc->top; + prc->left = pt.x - pWnd->movingOffset.x; + prc->top = pt.y - pWnd->movingOffset.y; + prc->right = prc->left + cx; + prc->bottom = prc->top + cy; + SnapWindowToAllWindows(prc, pWnd->hwnd); + } +} + +static void SkinnedWindow_OnSizing(SKINNEDWND *pWnd, UINT edge, RECT *prc) +{ + LONG cx, cy; + cx = prc->right - prc->left; + cy = prc->bottom - prc->top; + + if (!config_embedwnd_freesize && + 0 == (0x8000 & GetAsyncKeyState(VK_SHIFT))) + { + cx += (RESIZESTEP_CX - 1); + cx -= cx % RESIZESTEP_CX; + cy += (RESIZESTEP_CY - 1); + cy -= cy % RESIZESTEP_CY; + } + + if (cx < RESIZESTEP_CX*2) cx = RESIZESTEP_CX*2; + if (cy < RESIZESTEP_CY*2) cy = RESIZESTEP_CY*2; + prc->right = prc->left + cx; + prc->bottom = prc->top + cy; +} + +static void SkinnedWindow_OnEnterSizeMove(SKINNEDWND *pWnd) +{ + POINT pt; + RECT rw; + GetCursorPos(&pt); + GetWindowRect(pWnd->hwnd, &rw); + if (0xFFFF == pWnd->movingOffset.x) + pWnd->movingOffset.x = pt.x - rw.left; + if (0xFFFF == pWnd->movingOffset.y) + pWnd->movingOffset.y = pt.y - rw.top; +} + +static void SkinnedWindow_OnExitSizeMove(SKINNEDWND *pWnd) +{ + pWnd->movingOffset.x = 0xFFFF; + pWnd->movingOffset.y = 0xFFFF; +} + +static void SkinnedWindow_PatchCursor(SKINNEDWND *pWnd) +{ + RECT rc; + POINT ptOrig, pt; + + if (!GetCursorPos(&ptOrig) || + !GetWindowRect(pWnd->hwnd, &rc)) + return; + + pt.x = rc.right + 1; + pt.y = ptOrig.y; + + ShowCursor(FALSE); + SetCursorPos(pt.x, pt.y); + ShowCursor(TRUE); + SetCursorPos(ptOrig.x, ptOrig.y); +} + +static void SkinnedWindow_OnEnterMenuLoop(SKINNEDWND *pWnd, BOOL bTrackPopup) +{ + PostMessageW(pWnd->hwnd, WM_SETCURSOR, (WPARAM)pWnd->hwnd, MAKELPARAM(HTCLIENT,WM_ENTERMENULOOP)); +} + +static void SkinnedWindow_OnExitMenuLoop(SKINNEDWND *pWnd, BOOL bShortcut) +{ +} + +static void SkinnedWindow_OnUnskin(SKINNEDWND *pWnd) +{ + if (NULL == pWnd) return; + + HWND hwnd = pWnd->hwnd; + + BOOL restoreVisible = FALSE; + DWORD windowStyle = GetWindowLongPtrW(hwnd, GWL_STYLE); + if (0 != (WS_VISIBLE & windowStyle)) + { + restoreVisible = TRUE; + SetWindowLongPtrW(hwnd, GWL_STYLE, windowStyle & ~WS_VISIBLE); + } + + if (NULL != pWnd->embedData.wasabi_window) + { + SENDWAIPC(IPC_CB_ONHIDEWND, pWnd->hwnd); + // start looping till we get callback + + MSG msg; + BOOL stopLoop = FALSE; + + while(FALSE == stopLoop) + { + DWORD status = MsgWaitForMultipleObjectsEx(0, NULL, INFINITE, QS_ALLINPUT, MWMO_ALERTABLE | MWMO_INPUTAVAILABLE); + if (WAIT_OBJECT_0 == status) + { + while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) + { + if (WAMSG_CLOSE == msg.message && msg.hwnd == pWnd->hwnd) + { + stopLoop = TRUE; + break; + } + else if (!CallMsgFilter(&msg, MSGF_DIALOGBOX)) + { + if (msg.message == WM_QUIT) + { + PostQuitMessage((INT)msg.wParam); + stopLoop = TRUE; + break; + } + else + { + TranslateMessage(&msg); + DispatchMessageW(&msg); + } + } + } + } + } + } + + SkinnedWindow_Delete(pWnd); + + if (FALSE != restoreVisible) + SetWindowLongPtrW(hwnd, GWL_STYLE, WS_VISIBLE | GetWindowLongPtrW(hwnd, GWL_STYLE)); +} + +static LRESULT SkinnedWindow_OnWinampIPC(SKINNEDWND *pWnd, UINT uCmd, WPARAM param) +{ + switch(uCmd) + { + case IPC_SKINWINDOW_SETEXSTYLE: + pWnd->flags = (SWS_EX_MASK & pWnd->flags) | (~SWS_EX_MASK & param); + return 0; + + case IPC_SKINWINDOW_GETEXSTYLE: + return (~SWS_EX_MASK & pWnd->flags); + + case IPC_SKINWINDOW_SETEMBEDFLAGS: + pWnd->embedData.flags = (INT)param; + return 0; + + case IPC_SKINWINDOW_GETEMBEDFLAGS: + return pWnd->embedData.flags; + + case IPC_SKINWINDOW_GETWASABIWND: + return (LRESULT)pWnd->embedData.wasabi_window; + + case IPC_SKINWINDOW_UNSKIN: + SkinnedWindow_OnUnskin(pWnd); + break; + + case IPC_SKINWINDOW_GETGUID: + if (NULL != param) + { + CopyMemory((void*)param, &pWnd->embedData.guid, sizeof(GUID)); + return TRUE; + } + break; + + case IPC_SKINWINDOW_GETEMBEDNUMS: + return Skin_UseGenNums; + } + return 0; +} + +static void SkinnedWindow_OnSysCommand(SKINNEDWND *pWnd, UINT uCmd, LPARAM param) +{ + CallWndProc(pWnd, WM_SYSCOMMAND, (WPARAM)uCmd, param); + + switch(uCmd) + { + case SC_MOVE: + case SC_SIZE: + case SC_DRAGMOVE: + case SC_DRAGSIZE_N: + case SC_DRAGSIZE_S: + case SC_DRAGSIZE_E: + case SC_DRAGSIZE_W: + case SC_DRAGSIZE_NW: + case SC_DRAGSIZE_NE: + case SC_DRAGSIZE_SW: + case SC_DRAGSIZE_SE: + SkinnedWindow_PatchCursor(pWnd); + break; + } +} + +static LRESULT SkinnedWindow_OnSetText(SKINNEDWND *pWnd, LPCWSTR pszText) +{ + LRESULT result = CallWndProc(pWnd, WM_SETTEXT, 0, (LPARAM)pszText); + ifc_window *wnd = pWnd->embedData.wasabi_window; + if (NULL != wnd) + { + ifc_window *parent = wnd->getRootParent(); + if (NULL == parent) parent = wnd; + parent->setWindowTitle(pszText); + } + else + { + SetWindowPos(pWnd->hwnd, NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED); + } + return result; +} + +static LRESULT CALLBACK SkinnedWnd_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + SKINNEDWND *pWnd = GetSkinnedWnd(hwnd); + if (NULL == pWnd) + { + return ((IsWindowUnicode(hwnd)) ? DefWindowProcW(hwnd, uMsg, wParam, lParam) : + DefWindowProcA(hwnd, uMsg, wParam, lParam)); + } + + switch(uMsg) + { + case WM_DESTROY: + { + BOOL unicode = IsUnicode(pWnd); + WNDPROC wndProc = pWnd->fnWndProc; + SkinnedWindow_Delete(pWnd); + return ((unicode) ? CallWindowProcW(wndProc, hwnd, uMsg, wParam, lParam) : + CallWindowProcA(wndProc, hwnd, uMsg, wParam, lParam)); + } + break; + + case WAMSG_CLOSE: SkinnedWindow_OnWinampCustomClose(pWnd, MAKEPOINTS(lParam)); return 0; + case WM_NCHITTEST: return SkinnedWindow_OnNcHitTest(pWnd, MAKEPOINTS(lParam)); + case WM_NCCALCSIZE: return SkinnedWindow_OnNcCalcSize(pWnd, (BOOL)wParam, (NCCALCSIZE_PARAMS*)lParam); + case WM_NCPAINT: SkinnedWindow_OnNcPaint(pWnd, (HRGN)wParam); return 0; + case WM_NCACTIVATE: return SkinnedWindow_OnNcActivate(pWnd, (BOOL)wParam); + case WM_ACTIVATE: SkinnedWindow_OnActivate(pWnd, LOWORD(wParam), HIWORD(wParam), (HWND)lParam); return 0; + case WM_PRINT: SkinnedWindow_OnPrint(pWnd, (HDC)wParam, (UINT)lParam); return 0; + case WM_SETCURSOR: return SkinnedWindow_OnSetCursor(pWnd, (HWND)wParam, LOWORD(lParam), HIWORD(lParam)); + case WM_NCLBUTTONDOWN: if (SkinnedWindow_OnNcLButtonDown(pWnd, (INT)wParam, MAKEPOINTS(lParam))) return 0; break; + case WM_NCLBUTTONUP: if (SkinnedWindow_OnNcLButtonUp(pWnd, (INT)wParam, MAKEPOINTS(lParam))) return 0; break; + case WM_NCRBUTTONDOWN: if (SkinnedWindow_OnNcRButtonDown(pWnd, (INT)wParam, MAKEPOINTS(lParam))) return 0; break; + case WM_NCRBUTTONUP: if (SkinnedWindow_OnNcRButtonUp(pWnd, (INT)wParam, MAKEPOINTS(lParam))) return 0; break; + case WM_NCMOUSEMOVE: SkinnedWindow_OnNcMouseMove(pWnd, (INT)wParam, MAKEPOINTS(lParam)); break; + case WM_NCMOUSELEAVE: SkinnedWindow_OnNcMouseLeave(pWnd); break; + case WM_SHOWWINDOW: if (SkinnedWindow_OnShowWindow(pWnd, (BOOL)wParam, (UINT)lParam)) return 0; break; + case WM_WINDOWPOSCHANGING: SkinnedWindow_OnWindowPosChanging(pWnd, (WINDOWPOS*)lParam); return 0; + case WM_WINDOWPOSCHANGED: SkinnedWindow_OnWindowPosChanged(pWnd, (WINDOWPOS*)lParam); return 0; + case WM_ENTERSIZEMOVE: SkinnedWindow_OnEnterSizeMove(pWnd); break; + case WM_EXITSIZEMOVE: SkinnedWindow_OnExitSizeMove(pWnd); break; + case WM_MOVING: SkinnedWindow_OnMoving(pWnd, (RECT*)lParam); break; + case WM_SIZING: SkinnedWindow_OnSizing(pWnd, (UINT)wParam, (RECT*)lParam); break; + case WM_ENTERMENULOOP: SkinnedWindow_OnEnterMenuLoop(pWnd, (BOOL)wParam); break; + case WM_EXITMENULOOP: SkinnedWindow_OnExitMenuLoop(pWnd, (BOOL)wParam); break; + case WM_NCUAHDRAWCAPTION: return 0; + case WM_NCUAHDRAWFRAME: return 0; + case WM_WA_IPC: return SkinnedWindow_OnWinampIPC(pWnd, (UINT)lParam, wParam); + case WM_SYSCOMMAND: SkinnedWindow_OnSysCommand(pWnd, (UINT)wParam, lParam); return 0; + case WM_SETTEXT: return SkinnedWindow_OnSetText(pWnd, (LPCWSTR)lParam); + } + + if (FALSE != IsDirectMouseWheelMessage(uMsg)) + { + if (0 == (WS_CHILD & GetWindowStyle(hwnd))) + return TRUE; + else + { + HWND hParent; + hParent = GetAncestor(hwnd, GA_PARENT); + if (NULL != hParent) + return SendMessageW(hwnd, uMsg, wParam, lParam); + + return FALSE; + } + } + + return CallWndProc(pWnd, uMsg, wParam, lParam); +}
\ No newline at end of file |