summaryrefslogtreecommitdiff
path: root/alf/alficon.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'alf/alficon.cpp')
-rw-r--r--alf/alficon.cpp206
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;
+}