summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.mingw2
-rw-r--r--Makefile.vc62
-rw-r--r--Makefile.vc6-ansi2
-rw-r--r--Makefile.vc6-ansi-3136
-rw-r--r--Makefile.vc6-nt3136
-rw-r--r--alf/alf.cpp116
-rw-r--r--alf/alfcombobox.cpp46
-rw-r--r--alf/alfcompat.cpp107
-rw-r--r--alf/alfcompat.h4
-rw-r--r--alf/alfedit.cpp18
-rw-r--r--alf/alflist.h2
-rw-r--r--alf/alfpriv.h2
-rwxr-xr-xmakemakefile.sh55
-rw-r--r--widgetfactory.cpp17
14 files changed, 378 insertions, 67 deletions
diff --git a/Makefile.mingw b/Makefile.mingw
index 4bc45ce..a93af76 100644
--- a/Makefile.mingw
+++ b/Makefile.mingw
@@ -2,7 +2,7 @@
CXX = i686-w64-mingw32-c++
CFLAGS = -std=c++98 -Wall -Wextra -mwindows -municode -DUNICODE -D_UNICODE -fno-exceptions -fno-rtti -gstabs
-LDFLAGS = -luser32 -lcomctl32 -lshell32 -lrpcrt4 -lversion -static
+LDFLAGS = -luser32 -lcomctl32 -lshell32 -lversion -static
out/widgetfactory.exe: out/widgetfactory.o out/alfbutton.o out/alfcombobox.o out/alfcompat.o out/alf.o out/alfdpiaware.o out/alfedit.o out/alflabel.o
$(CXX) $(CFLAGS) -o $@ $^ $(LDFLAGS)
diff --git a/Makefile.vc6 b/Makefile.vc6
index c0ab753..8a37758 100644
--- a/Makefile.vc6
+++ b/Makefile.vc6
@@ -2,7 +2,7 @@
CXX = cl.exe
CFLAGS = -O2 -GA -W3 -DUNICODE -D_UNICODE -D_WIN32=0x0501 -D_WIN32_WINNT=0x0501 -D_WIN32_IE=0x0501 -nologo
-LDFLAGS = /link unicows.lib kernel32.lib user32.lib comctl32.lib shell32.lib gdi32.lib version.lib rpcrt4.lib
+LDFLAGS = /link unicows.lib kernel32.lib user32.lib comctl32.lib shell32.lib gdi32.lib version.lib
out/widgetfactory.exe: out/widgetfactory.obj out/alfbutton.obj out/alfcombobox.obj out/alfcompat.obj out/alf.obj out/alfdpiaware.obj out/alfedit.obj out/alflabel.obj
$(CXX) $(CFLAGS) -Fe$@ $** $(LDFLAGS)
diff --git a/Makefile.vc6-ansi b/Makefile.vc6-ansi
index 569e9a5..3bf0cb6 100644
--- a/Makefile.vc6-ansi
+++ b/Makefile.vc6-ansi
@@ -2,7 +2,7 @@
CXX = cl.exe
CFLAGS = -O2 -GA -W3 -D_WIN32=0x0501 -D_WIN32_WINNT=0x0501 -D_WIN32_IE=0x0501 -nologo
-LDFLAGS = /link kernel32.lib user32.lib comctl32.lib shell32.lib gdi32.lib version.lib rpcrt4.lib
+LDFLAGS = /link /entry:_entry kernel32.lib user32.lib comctl32.lib shell32.lib gdi32.lib version.lib
out/widgetfactory.exe: out/widgetfactory.obj out/alfbutton.obj out/alfcombobox.obj out/alfcompat.obj out/alf.obj out/alfdpiaware.obj out/alfedit.obj out/alflabel.obj
$(CXX) $(CFLAGS) -Fe$@ $** $(LDFLAGS)
diff --git a/Makefile.vc6-ansi-31 b/Makefile.vc6-ansi-31
new file mode 100644
index 0000000..adb8512
--- /dev/null
+++ b/Makefile.vc6-ansi-31
@@ -0,0 +1,36 @@
+# automatically created by makemakefile.sh. DO NOT EDIT!
+
+CXX = cl.exe
+CFLAGS = -O2 -GA -W3 -D_WIN32=0x0501 -D_WIN32_WINNT=0x0501 -D_WIN32_IE=0x0501 -nologo
+LDFLAGS = /link /subsystem:windows,3.10 /entry:_entry /fixed:no kernel32.lib user32.lib comctl32.lib shell32.lib gdi32.lib version.lib
+
+out/widgetfactory.exe: out/widgetfactory.obj out/alfbutton.obj out/alfcombobox.obj out/alfcompat.obj out/alf.obj out/alfdpiaware.obj out/alfedit.obj out/alflabel.obj
+ $(CXX) $(CFLAGS) -Fe$@ $** $(LDFLAGS)
+
+out/alfbutton.obj: alf/alfbutton.cpp alf/alfcompat.h alf/alf.h alf/alflist.h alf/alfpriv.h
+ $(CXX) $(CFLAGS) -c -Fo$@ alf/alfbutton.cpp
+
+out/alfcombobox.obj: alf/alfcombobox.cpp alf/alfcompat.h alf/alf.h alf/alflist.h alf/alfpriv.h
+ $(CXX) $(CFLAGS) -c -Fo$@ alf/alfcombobox.cpp
+
+out/alfcompat.obj: alf/alfcompat.cpp alf/alfcompat.h alf/alf.h alf/alflist.h alf/alfpriv.h
+ $(CXX) $(CFLAGS) -c -Fo$@ alf/alfcompat.cpp
+
+out/alf.obj: alf/alf.cpp alf/alfcompat.h alf/alf.h alf/alflist.h alf/alfpriv.h
+ $(CXX) $(CFLAGS) -c -Fo$@ alf/alf.cpp
+
+out/alfdpiaware.obj: alf/alfdpiaware.cpp alf/alfcompat.h alf/alf.h alf/alflist.h alf/alfpriv.h
+ $(CXX) $(CFLAGS) -c -Fo$@ alf/alfdpiaware.cpp
+
+out/alfedit.obj: alf/alfedit.cpp alf/alfcompat.h alf/alf.h alf/alflist.h alf/alfpriv.h
+ $(CXX) $(CFLAGS) -c -Fo$@ alf/alfedit.cpp
+
+out/alflabel.obj: alf/alflabel.cpp alf/alfcompat.h alf/alf.h alf/alflist.h alf/alfpriv.h
+ $(CXX) $(CFLAGS) -c -Fo$@ alf/alflabel.cpp
+
+out/widgetfactory.obj: widgetfactory.cpp alf/alf.h
+ $(CXX) $(CFLAGS) -c -Fo$@ widgetfactory.cpp
+
+clean:
+ del /f out\*.obj out\*.exe
+
diff --git a/Makefile.vc6-nt31 b/Makefile.vc6-nt31
new file mode 100644
index 0000000..339a91f
--- /dev/null
+++ b/Makefile.vc6-nt31
@@ -0,0 +1,36 @@
+# automatically created by makemakefile.sh. DO NOT EDIT!
+
+CXX = cl.exe
+CFLAGS = -O2 -GA -W3 -DUNICODE -D_UNICODE -D_WIN32=0x0501 -D_WIN32_WINNT=0x0501 -D_WIN32_IE=0x0501 -nologo
+LDFLAGS = /link /subsystem:windows,3.10 /entry:_entry kernel32.lib user32.lib comctl32.lib shell32.lib gdi32.lib version.lib
+
+out/widgetfactory.exe: out/widgetfactory.obj out/alfbutton.obj out/alfcombobox.obj out/alfcompat.obj out/alf.obj out/alfdpiaware.obj out/alfedit.obj out/alflabel.obj
+ $(CXX) $(CFLAGS) -Fe$@ $** $(LDFLAGS)
+
+out/alfbutton.obj: alf/alfbutton.cpp alf/alfcompat.h alf/alf.h alf/alflist.h alf/alfpriv.h
+ $(CXX) $(CFLAGS) -c -Fo$@ alf/alfbutton.cpp
+
+out/alfcombobox.obj: alf/alfcombobox.cpp alf/alfcompat.h alf/alf.h alf/alflist.h alf/alfpriv.h
+ $(CXX) $(CFLAGS) -c -Fo$@ alf/alfcombobox.cpp
+
+out/alfcompat.obj: alf/alfcompat.cpp alf/alfcompat.h alf/alf.h alf/alflist.h alf/alfpriv.h
+ $(CXX) $(CFLAGS) -c -Fo$@ alf/alfcompat.cpp
+
+out/alf.obj: alf/alf.cpp alf/alfcompat.h alf/alf.h alf/alflist.h alf/alfpriv.h
+ $(CXX) $(CFLAGS) -c -Fo$@ alf/alf.cpp
+
+out/alfdpiaware.obj: alf/alfdpiaware.cpp alf/alfcompat.h alf/alf.h alf/alflist.h alf/alfpriv.h
+ $(CXX) $(CFLAGS) -c -Fo$@ alf/alfdpiaware.cpp
+
+out/alfedit.obj: alf/alfedit.cpp alf/alfcompat.h alf/alf.h alf/alflist.h alf/alfpriv.h
+ $(CXX) $(CFLAGS) -c -Fo$@ alf/alfedit.cpp
+
+out/alflabel.obj: alf/alflabel.cpp alf/alfcompat.h alf/alf.h alf/alflist.h alf/alfpriv.h
+ $(CXX) $(CFLAGS) -c -Fo$@ alf/alflabel.cpp
+
+out/widgetfactory.obj: widgetfactory.cpp alf/alf.h
+ $(CXX) $(CFLAGS) -c -Fo$@ widgetfactory.cpp
+
+clean:
+ del /f out\*.obj out\*.exe
+
diff --git a/alf/alf.cpp b/alf/alf.cpp
index 6936436..aef4167 100644
--- a/alf/alf.cpp
+++ b/alf/alf.cpp
@@ -1,6 +1,6 @@
#include "alfpriv.h"
-#include <rpc.h>
+#include <objbase.h>
/* ALF App and Window */
@@ -62,26 +62,32 @@ ALF_UpdateFontsPriv(HWND win, ALFWindowPriv *priv)
{
priv->fonts.dpi = priv->app->compatFn->GetDpiForWindow(win);
- // XXX: SystemParametersInfoForDpi needs the Vista+ NONCLIENTMETRICS,
- // but we want to be able to build with WINVER = 0x0500 and PSDK2003
- ALF_NONCLIENTMETRICS_VISTA ncm;
- ZeroMemory(&ncm, sizeof(ncm));
- ncm.cbSize = ALF_SizeOf_NONCLIENTMETRICS();
-
- if (priv->app->compatFn->SystemParametersInfoForDpi(SPI_GETNONCLIENTMETRICS, ncm.cbSize, &ncm, 0, priv->fonts.dpi)) {
- priv->fonts.lfMessageFont = ncm.lfMessageFont;
+ if (LOBYTE(LOWORD(GetVersion())) < 4) {
+ // NT 3.x uses System font for everything, we copy that
+ priv->fonts.hMessageFont = (HFONT)GetStockObject(SYSTEM_FONT);
+ GetObject(priv->fonts.hMessageFont, sizeof(priv->fonts.lfMessageFont), &priv->fonts.lfMessageFont);
} else {
- // FIXME! fallback to default font, 8pt MS Shell Dlg
- ZeroMemory(&priv->fonts.lfMessageFont, sizeof(priv->fonts.lfMessageFont));
+ // XXX: SystemParametersInfoForDpi needs the Vista+ NONCLIENTMETRICS,
+ // but we want to be able to build with WINVER = 0x0500 and PSDK2003
+ ALF_NONCLIENTMETRICS_VISTA ncm;
+ ZeroMemory(&ncm, sizeof(ncm));
+ ncm.cbSize = ALF_SizeOf_NONCLIENTMETRICS();
+
+ if (priv->app->compatFn->SystemParametersInfoForDpi(SPI_GETNONCLIENTMETRICS, ncm.cbSize, &ncm, 0, priv->fonts.dpi)) {
+ priv->fonts.lfMessageFont = ncm.lfMessageFont;
+ } else {
+ // FIXME! fallback to default font, 8pt MS Shell Dlg
+ ZeroMemory(&priv->fonts.lfMessageFont, sizeof(priv->fonts.lfMessageFont));
- priv->fonts.lfMessageFont.lfHeight = -MulDiv(8, priv->fonts.dpi, 72);
- lstrcpy(priv->fonts.lfMessageFont.lfFaceName, TEXT("MS Shell Dlg"));
- }
+ priv->fonts.lfMessageFont.lfHeight = -MulDiv(8, priv->fonts.dpi, 72);
+ lstrcpy(priv->fonts.lfMessageFont.lfFaceName, TEXT("MS Shell Dlg"));
+ }
- if (priv->fonts.hMessageFont) {
- DeleteObject(priv->fonts.hMessageFont);
+ if (priv->fonts.hMessageFont) {
+ DeleteObject(priv->fonts.hMessageFont);
+ }
+ priv->fonts.hMessageFont = CreateFontIndirect(&priv->fonts.lfMessageFont);
}
- priv->fonts.hMessageFont = CreateFontIndirect(&priv->fonts.lfMessageFont);
ALF_FOR_LIST(ALFWidgetPriv, list, &priv->widgets, i) {
ALF_UpdateFontForWidget(priv, i);
@@ -249,6 +255,9 @@ ALF_ApplyLayout(HWND hwnd, ALFWindowPriv *win)
HDWP hdwp = BeginDeferWindowPos(win->layout.occupiedColumnCount * win->layout.occupiedRowCount);
ALF_FOR_LIST(ALFWidgetPriv, list, &win->widgets, c) {
+ if ((int)c->x >= win->layout.nColumns || (int)c->y >= win->layout.nRows)
+ continue;
+
int marginleft = ALF_CentipointsToPxPriv(win, c->cptMarginLeft);
int marginright = ALF_CentipointsToPxPriv(win, c->cptMarginRight);
int margintop = ALF_CentipointsToPxPriv(win, c->cptMarginTop);
@@ -549,6 +558,23 @@ ALF_DefWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
return TRUE;
}
+ if (msg == WM_CTLCOLORSTATIC) {
+ HDC hdcStatic = (HDC)wparam;
+ HWND hwndStatic = (HWND)lparam;
+
+ // HACK! return correct label background for NT3.x and NT4/95
+ // get rid of this once we fixed the label to draw on the parent control background
+ if (LOBYTE(LOWORD(GetVersion())) < 4) {
+ SetTextColor(hdcStatic, GetSysColor(IsWindowEnabled(hwndStatic) ? COLOR_WINDOWTEXT : COLOR_GRAYTEXT));
+ SetBkColor(hdcStatic, GetSysColor(COLOR_WINDOW));
+ return (LRESULT)GetSysColorBrush(COLOR_WINDOW);
+ } else {
+ SetTextColor(hdcStatic, GetSysColor(IsWindowEnabled(hwndStatic) ? COLOR_BTNTEXT : COLOR_GRAYTEXT));
+ SetBkColor(hdcStatic, GetSysColor(COLOR_BTNFACE));
+ return (LRESULT)GetSysColorBrush(COLOR_BTNFACE);
+ }
+ }
+
return DefWindowProc(hwnd, msg, wparam, lparam);
}
@@ -599,12 +625,7 @@ ALF_CreateApplication(HINSTANCE hInstance)
ALFAPP app = (ALFAPP)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY|HEAP_GENERATE_EXCEPTIONS, sizeof(struct ALFAppPriv));
app->hInstance = hInstance;
- INITCOMMONCONTROLSEX icc;
- ZeroMemory(&icc, sizeof(icc));
- icc.dwSize = sizeof(icc);
- icc.dwICC = ICC_WIN95_CLASSES;
-
- InitCommonControlsEx(&icc);
+ InitCommonControls();
app->compatFn = ALF_CreateCompatFuncTable();
ALF_RegisterComboClass(app);
@@ -620,23 +641,39 @@ ALF_TeardownApplication(ALFAPP app)
HeapFree(GetProcessHeap(), 0, app);
}
+static void
+ALF_IntToHex(TCHAR *buf, unsigned long num, int chars)
+{
+ char letters[] = { '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
+ for (int i = 0; i < chars; ++i) {
+ buf[chars-i-1] = letters[(num >> (i*4)) & 0xf];
+ }
+}
+
+static void
+ALF_UuidToString(const GUID *guid, TCHAR *buf)
+{
+ ALF_IntToHex(buf, guid->Data1, 8);
+ buf[8] = '-';
+ ALF_IntToHex(buf + 9, guid->Data2, 4);
+ buf[13] = '-';
+ ALF_IntToHex(buf + 14, guid->Data3, 4);
+ buf[18] = '-';
+ for (int i = 0; i < 8; ++i) {
+ ALF_IntToHex(buf + 19 + 2*i, guid->Data4[i], 2);
+ }
+ buf[35] = 0;
+}
+
void
-ALF_BuildRandomClassName(const TCHAR *prefix, TCHAR *buf)
+ALF_BuildRandomClassName(ALFAPP app, const TCHAR* prefix, TCHAR* buf)
{
UUID uuid;
- UuidCreate(&uuid);
-
-#ifdef UNICODE
- unsigned short *uuidstr = NULL;
-#else
- unsigned char *uuidstr = NULL;
-#endif
- UuidToString(&uuid, &uuidstr);
+ app->compatFn->UuidCreate(&uuid);
lstrcpy(buf, prefix);
- lstrcat(buf, (LPCTSTR)uuidstr);
-
- RpcStringFree(&uuidstr);
+ ALF_UuidToString(&uuid, &buf[lstrlen(buf)]);
}
LPTSTR
@@ -651,13 +688,18 @@ ALF_RegisterWindowClass(ALFAPP app, const ALFWindowClassParams *params)
ZeroMemory(classNameBuf, sizeof(classNameBuf));
classNamePtr = classNameBuf;
- ALF_BuildRandomClassName(TEXT("ALFWindow."), classNameBuf);
+ ALF_BuildRandomClassName(app, TEXT("ALFWindow."), classNameBuf);
}
cls.style = params->classStyle;
cls.hInstance = app->hInstance;
cls.hCursor = LoadCursor(NULL, (LPTSTR)IDC_ARROW);
- cls.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
+ if (LOBYTE(LOWORD(GetVersion())) >= 4) {
+ cls.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
+ } else {
+ // NT 3.x has white dialog backgrounds
+ cls.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
+ }
cls.lpszClassName = classNamePtr;
cls.cbWndExtra = sizeof(void*);
cls.cbClsExtra = sizeof(void*)*2;
diff --git a/alf/alfcombobox.cpp b/alf/alfcombobox.cpp
index 3007a20..8afdace 100644
--- a/alf/alfcombobox.cpp
+++ b/alf/alfcombobox.cpp
@@ -42,11 +42,15 @@ ALF__ComboWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
if (uMsg == WM_CREATE) {
ALFComboCreateParams *params = (ALFComboCreateParams*)((CREATESTRUCT*)lParam)->lpCreateParams;
+ DWORD comboStyle = params->comboStyle;
+ if (LOBYTE(LOWORD(GetVersion())) >= 4)
+ comboStyle |= CBS_OWNERDRAWFIXED | CBS_HASSTRINGS;
+
HWND hwndCombo = CreateWindowEx(0,
TEXT("COMBOBOX"),
TEXT(""),
- WS_CHILD | WS_VISIBLE | WS_TABSTOP | CBS_OWNERDRAWFIXED | CBS_HASSTRINGS | params->comboStyle,
- 0, 0, 0, 200 /* FIXME needed for commctl32 v5, what is the best value here? */,
+ WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP | comboStyle,
+ 0, 0, 100, 200 /* FIXME needed for commctl32 v5, what is the best value here? */,
hwnd,
(HMENU) GetWindowLongPtrW(hwnd, GWLP_ID),
((CREATESTRUCT*)lParam)->hInstance,
@@ -121,7 +125,9 @@ ALF__ComboWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
}
if (uMsg == WM_COMMAND && (HWND)lParam == hwndChild) {
- return SendMessage(GetParent(hwnd), WM_COMMAND, wParam, (LPARAM)hwnd);
+ // XXX: for whatever reason, Win95 (and only win95 - doesn't happen on NT)
+ // sends a wrong ID value in WPARAM. We fix it by replacing it with our own id.
+ return SendMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(GetWindowLong(hwnd, GWL_ID), HIWORD(wParam)), (LPARAM)hwnd);
}
if (uMsg == ALF_WM_QUERYSIZE) {
@@ -218,15 +224,22 @@ ALF__ComboWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
if (uMsg == WM_WINDOWPOSCHANGED && hwndChild) {
WINDOWPOS *pos = (WINDOWPOS *)lParam;
if (!(pos->flags & SWP_NOSIZE)) {
- RECT r;
- GetWindowRect(hwndChild, &r);
- SetWindowPos(hwndChild, NULL, 0, 1, pos->cx, r.bottom - r.top, SWP_NOZORDER|SWP_NOACTIVATE);
-
- SendMessage(hwndChild, CB_SETITEMHEIGHT, (WPARAM)-1, pos->cy - 8);
-
- int h = ALF__ComboItemHeight(hwnd);
- if (h)
- SendMessage(hwndChild, CB_SETITEMHEIGHT, (WPARAM)0, h);
+ // XXX: When resizing the combo box, it will improperly draw a selection.
+ // this appears to be a well-known bug that is still not fixed, even in Win10.
+ // workaround based on https://stackoverflow.com/questions/49603893/how-to-deal-with-invalidly-painted-combobox-control-in-win32-winapi
+ DWORD sel = SendMessage(hwndChild, CB_GETEDITSEL, 0, 0);
+ SendMessage(hwndChild, CB_SETEDITSEL, 0, -1);
+ // SWP_NOCOPYBITS because NT 3.51 doesn't properly repaint the drop-down button
+ SetWindowPos(hwndChild, NULL, 0, 1, pos->cx, 200, SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOCOPYBITS);
+ SendMessage(hwndChild, CB_SETEDITSEL, 0, (LPARAM)sel);
+
+ if (LOBYTE(LOWORD(GetVersion())) >= 4) {
+ SendMessage(hwndChild, CB_SETITEMHEIGHT, (WPARAM)-1, pos->cy - 8);
+
+ int h = ALF__ComboItemHeight(hwnd);
+ if (h)
+ SendMessage(hwndChild, CB_SETITEMHEIGHT, (WPARAM)0, h);
+ }
}
}
@@ -241,11 +254,16 @@ ALF_RegisterComboClass(ALFAPP app)
ZeroMemory(&cls, sizeof(cls));
TCHAR classNameBuf[256];
- ALF_BuildRandomClassName(TEXT("ALFComboBox."), classNameBuf);
+ ALF_BuildRandomClassName(app, TEXT("ALFComboBox."), classNameBuf);
cls.hInstance = app->hInstance;
cls.hCursor = LoadCursor(NULL, (LPTSTR)IDC_ARROW);
- cls.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
+ if (LOBYTE(LOWORD(GetVersion())) >= 4) {
+ cls.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
+ } else {
+ // NT 3.x has white dialog backgrounds
+ cls.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
+ }
cls.lpszClassName = classNameBuf;
cls.cbWndExtra = sizeof(void*)*2;
cls.lpfnWndProc = ALF__ComboWindowProc;
diff --git a/alf/alfcompat.cpp b/alf/alfcompat.cpp
index 269b9f4..5486b19 100644
--- a/alf/alfcompat.cpp
+++ b/alf/alfcompat.cpp
@@ -32,6 +32,14 @@ static int WINAPI
fallbackGetSystemMetricsForDpi(int nIndex, UINT dpi)
{
(void)dpi;
+ if (LOBYTE(LOWORD(GetVersion)) < 4) {
+ // old NT does not support several properties, so we fake them
+ switch (nIndex) {
+ case SM_CXEDGE:
+ case SM_CYEDGE:
+ return 2;
+ }
+ }
return GetSystemMetrics(nIndex);
}
@@ -77,6 +85,87 @@ fallbackAdjustWindowRectExForDpi(LPRECT lpRect, DWORD dwStyle, BOOL bMenu, DWORD
return AdjustWindowRectEx(lpRect, dwStyle, bMenu, dwExStyle);
}
+
+// FIXME: these support one subclass only, negating the whole point of it
+
+typedef struct {
+ ALF_COMPAT_SUBCLASSPROC pfnSubclass;
+ UINT_PTR uIdSubclass;
+ DWORD_PTR dwRefData;
+ UINT runCounter;
+ WNDPROC orig;
+} ALFWindowSubclassData;
+
+static LRESULT CALLBACK
+fallbackSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ ALFWindowSubclassData *data = (ALFWindowSubclassData *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
+
+ LRESULT ret = 0;
+
+ data->runCounter++;
+
+ if (data->pfnSubclass)
+ ret = data->pfnSubclass(hwnd, uMsg, wParam, lParam, data->uIdSubclass, data->dwRefData);
+ else
+ ret = CallWindowProc(data->orig, hwnd, uMsg, wParam, lParam);
+
+ data->runCounter--;
+
+ if (!data->pfnSubclass && !data->runCounter) {
+ SetWindowLongPtr(hwnd, GWLP_USERDATA, 0);
+ HeapFree(GetProcessHeap(), 0, data);
+ }
+
+ return ret;
+}
+
+static BOOL WINAPI
+fallbackSetWindowSubclass(HWND hwnd, ALF_COMPAT_SUBCLASSPROC pfnSubclass, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
+{
+ ALFWindowSubclassData *data = (ALFWindowSubclassData *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ALFWindowSubclassData));
+
+ data->pfnSubclass = pfnSubclass;
+ data->uIdSubclass = uIdSubclass;
+ data->dwRefData = dwRefData;
+ data->orig = (WNDPROC)GetWindowLongPtr(hwnd, GWLP_WNDPROC);
+
+ SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)data);
+ SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)fallbackSubclassProc);
+
+ return TRUE;
+}
+
+static LRESULT WINAPI
+fallbackDefSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ ALFWindowSubclassData *data = (ALFWindowSubclassData *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
+
+ return CallWindowProc(data->orig, hwnd, uMsg, wParam, lParam);
+}
+
+static BOOL WINAPI
+fallbackRemoveWindowSubclass(HWND hwnd, ALF_COMPAT_SUBCLASSPROC pfnSubclass, UINT_PTR uIdSubclass)
+{
+ (void)pfnSubclass;
+ (void)uIdSubclass;
+
+ ALFWindowSubclassData *data = (ALFWindowSubclassData *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
+
+ data->pfnSubclass = 0;
+ data->uIdSubclass = 0;
+ SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)data->orig);
+
+ // can't free it while the subclass is running, possibly in a nested SendMessage
+ // and wants to call DefSubclassProc
+ if (!data->runCounter) {
+ SetWindowLongPtr(hwnd, GWLP_USERDATA, 0);
+ HeapFree(GetProcessHeap(), 0, data);
+ }
+
+ return TRUE;
+}
+
ALFCompatFunctions *
ALF_CreateCompatFuncTable(void)
{
@@ -93,9 +182,9 @@ ALF_CreateCompatFuncTable(void)
compatfn->entrypoint = fallback; \
} while (0)
- COMPAT(comctl32.dll, SetWindowSubclass, 410, NULL);
- COMPAT(comctl32.dll, DefSubclassProc, 413, NULL);
- COMPAT(comctl32.dll, RemoveWindowSubclass, 412, NULL);
+ COMPAT(comctl32.dll, SetWindowSubclass, 410, fallbackSetWindowSubclass);
+ COMPAT(comctl32.dll, DefSubclassProc, 413, fallbackDefSubclassProc);
+ COMPAT(comctl32.dll, RemoveWindowSubclass, 412, fallbackRemoveWindowSubclass);
COMPAT(user32.dll, GetSystemMetricsForDpi, 0, fallbackGetSystemMetricsForDpi);
COMPAT(user32.dll, GetDpiForWindow, 0, fallbackGetDpiForWindow);
@@ -121,6 +210,18 @@ ALF_CreateCompatFuncTable(void)
#undef COMPAT
+ UINT oldErrorMode = SetErrorMode(SEM_NOOPENFILEERRORBOX); // stop win32s from barking about rpcrt4
+ HMODULE rpc = LoadLibraryA("rpcrt4.dll");
+ if (rpc) {
+ // NT always has rpcrt4.dll
+ compatfn->UuidCreate = (ULONG(WINAPI*)(UUID*))(void*)GetProcAddress(rpc, "UuidCreate");
+ } else {
+ // Win32s always has OLE32
+ HMODULE ole32 = LoadLibraryA("ole32.dll");
+ compatfn->UuidCreate = (ULONG(WINAPI*)(UUID*))(void*)GetProcAddress(ole32, "CoCreateGuid");
+ }
+ SetErrorMode(oldErrorMode);
+
return compatfn;
}
diff --git a/alf/alfcompat.h b/alf/alfcompat.h
index ba315e1..2d590c8 100644
--- a/alf/alfcompat.h
+++ b/alf/alfcompat.h
@@ -1,4 +1,5 @@
#include <windows.h>
+#include <rpc.h>
#ifndef WM_DPICHANGED
#define WM_DPICHANGED 0x02E0
@@ -6,7 +7,7 @@
typedef LRESULT (CALLBACK *ALF_COMPAT_SUBCLASSPROC)(HWND,UINT,WPARAM,LPARAM,UINT_PTR,DWORD_PTR);
typedef struct {
- LRESULT (WINAPI *SetWindowSubclass)(HWND, ALF_COMPAT_SUBCLASSPROC, UINT_PTR, DWORD_PTR);
+ BOOL (WINAPI *SetWindowSubclass)(HWND, ALF_COMPAT_SUBCLASSPROC, UINT_PTR, DWORD_PTR);
LRESULT (WINAPI *DefSubclassProc)(HWND, UINT, WPARAM, LPARAM);
BOOL (WINAPI *RemoveWindowSubclass)(HWND, ALF_COMPAT_SUBCLASSPROC, UINT_PTR);
int (WINAPI *GetSystemMetricsForDpi)(int, UINT);
@@ -14,6 +15,7 @@ typedef struct {
UINT (WINAPI *GetDpiForWindow)(HWND);
BOOL (WINAPI *SystemParametersInfoForDpi)(UINT,UINT,PVOID,UINT,UINT);
BOOL (WINAPI *AdjustWindowRectExForDpi)(LPRECT,DWORD,BOOL,DWORD,UINT);
+ ULONG (WINAPI *UuidCreate)(UUID *);
} ALFCompatFunctions;
diff --git a/alf/alfedit.cpp b/alf/alfedit.cpp
index fc1d876..bbe36b8 100644
--- a/alf/alfedit.cpp
+++ b/alf/alfedit.cpp
@@ -41,11 +41,12 @@ ALF__EditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_P
} else if (uMsg == ALF_WM_APPLYSIZE) {
RECT *p = (RECT *)lParam;
+ // SWP_NOCOPYBITS as a bandaid since NT 3.51 doesn't invalidate properly
return (LRESULT)DeferWindowPos((HDWP)wParam,
hwnd, NULL,
p->left, p->top + 1,
p->right - p->left, p->bottom - p->top - 2,
- SWP_NOZORDER|SWP_NOACTIVATE);
+ SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOCOPYBITS);
} else if (uMsg == WM_DESTROY) {
app->compatFn->RemoveWindowSubclass(hwnd, ALF__EditSubclassProc, 0);
}
@@ -56,10 +57,21 @@ ALF__EditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_P
HWND
ALF_AddEdit(HWND win, WORD id, UINT x, UINT y, const TCHAR *text)
{
- HWND hwndEdit = CreateWindowEx(WS_EX_CLIENTEDGE,
+ DWORD exstyle;
+ DWORD style;
+
+ if (LOBYTE(LOWORD(GetVersion())) >= 4) {
+ exstyle = WS_EX_CLIENTEDGE;
+ style = 0;
+ } else {
+ exstyle = 0;
+ style = WS_BORDER;
+ }
+
+ HWND hwndEdit = CreateWindowEx(exstyle,
TEXT("EDIT"),
text,
- WS_CHILD | WS_VISIBLE | WS_TABSTOP,
+ WS_CHILD | WS_VISIBLE | WS_TABSTOP | style,
0, 0, 100, 100,
win,
(HMENU)(int)id,
diff --git a/alf/alflist.h b/alf/alflist.h
index e0de033..6f63626 100644
--- a/alf/alflist.h
+++ b/alf/alflist.h
@@ -12,7 +12,7 @@ typedef struct ALFListHeader {
*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) \
+ alf_list_##iteratorvar##_next = alf_list_##iteratorvar##_curr->next) \
for (ContainerType *iteratorvar = (ContainerType *)((char *)alf_list_##iteratorvar##_curr - offsetof(ContainerType, containermember)); \
iteratorvar; iteratorvar = NULL) \
diff --git a/alf/alfpriv.h b/alf/alfpriv.h
index 0d5be2f..95bcda4 100644
--- a/alf/alfpriv.h
+++ b/alf/alfpriv.h
@@ -71,4 +71,4 @@ void
ALF_RegisterComboClass(ALFAPP app);
void
-ALF_BuildRandomClassName(const TCHAR *prefix, TCHAR *buf);
+ALF_BuildRandomClassName(ALFAPP app, const TCHAR *prefix, TCHAR *buf);
diff --git a/makemakefile.sh b/makemakefile.sh
index 22ac030..86a69b4 100755
--- a/makemakefile.sh
+++ b/makemakefile.sh
@@ -13,7 +13,7 @@ ALF_VC6_OBJECTS=$(for i in $ALF_SOURCES; do printf ' out/%s.obj' "$(basename "$i
printf '\n'
printf 'CXX = i686-w64-mingw32-c++\n'
printf 'CFLAGS = -std=c++98 -Wall -Wextra -mwindows -municode -DUNICODE -D_UNICODE -fno-exceptions -fno-rtti -gstabs\n'
- printf 'LDFLAGS = -luser32 -lcomctl32 -lshell32 -lrpcrt4 -lversion -static\n'
+ printf 'LDFLAGS = -luser32 -lcomctl32 -lshell32 -lversion -static\n'
printf '\n'
printf 'out/widgetfactory.exe: out/widgetfactory.o %s\n' "$ALF_MINGW_OBJECTS"
printf '\t$(CXX) $(CFLAGS) -o $@ $^ $(LDFLAGS)\n'
@@ -37,7 +37,7 @@ ALF_VC6_OBJECTS=$(for i in $ALF_SOURCES; do printf ' out/%s.obj' "$(basename "$i
printf '\n'
printf 'CXX = cl.exe\n'
printf 'CFLAGS = -O2 -GA -W3 -DUNICODE -D_UNICODE -D_WIN32=0x0501 -D_WIN32_WINNT=0x0501 -D_WIN32_IE=0x0501 -nologo\n'
- printf 'LDFLAGS = /link unicows.lib kernel32.lib user32.lib comctl32.lib shell32.lib gdi32.lib version.lib rpcrt4.lib\n'
+ printf 'LDFLAGS = /link unicows.lib kernel32.lib user32.lib comctl32.lib shell32.lib gdi32.lib version.lib\n'
printf '\n'
printf 'out/widgetfactory.exe: out/widgetfactory.obj %s\n' "$ALF_VC6_OBJECTS"
@@ -56,13 +56,38 @@ ALF_VC6_OBJECTS=$(for i in $ALF_SOURCES; do printf ' out/%s.obj' "$(basename "$i
printf '\tdel /f out\\*.obj out\\*.exe\n\n'
) > Makefile.vc6
+# vc6 nt31 makefile
+(
+ printf '# automatically created by makemakefile.sh. DO NOT EDIT!\n'
+ printf '\n'
+ printf 'CXX = cl.exe\n'
+ printf 'CFLAGS = -O2 -GA -W3 -DUNICODE -D_UNICODE -D_WIN32=0x0501 -D_WIN32_WINNT=0x0501 -D_WIN32_IE=0x0501 -nologo\n'
+ printf 'LDFLAGS = /link /subsystem:windows,3.10 /entry:_entry kernel32.lib user32.lib comctl32.lib shell32.lib gdi32.lib version.lib\n'
+
+ printf '\n'
+ printf 'out/widgetfactory.exe: out/widgetfactory.obj %s\n' "$ALF_VC6_OBJECTS"
+ printf '\t$(CXX) $(CFLAGS) -Fe$@ $** $(LDFLAGS)\n'
+ printf '\n'
+ for i in $ALF_SOURCES; do
+ printf 'out/%s: %s %s\n' "$(basename "$i" .cpp).obj" "alf/$i" "$(for k in $ALF_HEADERS; do printf ' alf/%s' "$k"; done)"
+ printf '\t$(CXX) $(CFLAGS) -c -Fo$@ %s\n\n' "alf/$i"
+ done
+
+ printf 'out/widgetfactory.obj: widgetfactory.cpp alf/alf.h\n'
+ printf '\t$(CXX) $(CFLAGS) -c -Fo$@ widgetfactory.cpp\n\n'
+
+
+ printf 'clean:\n'
+ printf '\tdel /f out\\*.obj out\\*.exe\n\n'
+) > Makefile.vc6-nt31
+
# vc6 ANSI makefile
(
printf '# automatically created by makemakefile.sh. DO NOT EDIT!\n'
printf '\n'
printf 'CXX = cl.exe\n'
printf 'CFLAGS = -O2 -GA -W3 -D_WIN32=0x0501 -D_WIN32_WINNT=0x0501 -D_WIN32_IE=0x0501 -nologo\n'
- printf 'LDFLAGS = /link kernel32.lib user32.lib comctl32.lib shell32.lib gdi32.lib version.lib rpcrt4.lib\n'
+ printf 'LDFLAGS = /link /entry:_entry kernel32.lib user32.lib comctl32.lib shell32.lib gdi32.lib version.lib\n'
printf '\n'
printf 'out/widgetfactory.exe: out/widgetfactory.obj %s\n' "$ALF_VC6_OBJECTS"
@@ -81,3 +106,27 @@ ALF_VC6_OBJECTS=$(for i in $ALF_SOURCES; do printf ' out/%s.obj' "$(basename "$i
printf '\tdel /f out\\*.obj out\\*.exe\n\n'
) > Makefile.vc6-ansi
+# vc6 NT3.1/Win32s ANSI makefile
+(
+ printf '# automatically created by makemakefile.sh. DO NOT EDIT!\n'
+ printf '\n'
+ printf 'CXX = cl.exe\n'
+ printf 'CFLAGS = -O2 -GA -W3 -D_WIN32=0x0501 -D_WIN32_WINNT=0x0501 -D_WIN32_IE=0x0501 -nologo\n'
+ printf 'LDFLAGS = /link /subsystem:windows,3.10 /entry:_entry /fixed:no kernel32.lib user32.lib comctl32.lib shell32.lib gdi32.lib version.lib\n'
+
+ printf '\n'
+ printf 'out/widgetfactory.exe: out/widgetfactory.obj %s\n' "$ALF_VC6_OBJECTS"
+ printf '\t$(CXX) $(CFLAGS) -Fe$@ $** $(LDFLAGS)\n'
+ printf '\n'
+ for i in $ALF_SOURCES; do
+ printf 'out/%s: %s %s\n' "$(basename "$i" .cpp).obj" "alf/$i" "$(for k in $ALF_HEADERS; do printf ' alf/%s' "$k"; done)"
+ printf '\t$(CXX) $(CFLAGS) -c -Fo$@ %s\n\n' "alf/$i"
+ done
+
+ printf 'out/widgetfactory.obj: widgetfactory.cpp alf/alf.h\n'
+ printf '\t$(CXX) $(CFLAGS) -c -Fo$@ widgetfactory.cpp\n\n'
+
+
+ printf 'clean:\n'
+ printf '\tdel /f out\\*.obj out\\*.exe\n\n'
+) > Makefile.vc6-ansi-31
diff --git a/widgetfactory.cpp b/widgetfactory.cpp
index 42eb987..7956d5c 100644
--- a/widgetfactory.cpp
+++ b/widgetfactory.cpp
@@ -68,6 +68,9 @@ handleCommand(void *closure, HWND window, WORD notificationcode, WORD sourceid,
HWND combo = ALF_WidgetHwndById(window, ID_COMBO2);
ALF_ComboBoxSetCurrentIndex(combo, -1);
}
+ if (control != NULL && sourceid == ID_B2) {
+ MessageBox(window, TEXT("Hello World!"), TEXT("Hello"), MB_ICONASTERISK|MB_OK);
+ }
return 0;
}
@@ -151,7 +154,7 @@ WinMain
ALF_ComboBoxSetText(hwndCombo2, TEXT("Goodbye World!"));
- //EnableWindow(ALF_WidgetHwndById(win, ID_LBL3), FALSE);
+ EnableWindow(ALF_WidgetHwndById(win, ID_LBL3), FALSE);
ALF_ResizeWindow(win, 1, 1);
@@ -163,3 +166,15 @@ WinMain
return 0;
}
+
+void
+_entry(void)
+{
+ ExitProcess(
+#ifdef UNICODE
+wWinMain
+#else
+WinMain
+#endif
+ (GetModuleHandle(NULL), NULL, GetCommandLine(), SW_SHOW));
+}