diff options
| author | Jonas Kümmerlin <jonas@kuemmerlin.eu> | 2020-06-12 17:05:26 +0200 |
|---|---|---|
| committer | Jonas Kümmerlin <jonas@kuemmerlin.eu> | 2020-06-12 17:05:26 +0200 |
| commit | 253b9857e7b4317275b50795ddc53508e1cbd181 (patch) | |
| tree | 8258de0a3f311ba621051f8130d115b61608d6e5 /alf/alficon.cpp | |
| parent | b7e4e6fb0bbfdd91f969be5011c0b76ef0ab2e2d (diff) | |
icon view and helper functions
initial implementation, needs more testing
Diffstat (limited to 'alf/alficon.cpp')
| -rw-r--r-- | alf/alficon.cpp | 206 |
1 files changed, 206 insertions, 0 deletions
diff --git a/alf/alficon.cpp b/alf/alficon.cpp new file mode 100644 index 0000000..eb83815 --- /dev/null +++ b/alf/alficon.cpp @@ -0,0 +1,206 @@ +#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); + + RECT rcClient; + GetClientRect(hwnd, &rcClient); + RECT rcPaint = { 0, 0, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top }; + + HDC hdcBuffer = NULL; + ALF_Compat_HPAINTBUFFER hpb = ALF_Compat_BeginBufferedPaint(hdc, &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; +} |
