summaryrefslogtreecommitdiff
path: root/alf
diff options
context:
space:
mode:
authorJonas Kümmerlin <jonas@kuemmerlin.eu>2018-12-27 20:50:39 +0100
committerJonas Kümmerlin <jonas@kuemmerlin.eu>2018-12-27 20:50:39 +0100
commitb0b0e97aa5a06b22768bb9c9ea5e8caf383d78a4 (patch)
tree8432ca1d8bf811bc7de6240e5988fb84e35b1f40 /alf
parent64b6b40ace30693f0e12d56799abc40c997df07c (diff)
split into multiple files
Diffstat (limited to 'alf')
-rw-r--r--alf/alf.cpp376
-rw-r--r--alf/alfbutton.cpp95
-rw-r--r--alf/alfcompat.cpp23
-rw-r--r--alf/alfedit.cpp76
-rw-r--r--alf/alflabel.cpp83
-rw-r--r--alf/alflist.h50
-rw-r--r--alf/alfpriv.h67
7 files changed, 396 insertions, 374 deletions
diff --git a/alf/alf.cpp b/alf/alf.cpp
index f4117e7..3bcde5b 100644
--- a/alf/alf.cpp
+++ b/alf/alf.cpp
@@ -1,112 +1,4 @@
-#include "alf.h"
-
-#include <windows.h>
-#include <commctrl.h>
-#include <windowsx.h>
-#include <stdio.h>
-#include <stddef.h>
-
-#ifdef _MSC_VER
-// MSVC6 for scoping hack
-# define for if(0){}else for
-#endif
-
-typedef struct ALFListHeader {
- struct ALFListHeader *prev;
- struct ALFListHeader *next;
-} ALFListHeader;
-
-#define ALF_LIST_CONTAINER(ContainerType, containermember, listp) \
- ((ContainerType *)((char *)(listp) - offsetof(ContainerType, containermember)))
-
-#define ALF_FOR_LIST(ContainerType, containermember, listp, iteratorvar) \
- for (ALFListHeader *alf_list_##iteratorvar##_curr = (listp)->next, \
- *alf_list_##iteratorvar##_next = alf_list_##iteratorvar##_curr->next; \
- alf_list_##iteratorvar##_curr != (listp); \
- alf_list_##iteratorvar##_curr = alf_list_##iteratorvar##_next, \
- alf_list_##iteratorvar##_next = alf_list_##iteratorvar##_next->next) \
- for (ContainerType *iteratorvar = (ContainerType *)((char *)alf_list_##iteratorvar##_curr - offsetof(ContainerType, containermember)); \
- iteratorvar; iteratorvar = NULL) \
-
-
-static inline BOOL
-ALF_ListIsEmpty(ALFListHeader *list)
-{
- return list->next == list;
-}
-
-static inline void
-ALF_ListInsert(ALFListHeader *list, ALFListHeader *newel)
-{
- newel->prev = list;
- newel->next = list->next;
- newel->next->prev = newel;
- list->next = newel;
-}
-
-static inline void
-ALF_ListRemove(ALFListHeader *member)
-{
- member->prev->next = member->next;
- member->next->prev = member->prev;
- member->next = NULL;
- member->prev = NULL;
-}
-
-static inline void
-ALF_ListInit(ALFListHeader *list)
-{
- list->next = list->prev = list;
-}
-
-typedef struct {
- ALFListHeader list;
- HWND hwnd;
- UINT x;
- UINT y;
- UINT cptWidth;
- UINT cptHeight;
- UINT cptMarginTop;
- UINT cptMarginRight;
- UINT cptMarginBottom;
- UINT cptMarginLeft;
- DWORD flags;
-} ALFWidgetPriv;
-
-typedef struct {
- int minWidth;
- int allocatedWidth;
- int allocatedPosition;
- int expand : 1;
-} ALFRowOrColumn;
-
-typedef struct {
- ALFRowOrColumn *columns;
- ALFRowOrColumn *rows;
- int nColumns;
- int nRows;
- int totalMinWidth;
- int totalMinHeight;
- int occupiedColumnCount;
- int occupiedRowCount;
-} ALFLayout;
-
-typedef struct {
- ALFAPP app;
- ALFWindowVTable *vtbl;
- void *closure;
- ALFWindowFonts fonts;
- ALFListHeader widgets;
- int modalResult;
- ALFLayout layout;
- WORD defid;
- HWND hwndFocus;
-} ALFWindowPriv;
-
-struct ALFAppPriv {
- HINSTANCE hInstance;
- ALFCompatFunctions *compatFn;
-};
+#include "alfpriv.h"
/* ALF App and Window */
@@ -600,23 +492,7 @@ ALF_CreateApplication(HINSTANCE hInstance)
InitCommonControlsEx(&icc);
- ALFCompatFunctions *compatfn = (ALFCompatFunctions*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY|HEAP_GENERATE_EXCEPTIONS, sizeof(ALFCompatFunctions));
-
-#define COMPAT(dll, entrypoint, ordinal) \
- do { \
- FARPROC p = GetProcAddress(GetModuleHandleA(#dll), #entrypoint); \
- if (!p && ordinal) \
- p = GetProcAddress(GetModuleHandleA(#dll), (char*)ordinal); \
- CopyMemory(&compatfn->entrypoint, &p, sizeof(void*)); \
- } while (0)
-
- COMPAT(comctl32.dll, SetWindowSubclass, 410);
- COMPAT(comctl32.dll, DefSubclassProc, 413);
- COMPAT(comctl32.dll, RemoveWindowSubclass, 412);
-
-#undef COMPAT
-
- app->compatFn = compatfn;
+ app->compatFn = ALF_CreateCompatFuncTable();
return app;
}
@@ -767,251 +643,3 @@ ALF_WidgetHwndById(HWND win, WORD id)
return closure.result;
}
-/* LABEL */
-
-static LRESULT CALLBACK
-ALF__LabelSubclassProc(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 hdcLabel = GetDC(hwnd);
- HFONT font = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0);
- HFONT oldFont = 0;
- if (font)
- oldFont = SelectFont(hdcLabel, font);
-
- // calc drawtext style
- DWORD style = GetWindowLong(hwnd, GWL_STYLE);
- UINT format = DT_LEFT | DT_EXPANDTABS | DT_CALCRECT;
- if (style & SS_NOPREFIX)
- format |= DT_NOPREFIX;
- if (style & SS_EDITCONTROL)
- format |= DT_EDITCONTROL;
- if (style & SS_ENDELLIPSIS || style & SS_PATHELLIPSIS || style & SS_WORDELLIPSIS)
- format |= DT_SINGLELINE;
-
- RECT r = { 0, 0, 100, 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(hdcLabel, textbuf, -1, &r, format);
-
- HeapFree(GetProcessHeap(), 0, textbuf);
-
- SIZE *pSize = (SIZE*)(void*)lParam;
- if (pSize->cx == 0)
- pSize->cx = r.right - r.left;
- if (pSize->cy == 0)
- pSize->cy = r.bottom - r.top;
-
- if (font)
- SelectFont(hdcLabel, oldFont);
-
- ReleaseDC(hwnd, hdcLabel);
- }
-
- return app->compatFn->DefSubclassProc(hwnd, uMsg, wParam, lParam);
-}
-
-HWND
-ALF_AddLabel(HWND win, WORD id, UINT x, UINT y, const WCHAR *text)
-{
- HWND hwndLabel = CreateWindow(L"STATIC",
- text,
- WS_CHILD | WS_VISIBLE | SS_LEFTNOWORDWRAP,
- 0, 0, 100, 100,
- win,
- (HMENU)(int)id,
- (HINSTANCE)GetWindowLongPtr(win, GWLP_HINSTANCE),
- NULL);
-
- ALFAPP app = ALF_ApplicationFromWindow(win);
- app->compatFn->SetWindowSubclass(hwndLabel, ALF__LabelSubclassProc, 0, (DWORD_PTR)app);
-
- ALFAddWidgetParams p;
- ZeroMemory(&p, sizeof(p));
- p.hwnd = hwndLabel;
- p.x = x;
- p.y = y;
- p.width = 0;
- p.height = 0;
- p.flags = ALF_QUERYSIZE | ALF_MESSAGEFONT;
- p.margins[0] = 300; // TODO: pixel perfect margins from system metrics
-
- ALF_AddWidgetEx(win, &p);
-
- return hwndLabel;
-}
-
-/* EDIT */
-static LRESULT CALLBACK
-ALF__EditSubclassProc(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);
-
- if (font) {
- HFONT oldfont = SelectFont(hDc, font);
-
- TEXTMETRIC tm;
- ZeroMemory(&tm, sizeof(tm));
-
- if (GetTextMetrics(hDc, &tm)) {
- SIZE *ps = (SIZE*)lParam;
- if (!ps->cx) {
- ps->cx = ALF_CentipointsToPixels(GetParent(hwnd), 12000);
- }
-
- if (!ps->cy) {
- ps->cy = tm.tmHeight + 6; // FIXME! use system metrics
- }
- }
-
- SelectFont(hDc, oldfont);
- }
-
- ReleaseDC(hwnd, hDc);
- return 0;
- }
-
- return app->compatFn->DefSubclassProc(hwnd, uMsg, wParam, lParam);
-}
-
-HWND
-ALF_AddEdit(HWND win, WORD id, UINT x, UINT y, const WCHAR *text)
-{
- HWND hwndEdit = CreateWindowEx(WS_EX_CLIENTEDGE,
- L"EDIT",
- text,
- WS_CHILD | WS_VISIBLE | WS_TABSTOP,
- 0, 0, 100, 100,
- win,
- (HMENU)(int)id,
- (HINSTANCE)GetWindowLongPtr(win, GWLP_HINSTANCE),
- NULL);
-
- ALFAPP app = ALF_ApplicationFromWindow(win);
-
- app->compatFn->SetWindowSubclass(hwndEdit, ALF__EditSubclassProc, 0, (DWORD_PTR)app);
- SetWindowPos(hwndEdit, NULL, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED);
-
- ALFAddWidgetParams p;
- ZeroMemory(&p, sizeof(p));
- p.hwnd = hwndEdit;
- p.x = x;
- p.y = y;
- p.width = 0;
- p.height = 0;
- p.flags = ALF_QUERYSIZE | ALF_MESSAGEFONT;
- p.margins[0] = 75; // TODO: pixel-perfect margin from system metrics
- p.margins[2] = 75;
-
- ALF_AddWidgetEx(win, &p);
-
- return hwndEdit;
-}
-
-/* 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, 100, 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);
-
- // TODO: calculate from system metrics
- int padding = ALF_CentipointsToPixels(GetParent(hwnd), 525);
-
- SIZE *pSize = (SIZE*)(void*)lParam;
- if (pSize->cx < r.right - r.left + padding) {
- pSize->cx = r.right - r.left + padding;
- }
- if (pSize->cy < r.bottom - r.top + padding) {
- pSize->cy = r.bottom - r.top + padding;
- }
- if (pSize->cx < pSize->cy) {
- pSize->cx = pSize->cy;
- }
-
- if (font)
- SelectFont(hdc, oldFont);
-
- ReleaseDC(hwnd, hdc);
- }
-
- return app->compatFn->DefSubclassProc(hwnd, uMsg, wParam, lParam);
-}
-
-HWND
-ALF_AddButton(HWND win, WORD id, UINT x, UINT y, const WCHAR *text)
-{
- HWND hwndButton = CreateWindowEx(0,
- L"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);
-
- ALFAddWidgetParams p;
- ZeroMemory(&p, sizeof(p));
- p.hwnd = hwndButton;
- p.x = x;
- p.y = y;
- p.width = 5625;
- p.height = 0;
- p.flags = ALF_QUERYSIZE | ALF_MESSAGEFONT;
-
- ALF_AddWidgetEx(win, &p);
-
- return hwndButton;
-}
-
-
-void
-ALF_SetDefaultButton(HWND win, WORD id)
-{
- SendMessage(win, DM_SETDEFID, (WPARAM)id, 0);
-}
diff --git a/alf/alfbutton.cpp b/alf/alfbutton.cpp
new file mode 100644
index 0000000..079da75
--- /dev/null
+++ b/alf/alfbutton.cpp
@@ -0,0 +1,95 @@
+#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, 100, 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);
+
+ // TODO: calculate from system metrics
+ int padding = ALF_CentipointsToPixels(GetParent(hwnd), 525);
+
+ SIZE *pSize = (SIZE*)(void*)lParam;
+ if (pSize->cx < r.right - r.left + padding) {
+ pSize->cx = r.right - r.left + padding;
+ }
+ if (pSize->cy < r.bottom - r.top + padding) {
+ pSize->cy = r.bottom - r.top + padding;
+ }
+ if (pSize->cx < pSize->cy) {
+ pSize->cx = pSize->cy;
+ }
+
+ if (font)
+ SelectFont(hdc, oldFont);
+
+ ReleaseDC(hwnd, hdc);
+ }
+
+ return app->compatFn->DefSubclassProc(hwnd, uMsg, wParam, lParam);
+}
+
+HWND
+ALF_AddButton(HWND win, WORD id, UINT x, UINT y, const WCHAR *text)
+{
+ HWND hwndButton = CreateWindowEx(0,
+ L"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);
+
+ ALFAddWidgetParams p;
+ ZeroMemory(&p, sizeof(p));
+ p.hwnd = hwndButton;
+ p.x = x;
+ p.y = y;
+ p.width = 5625;
+ p.height = 0;
+ p.flags = ALF_QUERYSIZE | ALF_MESSAGEFONT;
+
+ ALF_AddWidgetEx(win, &p);
+
+ return hwndButton;
+}
+
+
+void
+ALF_SetDefaultButton(HWND win, WORD id)
+{
+ SendMessage(win, DM_SETDEFID, (WPARAM)id, 0);
+}
+
diff --git a/alf/alfcompat.cpp b/alf/alfcompat.cpp
new file mode 100644
index 0000000..452b9bc
--- /dev/null
+++ b/alf/alfcompat.cpp
@@ -0,0 +1,23 @@
+#include "alfpriv.h"
+
+ALFCompatFunctions *
+ALF_CreateCompatFuncTable(void)
+{
+ ALFCompatFunctions *compatfn = (ALFCompatFunctions*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY|HEAP_GENERATE_EXCEPTIONS, sizeof(ALFCompatFunctions));
+
+#define COMPAT(dll, entrypoint, ordinal) \
+ do { \
+ FARPROC p = GetProcAddress(GetModuleHandleA(#dll), #entrypoint); \
+ if (!p && ordinal) \
+ p = GetProcAddress(GetModuleHandleA(#dll), (char*)ordinal); \
+ CopyMemory(&compatfn->entrypoint, &p, sizeof(void*)); \
+ } while (0)
+
+ COMPAT(comctl32.dll, SetWindowSubclass, 410);
+ COMPAT(comctl32.dll, DefSubclassProc, 413);
+ COMPAT(comctl32.dll, RemoveWindowSubclass, 412);
+
+#undef COMPAT
+
+ return compatfn;
+}
diff --git a/alf/alfedit.cpp b/alf/alfedit.cpp
new file mode 100644
index 0000000..65f14c8
--- /dev/null
+++ b/alf/alfedit.cpp
@@ -0,0 +1,76 @@
+#include "alfpriv.h"
+
+/* EDIT */
+static LRESULT CALLBACK
+ALF__EditSubclassProc(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);
+
+ if (font) {
+ HFONT oldfont = SelectFont(hDc, font);
+
+ TEXTMETRIC tm;
+ ZeroMemory(&tm, sizeof(tm));
+
+ if (GetTextMetrics(hDc, &tm)) {
+ SIZE *ps = (SIZE*)lParam;
+ if (!ps->cx) {
+ ps->cx = ALF_CentipointsToPixels(GetParent(hwnd), 12000);
+ }
+
+ if (!ps->cy) {
+ ps->cy = tm.tmHeight + 6; // FIXME! use system metrics
+ }
+ }
+
+ SelectFont(hDc, oldfont);
+ }
+
+ ReleaseDC(hwnd, hDc);
+ return 0;
+ }
+
+ return app->compatFn->DefSubclassProc(hwnd, uMsg, wParam, lParam);
+}
+
+HWND
+ALF_AddEdit(HWND win, WORD id, UINT x, UINT y, const WCHAR *text)
+{
+ HWND hwndEdit = CreateWindowEx(WS_EX_CLIENTEDGE,
+ L"EDIT",
+ text,
+ WS_CHILD | WS_VISIBLE | WS_TABSTOP,
+ 0, 0, 100, 100,
+ win,
+ (HMENU)(int)id,
+ (HINSTANCE)GetWindowLongPtr(win, GWLP_HINSTANCE),
+ NULL);
+
+ ALFAPP app = ALF_ApplicationFromWindow(win);
+
+ app->compatFn->SetWindowSubclass(hwndEdit, ALF__EditSubclassProc, 0, (DWORD_PTR)app);
+ SetWindowPos(hwndEdit, NULL, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED);
+
+ ALFAddWidgetParams p;
+ ZeroMemory(&p, sizeof(p));
+ p.hwnd = hwndEdit;
+ p.x = x;
+ p.y = y;
+ p.width = 0;
+ p.height = 0;
+ p.flags = ALF_QUERYSIZE | ALF_MESSAGEFONT;
+ p.margins[0] = 75; // TODO: pixel-perfect margin from system metrics
+ p.margins[2] = 75;
+
+ ALF_AddWidgetEx(win, &p);
+
+ return hwndEdit;
+}
+
diff --git a/alf/alflabel.cpp b/alf/alflabel.cpp
new file mode 100644
index 0000000..e9ae550
--- /dev/null
+++ b/alf/alflabel.cpp
@@ -0,0 +1,83 @@
+#include "alfpriv.h"
+
+/* LABEL */
+
+static LRESULT CALLBACK
+ALF__LabelSubclassProc(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 hdcLabel = GetDC(hwnd);
+ HFONT font = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0);
+ HFONT oldFont = 0;
+ if (font)
+ oldFont = SelectFont(hdcLabel, font);
+
+ // calc drawtext style
+ DWORD style = GetWindowLong(hwnd, GWL_STYLE);
+ UINT format = DT_LEFT | DT_EXPANDTABS | DT_CALCRECT;
+ if (style & SS_NOPREFIX)
+ format |= DT_NOPREFIX;
+ if (style & SS_EDITCONTROL)
+ format |= DT_EDITCONTROL;
+ if (style & SS_ENDELLIPSIS || style & SS_PATHELLIPSIS || style & SS_WORDELLIPSIS)
+ format |= DT_SINGLELINE;
+
+ RECT r = { 0, 0, 100, 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(hdcLabel, textbuf, -1, &r, format);
+
+ HeapFree(GetProcessHeap(), 0, textbuf);
+
+ SIZE *pSize = (SIZE*)(void*)lParam;
+ if (pSize->cx == 0)
+ pSize->cx = r.right - r.left;
+ if (pSize->cy == 0)
+ pSize->cy = r.bottom - r.top;
+
+ if (font)
+ SelectFont(hdcLabel, oldFont);
+
+ ReleaseDC(hwnd, hdcLabel);
+ }
+
+ return app->compatFn->DefSubclassProc(hwnd, uMsg, wParam, lParam);
+}
+
+HWND
+ALF_AddLabel(HWND win, WORD id, UINT x, UINT y, const WCHAR *text)
+{
+ HWND hwndLabel = CreateWindow(L"STATIC",
+ text,
+ WS_CHILD | WS_VISIBLE | SS_LEFTNOWORDWRAP,
+ 0, 0, 100, 100,
+ win,
+ (HMENU)(int)id,
+ (HINSTANCE)GetWindowLongPtr(win, GWLP_HINSTANCE),
+ NULL);
+
+ ALFAPP app = ALF_ApplicationFromWindow(win);
+ app->compatFn->SetWindowSubclass(hwndLabel, ALF__LabelSubclassProc, 0, (DWORD_PTR)app);
+
+ ALFAddWidgetParams p;
+ ZeroMemory(&p, sizeof(p));
+ p.hwnd = hwndLabel;
+ p.x = x;
+ p.y = y;
+ p.width = 0;
+ p.height = 0;
+ p.flags = ALF_QUERYSIZE | ALF_MESSAGEFONT;
+ p.margins[0] = 300; // TODO: pixel perfect margins from system metrics
+
+ ALF_AddWidgetEx(win, &p);
+
+ return hwndLabel;
+}
diff --git a/alf/alflist.h b/alf/alflist.h
new file mode 100644
index 0000000..e0de033
--- /dev/null
+++ b/alf/alflist.h
@@ -0,0 +1,50 @@
+
+typedef struct ALFListHeader {
+ struct ALFListHeader *prev;
+ struct ALFListHeader *next;
+} ALFListHeader;
+
+#define ALF_LIST_CONTAINER(ContainerType, containermember, listp) \
+ ((ContainerType *)((char *)(listp) - offsetof(ContainerType, containermember)))
+
+#define ALF_FOR_LIST(ContainerType, containermember, listp, iteratorvar) \
+ for (ALFListHeader *alf_list_##iteratorvar##_curr = (listp)->next, \
+ *alf_list_##iteratorvar##_next = alf_list_##iteratorvar##_curr->next; \
+ alf_list_##iteratorvar##_curr != (listp); \
+ alf_list_##iteratorvar##_curr = alf_list_##iteratorvar##_next, \
+ alf_list_##iteratorvar##_next = alf_list_##iteratorvar##_next->next) \
+ for (ContainerType *iteratorvar = (ContainerType *)((char *)alf_list_##iteratorvar##_curr - offsetof(ContainerType, containermember)); \
+ iteratorvar; iteratorvar = NULL) \
+
+
+static inline BOOL
+ALF_ListIsEmpty(ALFListHeader *list)
+{
+ return list->next == list;
+}
+
+static inline void
+ALF_ListInsert(ALFListHeader *list, ALFListHeader *newel)
+{
+ newel->prev = list;
+ newel->next = list->next;
+ newel->next->prev = newel;
+ list->next = newel;
+}
+
+static inline void
+ALF_ListRemove(ALFListHeader *member)
+{
+ member->prev->next = member->next;
+ member->next->prev = member->prev;
+ member->next = NULL;
+ member->prev = NULL;
+}
+
+static inline void
+ALF_ListInit(ALFListHeader *list)
+{
+ list->next = list->prev = list;
+}
+
+
diff --git a/alf/alfpriv.h b/alf/alfpriv.h
new file mode 100644
index 0000000..08f3832
--- /dev/null
+++ b/alf/alfpriv.h
@@ -0,0 +1,67 @@
+#include "alf.h"
+
+#include <windows.h>
+#include <commctrl.h>
+#include <windowsx.h>
+#include <stdio.h>
+#include <stddef.h>
+
+#ifdef _MSC_VER
+// MSVC6 for scoping hack
+# define for if(0){}else for
+#endif
+
+#include "alflist.h"
+
+typedef struct {
+ ALFListHeader list;
+ HWND hwnd;
+ UINT x;
+ UINT y;
+ UINT cptWidth;
+ UINT cptHeight;
+ UINT cptMarginTop;
+ UINT cptMarginRight;
+ UINT cptMarginBottom;
+ UINT cptMarginLeft;
+ DWORD flags;
+} ALFWidgetPriv;
+
+typedef struct {
+ int minWidth;
+ int allocatedWidth;
+ int allocatedPosition;
+ int expand : 1;
+} ALFRowOrColumn;
+
+typedef struct {
+ ALFRowOrColumn *columns;
+ ALFRowOrColumn *rows;
+ int nColumns;
+ int nRows;
+ int totalMinWidth;
+ int totalMinHeight;
+ int occupiedColumnCount;
+ int occupiedRowCount;
+} ALFLayout;
+
+typedef struct {
+ ALFAPP app;
+ ALFWindowVTable *vtbl;
+ void *closure;
+ ALFWindowFonts fonts;
+ ALFListHeader widgets;
+ int modalResult;
+ ALFLayout layout;
+ WORD defid;
+ HWND hwndFocus;
+} ALFWindowPriv;
+
+struct ALFAppPriv {
+ HINSTANCE hInstance;
+ ALFCompatFunctions *compatFn;
+};
+
+ALFCompatFunctions *
+ALF_CreateCompatFuncTable(void);
+