summaryrefslogtreecommitdiff
path: root/alf/alfbutton.cpp
blob: 729e7ee787fbfa341523735970841dd5eee792d1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include "alfpriv.h"

/* BUTTON */
static LRESULT CALLBACK
ALF__ButtonSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
    (void)uIdSubclass;
    (void)dwRefData;

    ALFAPP app = (ALFAPP)dwRefData;

    if (uMsg == ALF_WM_QUERYSIZE) {
        HDC hdc = GetDC(hwnd);
        HFONT font = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0);
        HFONT oldFont = 0;
        if (font)
            oldFont = SelectFont(hdc, font);

        // calc drawtext style
        DWORD style = GetWindowLong(hwnd, GWL_STYLE);
        UINT format = DT_LEFT | DT_EXPANDTABS | DT_CALCRECT;
        if ((style & BS_MULTILINE) == 0)
            format |= DT_SINGLELINE;

        RECT r = { 0, 0, 0x7FFFFFFF, 100 };

        int textlen = GetWindowTextLength(hwnd);
        TCHAR *textbuf = (TCHAR*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY|HEAP_GENERATE_EXCEPTIONS, (textlen + 1)*sizeof(TCHAR));
        GetWindowText(hwnd, textbuf, textlen+1);

        DrawText(hdc, textbuf, -1, &r, format);

        HeapFree(GetProcessHeap(), 0, textbuf);

        int xpadding = app->compatFn->GetSystemMetricsForDpi(SM_CXEDGE,
            ALF_CentipointsToPixels(GetParent(hwnd), 7200)) * 2 + 6;
        int ypadding = app->compatFn->GetSystemMetricsForDpi(SM_CYEDGE,
            ALF_CentipointsToPixels(GetParent(hwnd), 7200)) * 2 + 6;

        SIZE *pSize = (SIZE*)(void*)lParam;
        if (pSize->cx < r.right - r.left + xpadding) {
            pSize->cx = r.right - r.left + xpadding;
        }
        if (pSize->cy < r.bottom - r.top + ypadding) {
            pSize->cy = r.bottom - r.top + ypadding;
        }
        if (pSize->cx < pSize->cy) {
            pSize->cx = pSize->cy;
        }

        if (font)
            SelectFont(hdc, oldFont);

        ReleaseDC(hwnd, hdc);
    } else if (uMsg == ALF_WM_APPLYSIZE) {
        // HACK: a themed button contains a 1px margin. An unthemed button
        // does not, so we add one.

        RECT *p = (RECT *)lParam;

        int padding = app->compatFn->IsAppThemed() ? 0 : 1;

        return (LRESULT)DeferWindowPos((HDWP)wParam,
                                       hwnd, NULL,
                                       p->left, p->top + padding,
                                       p->right - p->left, p->bottom - p->top - 2*padding,
                                       SWP_NOZORDER|SWP_NOACTIVATE);
    } else if (uMsg == WM_DESTROY) {
        app->compatFn->RemoveWindowSubclass(hwnd, ALF__ButtonSubclassProc, 0);
    }

    return app->compatFn->DefSubclassProc(hwnd, uMsg, wParam, lParam);
}

HWND
ALF_AddButton(HWND win, WORD id, UINT x, UINT y, const TCHAR *text)
{
    HWND hwndButton  = CreateWindowEx(0,
                                      TEXT("BUTTON"),
                                      text,
                                      WS_CHILD | WS_TABSTOP | WS_VISIBLE | BS_PUSHBUTTON | BS_MULTILINE,
                                      0, 0, 100, 100,
                                      win,
                                      (HMENU)(int)id,
                                      (HINSTANCE)GetWindowLongPtr(win, GWLP_HINSTANCE),
                                      NULL);

    ALFAPP app = ALF_ApplicationFromWindow(win);

    app->compatFn->SetWindowSubclass(hwndButton, ALF__ButtonSubclassProc, 0, (DWORD_PTR)app);
    SetWindowPos(hwndButton, NULL, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED);

    ALFAddWidgetParams p;
    ZeroMemory(&p, sizeof(p));
    p.hwnd = hwndButton;
    p.x = x;
    p.y = y;
    p.width = 0;
    p.height = 0;
    p.flags = ALF_QUERYSIZE | ALF_MESSAGEFONT | ALF_APPLYSIZE;

    ALF_AddWidgetEx(win, &p);

    return hwndButton;
}


void
ALF_SetDefaultButton(HWND win, WORD id)
{
    SendMessage(win, DM_SETDEFID, (WPARAM)id, 0);
}