#include "alfpriv.h" /* ICONS */ typedef struct { ALFColor bgcolor; HICON icon; SIZE iconsize; } ALFIconViewPriv; static void ALF_IconView_Paint(HWND hwnd, ALFIconViewPriv *priv, HDC hdc, RECT *r) { if (priv->bgcolor == ALF_COLOR_TRANSPARENT) { ALF_Compat_DrawThemeParentBackground(hwnd, hdc, r); SetBkMode(hdc, TRANSPARENT); } else { ALF_FillRect(hdc, r, priv->bgcolor); SetBkMode(hdc, OPAQUE); SetBkColor(hdc, ALF_ColorToGdi(priv->bgcolor)); } if (priv->icon) { RECT rcClient; GetClientRect(hwnd, &rcClient); int iconx = (rcClient.right - rcClient.left - priv->iconsize.cx) / 2; int icony = (rcClient.bottom - rcClient.top - priv->iconsize.cy) / 2; DrawIconEx(hdc, iconx, icony, priv->icon, 0, 0, 0, NULL, DI_NORMAL); } } static LRESULT CALLBACK ALF_IconView_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { ALFIconViewPriv *priv = (ALFIconViewPriv*)GetWindowLongPtr(hwnd, 0); if (uMsg == WM_CREATE && !priv) { priv = ALF_New(ALFIconViewPriv, 1); priv->bgcolor = ALF_COLOR_SYS(COLOR_BTNFACE); SetWindowLongPtr(hwnd, 0, (LONG_PTR)priv); } if (!priv) return DefWindowProc(hwnd, uMsg, wParam, lParam); if (uMsg == WM_GETDLGCODE) { return DLGC_STATIC; } else if (uMsg == WM_PAINT) { PAINTSTRUCT ps; HDC hdc = BeginPaint(hwnd, &ps); HDC hdcBuffer = NULL; ALF_Compat_HPAINTBUFFER hpb = ALF_Compat_BeginBufferedPaint(hdc, &ps.rcPaint, 0, NULL, &hdcBuffer); if (hpb) { ALF_IconView_Paint(hwnd, priv, hdcBuffer, &ps.rcPaint); ALF_Compat_EndBufferedPaint(hpb, TRUE); } else { ALF_IconView_Paint(hwnd, priv, hdc, &ps.rcPaint); } EndPaint(hwnd, &ps); return TRUE; } else if (uMsg == WM_PRINTCLIENT) { RECT rcClient; GetClientRect(hwnd, &rcClient); RECT rcPaint = { 0, 0, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top }; ALF_IconView_Paint(hwnd, priv, (HDC)wParam, &rcPaint); } else if (uMsg == WM_NCHITTEST) { return HTTRANSPARENT; } else if (uMsg == ALF_WM_QUERYSIZE) { *(SIZE*)lParam = priv->iconsize; return TRUE; } else if (uMsg == WM_WINDOWPOSCHANGED) { WINDOWPOS *p = (WINDOWPOS *)lParam; if (!(p->flags & SWP_NOSIZE)) { InvalidateRect(hwnd, NULL, TRUE); } } else if (uMsg == ALF_WM_BACKGROUNDCHANGE) { if (priv->bgcolor == ALF_COLOR_TRANSPARENT) { InvalidateRect(hwnd, NULL, TRUE); } return TRUE; } else if (uMsg == ALF_WM_SETBGCOLOR) { ALFColor newcolor = (ALFColor)lParam; if (priv->bgcolor == newcolor) return TRUE; priv->bgcolor = newcolor; InvalidateRect(hwnd, NULL, TRUE); return TRUE; } else if (uMsg == ALF_WM_GETBGCOLOR) { return (LRESULT)priv->bgcolor; } else if (uMsg == ALF_WM_ICONVIEW_GETICON) { return (LRESULT)priv->icon; } else if (uMsg == ALF_WM_ICONVIEW_SETICON) { HICON old = priv->icon; SIZE oldsize = priv->iconsize; priv->icon = (HICON)lParam; priv->iconsize = ALF_IconSize(priv->icon); InvalidateRect(hwnd, NULL, TRUE); if (priv->iconsize.cx != oldsize.cx || priv->iconsize.cy != oldsize.cy) { ALF_InvalidateLayout(GetParent(hwnd)); } return (LRESULT)old; } else if (uMsg == WM_DESTROY) { ALF_Free(priv); SetWindowLongPtr(hwnd, 0, 0); } return DefWindowProc(hwnd, uMsg, wParam, lParam); } HWND ALF_AddIconView(HWND win, WORD id, int x, int y, HICON icon) { HWND hwndIV = ALF_CreateControlWindow( 0, TEXT(""), WS_CHILD | WS_VISIBLE, 0, 0, 100, 100, win, (HMENU)(ULONG_PTR)id, ALF_IconView_WindowProc, NULL); ALF_AddControl(win, x, y, hwndIV, 0, 0, ALF_LAYOUT_SIZE_QUERY | ALF_LAYOUT_INHERITBGCOLOR | ALF_LAYOUT_SENDBGCHANGE); ALF_IconView_SetIcon(hwndIV, icon); return hwndIV; } HICON ALF_IconView_Icon(HWND control) { return (HICON)SendMessage(control, ALF_WM_ICONVIEW_GETICON, 0, 0); } HICON ALF_IconView_SetIcon(HWND control, HICON icon) { return (HICON)SendMessage(control, ALF_WM_ICONVIEW_SETICON, 0, (LPARAM)icon); } HICON ALF_LoadIcon(HINSTANCE hinst, const TCHAR *name, int cx, int cy) { HICON hi; #ifdef UNICODE const WCHAR *namew = name; #else WCHAR namebuf[MAX_PATH] = {0}; const WCHAR *namew; if (IS_INTRESOURCE(name)) { namew = (WCHAR *)name; } else { MultiByteToWideChar(CP_ACP, 0, name, -1, namebuf, sizeof(namebuf)/sizeof(namebuf[0])-1); namew = namebuf; } #endif if (SUCCEEDED(ALF_Compat_LoadIconWithScaleDown(hinst, namew, cx, cy, &hi))) { return hi; } else { if (hinst == NULL) { if (IS_INTRESOURCE(name)) { // standard icon return CopyIcon(LoadIcon(hinst, name)); } else { // .ico file return (HICON)LoadImage(hinst, name, IMAGE_ICON, cx, cy, LR_LOADFROMFILE); } } else { return (HICON)LoadImage(hinst, name, IMAGE_ICON, cx, cy, 0); } } } SIZE ALF_IconSize(HICON icon) { ICONINFO ii; SIZE s = { 0, 0 }; if (GetIconInfo(icon, &ii)) { BITMAP bm; if (GetObject(ii.hbmMask, sizeof(bm), &bm) == sizeof(bm)) { s.cx = bm.bmWidth; s.cy = ii.hbmColor ? bm.bmHeight : bm.bmHeight / 2; } if (ii.hbmMask) DeleteObject(ii.hbmMask); if (ii.hbmColor) DeleteObject(ii.hbmColor); } return s; }