summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--alf/alf.cpp15
-rw-r--r--alf/alfbutton.cpp432
-rw-r--r--alf/alfcompat.cpp356
-rw-r--r--alf/alfcompat.h42
-rw-r--r--widgetfactory.cpp26
5 files changed, 868 insertions, 3 deletions
diff --git a/alf/alf.cpp b/alf/alf.cpp
index 06e6e0c..0e07e0f 100644
--- a/alf/alf.cpp
+++ b/alf/alf.cpp
@@ -183,6 +183,17 @@ ALF_DefWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
return ret;
}
+ if (msg == WM_DRAWITEM) {
+ LPDRAWITEMSTRUCT dis = (DRAWITEMSTRUCT *)lparam;
+ LRESULT ret = 0;
+ if (wparam && dis->hwndItem) {
+ ret = SendMessage(dis->hwndItem, 0x2000 + WM_DRAWITEM, wparam, lparam);
+ }
+
+ if (ret)
+ return ret;
+ }
+
if (msg == WM_ACTIVATE) {
if (!HIWORD(wparam)) { // if !minimized
if (LOWORD(wparam)) {
@@ -347,12 +358,16 @@ ALF_CreateApplication(HINSTANCE hInstance)
ALF_RegisterPanelClass(app);
ALF_RegisterSpacerClass(app);
+ ALF_Compat_BufferedPaintInit();
+
return app;
}
void
ALF_TeardownApplication(ALFAPP app)
{
+ ALF_Compat_BufferedPaintUnInit();
+
UnregisterClass(app->comboClass, app->hInstance);
UnregisterClass(app->panelClass, app->hInstance);
UnregisterClass(app->spacerClass, app->hInstance);
diff --git a/alf/alfbutton.cpp b/alf/alfbutton.cpp
index 9cf7c1d..fb8d1c3 100644
--- a/alf/alfbutton.cpp
+++ b/alf/alfbutton.cpp
@@ -1,5 +1,271 @@
#include "alfpriv.h"
+#define BP_PUSHBUTTON 1
+#define PBS_NORMAL 1
+#define PBS_HOT 2
+#define PBS_PRESSED 3
+#define PBS_DISABLED 4
+#define PBS_DEFAULTED 5
+#define PBS_DEFAULTED_ANIMATING 6
+
+
+typedef struct {
+ BOOL isDefault;
+ BOOL isHot;
+ HTHEME hTheme;
+ UINT uxStatePrev;
+ UINT uxStateCurrent;
+ UINT itemStatePrev;
+ UINT itemStateCurrent;
+ DWORD uxDefaultAnimationDuration;
+ BOOL uxIsDefaultAnimating;
+} ALFButtonPriv;
+
+static void CALLBACK
+ALF__Button_DefaultAnimatingTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
+{
+ (void)uMsg;
+ (void)dwTime;
+ ALFButtonPriv *priv = (ALFButtonPriv *)idEvent;
+
+ priv->uxIsDefaultAnimating = !priv->uxIsDefaultAnimating;
+ InvalidateRect(hwnd, NULL, FALSE);
+}
+
+static BOOL CALLBACK
+ALF__Button_Text_DrawStateProc(HDC hdc, LPARAM lData, WPARAM wData, int cx, int cy)
+{
+ (void)wData;
+
+ int oldBkMode = SetBkMode(hdc, TRANSPARENT);
+
+ RECT r = { 0, 0, cx, cy };
+ DrawText(hdc, (TCHAR*)lData, -1, &r, (UINT)wData);
+
+ SetBkMode(hdc, oldBkMode);
+
+ return TRUE;
+}
+
+static void
+ALF__Button_RenderUxtheme(HWND hwnd, ALFButtonPriv *priv, UINT uxstate, UINT itemState, HDC hDC, LPRECT pRcItem)
+{
+ if (ALF_Compat_IsThemeBackgroundPartiallyTransparent(priv->hTheme, BP_PUSHBUTTON, uxstate)) {
+ ALF_Compat_DrawThemeParentBackground(hwnd, hDC, pRcItem);
+ }
+
+ RECT r = *pRcItem;
+ InflateRect(&r, 1, 1); // HACK! get rid of 1px transparent border
+
+ ALF_Compat_DrawThemeBackground(priv->hTheme, hDC, BP_PUSHBUTTON, uxstate, &r, pRcItem);
+
+ RECT content = r;
+ ALF_Compat_GetThemeBackgroundContentRect(priv->hTheme, hDC, BP_PUSHBUTTON, uxstate, &r, &content);
+
+ if ((itemState & ODS_FOCUS) && !(itemState & ODS_NOFOCUSRECT))
+ DrawFocusRect(hDC, &content);
+
+ int textlen = GetWindowTextLengthW(hwnd);
+ WCHAR *textbuf = ALF_New(WCHAR, textlen + 1);
+ GetWindowTextW(hwnd, textbuf, textlen+1);
+
+ UINT style = DT_CENTER;
+
+ if (itemState & ODS_NOACCEL)
+ style |= DT_HIDEPREFIX;
+
+ RECT textbounds = content;
+ ALF_Compat_GetThemeTextExtent(priv->hTheme, hDC, BP_PUSHBUTTON, uxstate, textbuf, -1, style, &content, &textbounds);
+
+ RECT texttarget = content;
+ texttarget.top += ((content.bottom - content.top) - (textbounds.bottom - textbounds.top)) / 2;
+ texttarget.left += ((content.right - content.left) - (textbounds.right - textbounds.left)) / 2;
+ texttarget.right = texttarget.left + (textbounds.right - textbounds.left);
+ texttarget.bottom = texttarget.top + (textbounds.bottom - textbounds.top);
+
+ ALF_Compat_DrawThemeText(priv->hTheme, hDC, BP_PUSHBUTTON, uxstate, textbuf, -1, style, 0, &texttarget);
+
+ ALF_Free(textbuf);
+}
+
+static void
+ALF__Button_Render95(HWND hwnd, ALFButtonPriv *priv, LPDRAWITEMSTRUCT dis)
+{
+ RECT r = dis->rcItem;
+ DWORD v = GetVersion();
+
+ int textlen = GetWindowTextLength(hwnd);
+ TCHAR *textbuf = ALF_New(TCHAR, textlen + 1);
+ GetWindowText(hwnd, textbuf, textlen+1);
+
+ if (priv->isDefault) {
+ HBRUSH framecolor = GetSysColorBrush(COLOR_WINDOWFRAME);
+ FrameRect(dis->hDC, &r, framecolor);
+ InflateRect(&r, -1, -1);
+ }
+
+ UINT dfcs = DFCS_BUTTONPUSH | DFCS_ADJUSTRECT;
+ if (dis->itemState & ODS_SELECTED)
+ dfcs |= DFCS_FLAT;
+ if (dis->itemState & ODS_DISABLED)
+ dfcs |= DFCS_INACTIVE;
+ if (dis->itemState & ODS_HOTLIGHT)
+ dfcs |= DFCS_HOT;
+
+ DrawFrameControl(dis->hDC, &r, DFC_BUTTON, dfcs);
+
+ if ((dis->itemState & ODS_FOCUS) && !(dis->itemState & ODS_NOFOCUSRECT)) {
+ RECT f = r;
+ InflateRect(&f, -1, -1);
+ DrawFocusRect(dis->hDC, &f);
+ }
+
+ RECT textbounds = dis->rcItem;
+ DrawText(dis->hDC, textbuf, -1, &textbounds, DT_LEFT | DT_CALCRECT);
+
+ RECT texttarget = dis->rcItem;
+ texttarget.top += ((dis->rcItem.bottom - dis->rcItem.top) - (textbounds.bottom - textbounds.top)) / 2 - 1;
+ texttarget.left += ((dis->rcItem.right - dis->rcItem.left) - (textbounds.right - textbounds.left)) / 2;
+ texttarget.right = texttarget.left + (textbounds.right - textbounds.left);
+ texttarget.bottom = texttarget.top + (textbounds.bottom - textbounds.top);
+
+ if (dis->itemState & ODS_SELECTED) {
+ texttarget.top += 1;
+ texttarget.left += 1;
+ texttarget.right += 1;
+ texttarget.bottom += 1;
+ }
+
+ UINT style = DT_CENTER;
+
+ if (dis->itemState & ODS_NOACCEL)
+ style |= DT_HIDEPREFIX;
+
+ if (dis->itemState & ODS_DISABLED) {
+ if (v >= 0x80000000) {
+ // Win9x just uses gray text. DSS_DISABLED is broken there, too,
+ // so we can't get the NT look even if we wanted to
+ COLORREF oldTextColor = SetTextColor(dis->hDC, GetSysColor(COLOR_GRAYTEXT));
+
+ POINT oldorg = { 0, 0 };
+ SetViewportOrgEx(dis->hDC, texttarget.left, texttarget.top, &oldorg);
+ ALF__Button_Text_DrawStateProc(dis->hDC, (LPARAM)textbuf, (WPARAM)style,
+ texttarget.right - texttarget.left, texttarget.bottom - texttarget.top);
+ SetViewportOrgEx(dis->hDC, oldorg.x, oldorg.y, NULL);
+
+ SetTextColor(dis->hDC, oldTextColor);
+ } else {
+ DrawState(dis->hDC, NULL, ALF__Button_Text_DrawStateProc,
+ (LPARAM)textbuf, (WPARAM)style,
+ texttarget.left, texttarget.top,
+ texttarget.right - texttarget.left, texttarget.bottom - texttarget.top,
+ DST_COMPLEX | DSS_DISABLED);
+ }
+ } else {
+ POINT oldorg = { 0, 0 };
+
+ SetViewportOrgEx(dis->hDC, texttarget.left, texttarget.top, &oldorg);
+ ALF__Button_Text_DrawStateProc(dis->hDC, (LPARAM)textbuf, (WPARAM)style,
+ texttarget.right - texttarget.left, texttarget.bottom - texttarget.top);
+ SetViewportOrgEx(dis->hDC, oldorg.x, oldorg.y, NULL);
+ }
+
+ ALF_Free(textbuf);
+}
+
+static void
+ALF__Button_Render3x(HWND hwnd, ALFButtonPriv *priv, LPDRAWITEMSTRUCT dis)
+{
+ RECT r = dis->rcItem;
+
+ int textlen = GetWindowTextLength(hwnd);
+ TCHAR *textbuf = ALF_New(TCHAR, textlen + 1);
+ GetWindowText(hwnd, textbuf, textlen+1);
+
+ HBRUSH framecolor = GetSysColorBrush(COLOR_WINDOWFRAME);
+ HBRUSH facecolor = GetSysColorBrush(COLOR_BTNFACE);
+
+ // black frame
+ if (priv->isDefault) {
+ RECT rt = { r.left + 1, r.top, r.right - 1, r.top + 2 };
+ RECT rl = { r.left, r.top + 1, r.left + 2, r.bottom - 1 };
+ RECT rr = { r.right - 2, r.top + 1, r.right, r.bottom - 1 };
+ RECT rb = { r.left + 1, r.bottom - 2, r.right - 1, r.bottom };
+ FillRect(dis->hDC, &rt, framecolor);
+ FillRect(dis->hDC, &rl, framecolor);
+ FillRect(dis->hDC, &rr, framecolor);
+ FillRect(dis->hDC, &rb, framecolor);
+ InflateRect(&r, -2, -2);
+ } else {
+ RECT rt = { r.left + 1, r.top, r.right - 1, r.top + 1 };
+ RECT rl = { r.left, r.top + 1, r.left + 1, r.bottom - 1 };
+ RECT rr = { r.right - 1, r.top + 1, r.right, r.bottom - 1 };
+ RECT rb = { r.left + 1, r.bottom - 1, r.right - 1, r.bottom };
+ FillRect(dis->hDC, &rt, framecolor);
+ FillRect(dis->hDC, &rl, framecolor);
+ FillRect(dis->hDC, &rr, framecolor);
+ FillRect(dis->hDC, &rb, framecolor);
+ InflateRect(&r, -1, -1);
+ }
+
+ // 3d button
+ if (dis->itemState & ODS_SELECTED) {
+ DrawEdge(dis->hDC, &r, BDR_SUNKENOUTER, BF_TOPLEFT);
+
+ RECT f = r;
+ f.left++;
+ f.top++;
+
+ FillRect(dis->hDC, &f, facecolor);
+
+ InflateRect(&r, -2, -2);
+ } else {
+ DrawEdge(dis->hDC, &r, BDR_RAISEDINNER, BF_RECT);
+ InflateRect(&r, -1, -1);
+ DrawEdge(dis->hDC, &r, BDR_RAISEDINNER, BF_RECT);
+ InflateRect(&r, -1, -1);
+
+ FillRect(dis->hDC, &r, facecolor);
+ }
+
+ RECT textbounds = dis->rcItem;
+ DrawText(dis->hDC, textbuf, -1, &textbounds, DT_LEFT | DT_CALCRECT);
+
+ RECT texttarget = dis->rcItem;
+ texttarget.top += ((dis->rcItem.bottom - dis->rcItem.top) - (textbounds.bottom - textbounds.top)) / 2;
+ texttarget.left += ((dis->rcItem.right - dis->rcItem.left) - (textbounds.right - textbounds.left)) / 2;
+ texttarget.right = texttarget.left + (textbounds.right - textbounds.left);
+ texttarget.bottom = texttarget.top + (textbounds.bottom - textbounds.top);
+
+ if (dis->itemState & ODS_SELECTED) {
+ texttarget.top += 1;
+ texttarget.left += 1;
+ texttarget.right += 1;
+ texttarget.bottom += 1;
+ }
+
+ if (dis->itemState & ODS_FOCUS) {
+ DrawFocusRect(dis->hDC, &texttarget);
+ }
+
+ int oldBkMode = SetBkMode(dis->hDC, TRANSPARENT);
+
+ if (dis->itemState & ODS_DISABLED) {
+ // FIXME! This is how NT 3.51 does it, but Win 3.1 is different
+ COLORREF oldTextColor = SetTextColor(dis->hDC, GetSysColor(COLOR_BTNSHADOW));
+
+ DrawText(dis->hDC, textbuf, -1, &texttarget, DT_CENTER);
+
+ SetTextColor(dis->hDC, oldTextColor);
+ } else {
+ DrawText(dis->hDC, textbuf, -1, &texttarget, DT_CENTER);
+ }
+
+ SetBkMode(dis->hDC, oldBkMode);
+
+ ALF_Free(textbuf);
+}
+
/* BUTTON */
static LRESULT CALLBACK
ALF__ButtonSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
@@ -7,6 +273,8 @@ ALF__ButtonSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT
(void)uIdSubclass;
(void)dwRefData;
+ ALFButtonPriv *priv = (ALFButtonPriv *)dwRefData;
+
if (uMsg == ALF_WM_QUERYSIZE) {
HDC hdc = GetDC(hwnd);
HFONT font = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0);
@@ -50,7 +318,160 @@ ALF__ButtonSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT
SelectFont(hdc, oldFont);
ReleaseDC(hwnd, hdc);
+ } else if (uMsg == 0x2000 + WM_DRAWITEM) {
+ LPDRAWITEMSTRUCT dis = (DRAWITEMSTRUCT *)lParam;
+ DWORD v = GetVersion();
+
+ if (!ALF_Compat_BufferedPaintRenderAnimation(hwnd, dis->hDC)) {
+ if (priv->hTheme) {
+ // Draw XP style themed button
+ UINT stateid = PBS_NORMAL;
+
+ if (priv->isDefault && IsChild(GetForegroundWindow(), hwnd))
+ stateid = priv->uxIsDefaultAnimating ? PBS_DEFAULTED_ANIMATING : PBS_DEFAULTED;
+ if (priv->isHot)
+ stateid = PBS_HOT;
+ if (dis->itemState & ODS_SELECTED)
+ stateid = PBS_PRESSED;
+ if (dis->itemState & ODS_DISABLED)
+ stateid = PBS_DISABLED;
+
+ if (priv->uxStatePrev == (UINT)-1) {
+ // initial draw
+ priv->uxStateCurrent = stateid;
+ priv->itemStateCurrent = dis->itemState;
+
+ if (priv->uxStateCurrent == PBS_DEFAULTED || priv->uxStateCurrent == PBS_DEFAULTED_ANIMATING)
+ priv->uxStateCurrent = PBS_NORMAL;
+ }
+
+ priv->uxStatePrev = priv->uxStateCurrent;
+ priv->uxStateCurrent = stateid;
+ priv->itemStatePrev = priv->itemStateCurrent;
+ priv->itemStateCurrent = dis->itemState;
+
+ ALF_Compat_BP_ANIMATIONPARAMS animParams;
+ ZeroMemory(&animParams, sizeof(animParams));
+ animParams.cbSize = sizeof(animParams);
+ animParams.style = ALF_Compat_BPAS_LINEAR;
+
+ if (priv->uxStateCurrent != priv->uxStatePrev) {
+ if ((priv->uxStateCurrent == PBS_DEFAULTED && priv->uxStatePrev == PBS_DEFAULTED_ANIMATING) ||
+ (priv->uxStatePrev == PBS_DEFAULTED && priv->uxStateCurrent == PBS_DEFAULTED_ANIMATING)) {
+ animParams.dwDuration = priv->uxDefaultAnimationDuration;
+ } else if (priv->uxStateCurrent == PBS_DEFAULTED_ANIMATING) {
+ // Win7 misses these transition times, use the one for PBS_DEFAULTED
+ ALF_Compat_GetThemeTransitionDuration(priv->hTheme,
+ BP_PUSHBUTTON,
+ priv->uxStatePrev,
+ PBS_DEFAULTED,
+ TMT_TRANSITIONDURATION,
+ &animParams.dwDuration);
+ } else if (priv->uxStatePrev == PBS_DEFAULTED_ANIMATING) {
+ // Win7 misses these transition times, use the one for PBS_DEFAULTED
+ ALF_Compat_GetThemeTransitionDuration(priv->hTheme,
+ BP_PUSHBUTTON,
+ PBS_DEFAULTED,
+ priv->uxStateCurrent,
+ TMT_TRANSITIONDURATION,
+ &animParams.dwDuration);
+ } else {
+ ALF_Compat_GetThemeTransitionDuration(priv->hTheme,
+ BP_PUSHBUTTON,
+ priv->uxStatePrev,
+ priv->uxStateCurrent,
+ TMT_TRANSITIONDURATION,
+ &animParams.dwDuration);
+ }
+
+ if ((priv->uxStatePrev == PBS_DEFAULTED || priv->uxStatePrev == PBS_DEFAULTED_ANIMATING)
+ && !(priv->uxStateCurrent == PBS_DEFAULTED || priv->uxStateCurrent == PBS_DEFAULTED_ANIMATING)) {
+ KillTimer(hwnd, (UINT_PTR)priv);
+ priv->uxIsDefaultAnimating = FALSE;
+ }
+
+ if (!(priv->uxStatePrev == PBS_DEFAULTED || priv->uxStatePrev == PBS_DEFAULTED_ANIMATING)
+ && (priv->uxStateCurrent == PBS_DEFAULTED || priv->uxStateCurrent == PBS_DEFAULTED_ANIMATING)
+ && priv->uxDefaultAnimationDuration) {
+ SetTimer(hwnd, (UINT_PTR)priv, priv->uxDefaultAnimationDuration, ALF__Button_DefaultAnimatingTimerProc);
+ }
+ }
+
+ HDC hdcFrom = NULL, hdcTo = NULL;
+ ALF_Compat_HANIMATIONBUFFER hbpAnimation;
+
+ hbpAnimation = ALF_Compat_BeginBufferedAnimation(hwnd, dis->hDC, &dis->rcItem, 0, NULL, &animParams, &hdcFrom, &hdcTo);
+ if (hbpAnimation) {
+ HFONT font = (HFONT)GetCurrentObject(dis->hDC, OBJ_FONT);
+
+ if (hdcFrom) {
+ SelectFont(hdcFrom, font);
+ ALF__Button_RenderUxtheme(hwnd, priv, priv->uxStatePrev, priv->itemStatePrev, hdcFrom, &dis->rcItem);
+ }
+
+ if (hdcTo) {
+ SelectFont(hdcTo, font);
+ ALF__Button_RenderUxtheme(hwnd, priv, priv->uxStateCurrent, priv->itemStateCurrent, hdcTo, &dis->rcItem);
+ }
+
+ ALF_Compat_EndBufferedAnimation(hbpAnimation, TRUE);
+ } else {
+ ALF__Button_RenderUxtheme(hwnd, priv, stateid, dis->itemState, dis->hDC, &dis->rcItem);
+ }
+ } else if (LOBYTE(LOWORD(v)) < 4) {
+ // Draw pre-95 style button
+ ALF__Button_Render3x(hwnd, priv, dis);
+ } else {
+ // Draw 95 style button
+ ALF__Button_Render95(hwnd, priv, dis);
+ }
+ }
+
+ return TRUE;
+ } else if (uMsg == WM_GETDLGCODE) {
+ if (priv->isDefault) {
+ return DLGC_DEFPUSHBUTTON | DLGC_BUTTON;
+ } else {
+ return DLGC_UNDEFPUSHBUTTON | DLGC_BUTTON;
+ }
+ } else if (uMsg == BM_SETSTYLE) {
+ // HACK! stop windows from resetting the owner draw flag
+ priv->isDefault = (wParam & BS_DEFPUSHBUTTON) ? 1 : 0;
+
+ return ALF_Compat_DefSubclassProc(hwnd, BM_SETSTYLE, (wParam & 0xFFFFFFF0) | BS_OWNERDRAW, lParam);
+ } else if (uMsg == WM_THEMECHANGED) {
+ ALF_Compat_CloseThemeData(priv->hTheme);
+ priv->hTheme = NULL;
+ if (ALF_Compat_IsAppThemed())
+ priv->hTheme = ALF_Compat_OpenThemeData(hwnd, L"Button");
+ priv->uxDefaultAnimationDuration = 0;
+ ALF_Compat_GetThemeTransitionDuration(priv->hTheme,
+ BP_PUSHBUTTON,
+ PBS_DEFAULTED,
+ PBS_DEFAULTED_ANIMATING,
+ TMT_TRANSITIONDURATION,
+ &priv->uxDefaultAnimationDuration);
+ InvalidateRect(hwnd, NULL, TRUE);
+ } else if (uMsg == WM_MOUSEMOVE) {
+ if (!priv->isHot) {
+ TRACKMOUSEEVENT tme;
+ ZeroMemory(&tme, sizeof(tme));
+ tme.cbSize = sizeof(tme);
+ tme.dwFlags = TME_LEAVE;
+ tme.hwndTrack = hwnd;
+ if (ALF_Compat_TrackMouseEvent(&tme)) {
+ priv->isHot = TRUE;
+ InvalidateRect(hwnd, NULL, FALSE);
+ }
+ }
+ } else if (uMsg == WM_MOUSELEAVE) {
+ if (priv->isHot) {
+ priv->isHot = FALSE;
+ InvalidateRect(hwnd, NULL, FALSE);
+ }
} else if (uMsg == WM_DESTROY) {
+ ALF_Compat_CloseThemeData(priv->hTheme);
+ ALF_Free(priv);
ALF_Compat_RemoveWindowSubclass(hwnd, ALF__ButtonSubclassProc, 0);
}
@@ -63,15 +484,20 @@ 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,
+ WS_CHILD | WS_TABSTOP | WS_VISIBLE | BS_PUSHBUTTON | BS_MULTILINE | BS_OWNERDRAW,
0, 0, 100, 100,
win,
(HMENU)(int)id,
(HINSTANCE)GetWindowLongPtr(win, GWLP_HINSTANCE),
NULL);
- ALF_Compat_SetWindowSubclass(hwndButton, ALF__ButtonSubclassProc, 0, 0);
- SetWindowPos(hwndButton, NULL, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED);
+ ALFButtonPriv *priv = ALF_New(ALFButtonPriv, 1);
+ priv->uxStateCurrent = (UINT)-1;
+ priv->uxStatePrev = (UINT)-1;
+
+ ALF_Compat_SetWindowSubclass(hwndButton, ALF__ButtonSubclassProc, 0, (DWORD_PTR)priv);
+
+ SendMessage(hwndButton, WM_THEMECHANGED, 0, 0);
ALFWidgetLayoutParams p;
ZeroMemory(&p, sizeof(p));
diff --git a/alf/alfcompat.cpp b/alf/alfcompat.cpp
index 2260ed4..c0e11ba 100644
--- a/alf/alfcompat.cpp
+++ b/alf/alfcompat.cpp
@@ -358,6 +358,346 @@ ALF_Compat_loadSystemParametersInfoForDpi(UINT uiAction, UINT uiParam, PVOID pvP
return ALF_Compat_SystemParametersInfoForDpi(uiAction, uiParam, pvParam, fWinIni, dpi);
}
+static HTHEME WINAPI
+ALF_Compat_fallbackOpenThemeData(HWND window, LPCWSTR classNames)
+{
+ (void)window;
+ (void)classNames;
+
+ return NULL;
+}
+
+static HTHEME WINAPI
+ALF_Compat_loadOpenThemeData(HWND window, LPCWSTR classNames)
+{
+ void *p = (void*)GetProcAddress(GetModuleHandleA("uxtheme.dll"), "OpenThemeData");
+ if (!p)
+ p = (void*)ALF_Compat_fallbackOpenThemeData;
+
+ InterlockedCompareExchangePointer((void**)&ALF_Compat_OpenThemeData, p, (void*)ALF_Compat_loadOpenThemeData);
+
+ return ALF_Compat_OpenThemeData(window, classNames);
+}
+
+static HRESULT WINAPI
+ALF_Compat_fallbackCloseThemeData(HTHEME hTheme)
+{
+ (void)hTheme;
+
+ return S_OK;
+}
+
+static HRESULT WINAPI
+ALF_Compat_loadCloseThemeData(HTHEME hTheme)
+{
+ void *p = (void*)GetProcAddress(GetModuleHandleA("uxtheme.dll"), "CloseThemeData");
+ if (!p)
+ p = (void*)ALF_Compat_fallbackCloseThemeData;
+
+ InterlockedCompareExchangePointer((void**)&ALF_Compat_CloseThemeData, p, (void*)ALF_Compat_loadCloseThemeData);
+
+ return ALF_Compat_CloseThemeData(hTheme);
+}
+
+static BOOL WINAPI
+ALF_Compat_fallbackIsThemeBackgroundPartiallyTransparent(HTHEME hTheme, int iPartId, int iStateId)
+{
+ (void)hTheme; (void)iPartId; (void)iStateId;
+
+ return TRUE;
+}
+
+static BOOL WINAPI
+ALF_Compat_loadIsThemeBackgroundPartiallyTransparent(HTHEME hTheme, int iPartId, int iStateId)
+{
+ void *p = (void*)GetProcAddress(GetModuleHandleA("uxtheme.dll"), "IsThemeBackgroundPartiallyTransparent");
+ if (!p)
+ p = (void*)ALF_Compat_fallbackIsThemeBackgroundPartiallyTransparent;
+
+ InterlockedCompareExchangePointer((void**)&ALF_Compat_IsThemeBackgroundPartiallyTransparent, p, (void*)ALF_Compat_loadIsThemeBackgroundPartiallyTransparent);
+
+ return ALF_Compat_IsThemeBackgroundPartiallyTransparent(hTheme, iPartId, iStateId);
+}
+
+static HRESULT WINAPI
+ALF_Compat_fallbackDrawThemeParentBackground(HWND hwnd, HDC hdc, RECT *prc)
+{
+ (void)hwnd;
+ (void)hdc;
+ (void)prc;
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+ALF_Compat_loadDrawThemeParentBackground(HWND hwnd, HDC hdc, RECT *prc)
+{
+ void *p = (void*)GetProcAddress(GetModuleHandleA("uxtheme.dll"), "DrawThemeParentBackground");
+ if (!p)
+ p = (void*)ALF_Compat_fallbackDrawThemeParentBackground;
+
+ InterlockedCompareExchangePointer((void**)&ALF_Compat_DrawThemeParentBackground, p, (void*)ALF_Compat_loadDrawThemeParentBackground);
+
+ return ALF_Compat_DrawThemeParentBackground(hwnd, hdc, prc);
+}
+
+static HRESULT WINAPI
+ALF_Compat_fallbackDrawThemeBackground(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, const RECT *pClipRect)
+{
+ (void)hTheme;
+ (void)hdc;
+ (void)iPartId;
+ (void)iStateId;
+ (void)pRect;
+ (void)pClipRect;
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+ALF_Compat_loadDrawThemeBackground(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, const RECT *pClipRect)
+{
+ void *p = (void*)GetProcAddress(GetModuleHandleA("uxtheme.dll"), "DrawThemeBackground");
+ if (!p)
+ p = (void*)ALF_Compat_fallbackDrawThemeBackground;
+
+ InterlockedCompareExchangePointer((void**)&ALF_Compat_DrawThemeBackground, p, (void*)ALF_Compat_loadDrawThemeBackground);
+
+ return ALF_Compat_DrawThemeBackground(hTheme, hdc, iPartId, iStateId, pRect, pClipRect);
+}
+
+static HRESULT WINAPI
+ALF_Compat_fallbackGetThemeBackgroundContentRect(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pBoundingRect, RECT *pContentRect)
+{
+ (void)hTheme;
+ (void)hdc;
+ (void)iPartId;
+ (void)iStateId;
+ (void)pBoundingRect;
+ (void)pContentRect;
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+ALF_Compat_loadGetThemeBackgroundContentRect(HTHEME hTheme, HDC hdc, int iPArtId, int iStateId, const RECT *pBoundingRect, RECT *pContentRect)
+{
+ void *p = (void*)GetProcAddress(GetModuleHandleA("uxtheme.dll"), "GetThemeBackgroundContentRect");
+ if (!p)
+ p = (void*)ALF_Compat_fallbackGetThemeBackgroundContentRect;
+
+ InterlockedCompareExchangePointer((void**)&ALF_Compat_GetThemeBackgroundContentRect, p, (void*)ALF_Compat_loadGetThemeBackgroundContentRect);
+
+ return ALF_Compat_GetThemeBackgroundContentRect(hTheme, hdc, iPArtId, iStateId, pBoundingRect, pContentRect);
+}
+
+static HRESULT WINAPI
+ALF_Compat_fallbackGetThemeTextExtent(HTHEME hTheme, HDC hdc, int iPartId,
+ int iStateId, LPCWSTR pszText, int iCharCount,
+ DWORD dwTextFlags, const RECT *pBoundingRect,
+ RECT *pExtentRect)
+{
+ (void)hTheme; (void)hdc; (void)iPartId; (void)iStateId; (void)pszText;
+ (void)iCharCount; (void)dwTextFlags; (void)pBoundingRect; (void)pExtentRect;
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+ALF_Compat_loadGetThemeTextExtent(HTHEME hTheme, HDC hdc, int iPartId,
+ int iStateId, LPCWSTR pszText, int iCharCount,
+ DWORD dwTextFlags, const RECT *pBoundingRect,
+ RECT *pExtentRect)
+{
+ void *p = (void*)GetProcAddress(GetModuleHandleA("uxtheme.dll"), "GetThemeTextExtent");
+ if (!p)
+ p = (void*)ALF_Compat_fallbackGetThemeTextExtent;
+
+ InterlockedCompareExchangePointer((void**)&ALF_Compat_GetThemeTextExtent, p, (void*)ALF_Compat_loadGetThemeTextExtent);
+
+ return ALF_Compat_GetThemeTextExtent(hTheme, hdc, iPartId, iStateId, pszText, iCharCount, dwTextFlags, pBoundingRect, pExtentRect);
+}
+
+static HRESULT WINAPI
+ALF_Compat_fallbackDrawThemeText(HTHEME hTheme, HDC hdc, int iPartId, int iStateId,
+ LPCWSTR pszText, int iCharCount, DWORD dwTextFlags,
+ DWORD dwTextFlags2, const RECT *pRect)
+{
+ (void)hTheme; (void)hdc; (void)iPartId; (void)iStateId; (void)pszText;
+ (void)iCharCount; (void)dwTextFlags; (void)dwTextFlags2; (void)pRect;
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+ALF_Compat_loadDrawThemeText(HTHEME hTheme, HDC hdc, int iPartId, int iStateId,
+ LPCWSTR pszText, int iCharCount, DWORD dwTextFlags,
+ DWORD dwTextFlags2, const RECT *pRect)
+{
+ void *p = (void*)GetProcAddress(GetModuleHandleA("uxtheme.dll"), "DrawThemeText");
+ if (!p)
+ p = (void*)ALF_Compat_fallbackDrawThemeText;
+
+ InterlockedCompareExchangePointer((void**)&ALF_Compat_DrawThemeText, p, (void*)ALF_Compat_loadDrawThemeText);
+
+ return ALF_Compat_DrawThemeText(hTheme, hdc, iPartId, iStateId, pszText, iCharCount, dwTextFlags, dwTextFlags2, pRect);
+}
+
+static BOOL WINAPI
+ALF_Compat_fallbackTrackMouseEvent(LPTRACKMOUSEEVENT tme)
+{
+ (void)tme;
+
+ return FALSE;
+}
+
+static BOOL WINAPI
+ALF_Compat_loadTrackMouseEvent(LPTRACKMOUSEEVENT tme)
+{
+ void *p = (void*)GetProcAddress(GetModuleHandleA("comctl32.dll"), "_TrackMouseEvent");
+ if (!p)
+ p = (void*)ALF_Compat_fallbackTrackMouseEvent;
+
+ InterlockedCompareExchangePointer((void**)&ALF_Compat_TrackMouseEvent, p, (void*)ALF_Compat_loadTrackMouseEvent);
+
+ return ALF_Compat_TrackMouseEvent(tme);
+}
+
+static HRESULT WINAPI
+ALF_Compat_fallbackBufferedPaintInit(void)
+{
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+ALF_Compat_loadBufferedPaintInit(void)
+{
+ void *p = (void*)GetProcAddress(GetModuleHandleA("uxtheme.dll"), "BufferedPaintInit");
+ if (!p)
+ p = (void*)ALF_Compat_fallbackBufferedPaintInit;
+
+ InterlockedCompareExchangePointer((void**)&ALF_Compat_BufferedPaintInit, p, (void*)ALF_Compat_loadBufferedPaintInit);
+
+ return ALF_Compat_BufferedPaintInit();
+}
+
+static HRESULT WINAPI
+ALF_Compat_fallbackBufferedPaintUnInit(void)
+{
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+ALF_Compat_loadBufferedPaintUnInit(void)
+{
+ void *p = (void*)GetProcAddress(GetModuleHandleA("uxtheme.dll"), "BufferedPaintUnInit");
+ if (!p)
+ p = (void*)ALF_Compat_fallbackBufferedPaintUnInit;
+
+ InterlockedCompareExchangePointer((void**)&ALF_Compat_BufferedPaintUnInit, p, (void*)ALF_Compat_loadBufferedPaintUnInit);
+
+ return ALF_Compat_BufferedPaintUnInit();
+}
+
+static ALF_Compat_HANIMATIONBUFFER WINAPI
+ALF_Compat_fallbackBeginBufferedAnimation(HWND hwnd, HDC hdcTarget,
+ const RECT *prcTarget, DWORD dwFormat,
+ ALF_Compat_BP_PAINTPARAMS *pPaintParams,
+ ALF_Compat_BP_ANIMATIONPARAMS *pAnimationParams,
+ HDC *phdcFrom, HDC *phdcTo)
+{
+ (void)hwnd; (void)hdcTarget; (void)prcTarget; (void)dwFormat;
+ (void)pPaintParams; (void)pAnimationParams; (void)phdcFrom; (void)phdcTo;
+
+ return NULL;
+}
+
+static ALF_Compat_HANIMATIONBUFFER WINAPI
+ALF_Compat_loadBeginBufferedAnimation(HWND hwnd, HDC hdcTarget,
+ const RECT *prcTarget, DWORD dwFormat,
+ ALF_Compat_BP_PAINTPARAMS *pPaintParams,
+ ALF_Compat_BP_ANIMATIONPARAMS *pAnimationParams,
+ HDC *phdcFrom, HDC *phdcTo)
+{
+ void *p = (void *)GetProcAddress(GetModuleHandleA("uxtheme.dll"), "BeginBufferedAnimation");
+ if (!p)
+ p = (void*)ALF_Compat_fallbackBeginBufferedAnimation;
+
+ InterlockedCompareExchangePointer((void**)&ALF_Compat_BeginBufferedAnimation, p, (void*)ALF_Compat_loadBeginBufferedAnimation);
+
+ return ALF_Compat_BeginBufferedAnimation(hwnd, hdcTarget, prcTarget, dwFormat, pPaintParams, pAnimationParams, phdcFrom, phdcTo);
+}
+
+static HRESULT WINAPI
+ALF_Compat_fallbackEndBufferedAnimation(ALF_Compat_HANIMATIONBUFFER hbpAnimation, BOOL fUpdateTarget)
+{
+ (void)hbpAnimation; (void)fUpdateTarget;
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+ALF_Compat_loadEndBufferedAnimation(ALF_Compat_HANIMATIONBUFFER hbpAnimation, BOOL fUpdateTarget)
+{
+ void *p = (void *)GetProcAddress(GetModuleHandleA("uxtheme.dll"), "EndBufferedAnimation");
+ if (!p)
+ p = (void*)ALF_Compat_fallbackEndBufferedAnimation;
+
+ InterlockedCompareExchangePointer((void**)&ALF_Compat_EndBufferedAnimation, p, (void*)ALF_Compat_loadEndBufferedAnimation);
+
+ return ALF_Compat_EndBufferedAnimation(hbpAnimation, fUpdateTarget);
+}
+
+static BOOL WINAPI
+ALF_Compat_fallbackBufferedPaintRenderAnimation(HWND hwnd, HDC hdc)
+{
+ (void)hwnd; (void)hdc;
+
+ return FALSE;
+}
+
+static BOOL WINAPI
+ALF_Compat_loadBufferedPaintRenderAnimation(HWND hwnd, HDC hdc)
+{
+ void *p = (void *)GetProcAddress(GetModuleHandleA("uxtheme.dll"), "BufferedPaintRenderAnimation");
+ if (!p)
+ p = (void *)ALF_Compat_fallbackBufferedPaintRenderAnimation;
+
+ InterlockedCompareExchangePointer((void**)&ALF_Compat_BufferedPaintRenderAnimation, p, (void*)ALF_Compat_loadBufferedPaintRenderAnimation);
+
+ return ALF_Compat_BufferedPaintRenderAnimation(hwnd, hdc);
+}
+
+static HRESULT WINAPI
+ALF_Compat_fallbackGetThemeTransitionDuration(HTHEME hTheme,
+ int iPartId,
+ int iStateIdFrom,
+ int iStateIdTo,
+ int iPropId,
+ DWORD *pdwDuration)
+{
+ (void)hTheme; (void)iPartId; (void)iStateIdFrom; (void)iStateIdTo; (void)iPropId; (void)pdwDuration;
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+ALF_Compat_loadGetThemeTransitionDuration(HTHEME hTheme,
+ int iPartId,
+ int iStateIdFrom,
+ int iStateIdTo,
+ int iPropId,
+ DWORD *pdwDuration)
+{
+ void *p = (void*)GetProcAddress(GetModuleHandleA("uxtheme.dll"), "GetThemeTransitionDuration");
+
+ if (!p)
+ p = (void*)ALF_Compat_fallbackGetThemeTransitionDuration;
+
+ InterlockedCompareExchangePointer((void**)&ALF_Compat_GetThemeTransitionDuration, p, (void*)ALF_Compat_loadGetThemeTransitionDuration);
+
+ return ALF_Compat_GetThemeTransitionDuration(hTheme, iPartId, iStateIdFrom, iStateIdTo, iPropId, pdwDuration);
+}
BOOL (WINAPI *ALF_Compat_IsAppThemed)(void) = ALF_Compat_loadIsAppThemed;
UINT (WINAPI *ALF_Compat_GetDpiForWindow)(HWND /*window*/) = ALF_Compat_loadGetDpiForWindow;
@@ -373,3 +713,19 @@ BOOL (WINAPI *ALF_Compat_SystemParametersInfoForDpi)(UINT,UINT,PVOID,UINT,UINT)
#else
BOOL (WINAPI *ALF_Compat_SystemParametersInfoForDpi)(UINT,UINT,PVOID,UINT,UINT) = ALF_Compat_fallbackSystemParametersInfoForDpi;
#endif
+
+HTHEME (WINAPI *ALF_Compat_OpenThemeData)(HWND, LPCWSTR) = ALF_Compat_loadOpenThemeData;
+HRESULT (WINAPI *ALF_Compat_CloseThemeData)(HTHEME) = ALF_Compat_loadCloseThemeData;
+BOOL (WINAPI *ALF_Compat_IsThemeBackgroundPartiallyTransparent)(HTHEME,int,int) = ALF_Compat_loadIsThemeBackgroundPartiallyTransparent;
+HRESULT (WINAPI *ALF_Compat_DrawThemeParentBackground)(HWND,HDC,RECT *) = ALF_Compat_loadDrawThemeParentBackground;
+HRESULT (WINAPI *ALF_Compat_DrawThemeBackground)(HTHEME, HDC, int, int, const RECT *, const RECT *) = ALF_Compat_loadDrawThemeBackground;
+HRESULT (WINAPI *ALF_Compat_GetThemeBackgroundContentRect)(HTHEME,HDC,int,int,const RECT *,RECT *) = ALF_Compat_loadGetThemeBackgroundContentRect;
+HRESULT (WINAPI *ALF_Compat_GetThemeTextExtent)(HTHEME,HDC,int,int,LPCWSTR,int,DWORD,const RECT *, RECT *) = ALF_Compat_loadGetThemeTextExtent;
+HRESULT (WINAPI *ALF_Compat_DrawThemeText)(HTHEME,HDC,int,int,LPCWSTR,int,DWORD,DWORD,const RECT *) = ALF_Compat_loadDrawThemeText;
+BOOL (WINAPI *ALF_Compat_TrackMouseEvent)(LPTRACKMOUSEEVENT tme) = ALF_Compat_loadTrackMouseEvent;
+HRESULT (WINAPI *ALF_Compat_BufferedPaintInit)(void) = ALF_Compat_loadBufferedPaintInit;
+HRESULT (WINAPI *ALF_Compat_BufferedPaintUnInit)(void) = ALF_Compat_loadBufferedPaintUnInit;
+ALF_Compat_HANIMATIONBUFFER (WINAPI *ALF_Compat_BeginBufferedAnimation)(HWND,HDC,const RECT *,DWORD,ALF_Compat_BP_PAINTPARAMS *,ALF_Compat_BP_ANIMATIONPARAMS *,HDC *,HDC *) = ALF_Compat_loadBeginBufferedAnimation;
+HRESULT (WINAPI *ALF_Compat_EndBufferedAnimation)(ALF_Compat_HANIMATIONBUFFER,BOOL) = ALF_Compat_loadEndBufferedAnimation;
+BOOL (WINAPI *ALF_Compat_BufferedPaintRenderAnimation)(HWND,HDC) = ALF_Compat_loadBufferedPaintRenderAnimation;
+HRESULT (WINAPI *ALF_Compat_GetThemeTransitionDuration)(HTHEME,int,int,int,int,DWORD*) = ALF_Compat_loadGetThemeTransitionDuration;
diff --git a/alf/alfcompat.h b/alf/alfcompat.h
index b0a43ec..e0faf62 100644
--- a/alf/alfcompat.h
+++ b/alf/alfcompat.h
@@ -2,6 +2,7 @@
#include <windows.h>
#include <rpc.h>
+#include <uxtheme.h>
#ifndef WM_DPICHANGED
#define WM_DPICHANGED 0x02E0
@@ -44,6 +45,32 @@ ALF_GetAveCharWidth(HDC hdc);
void
ALF_UniqueCounterValue(LONG_PTR *pCounterId, LONG_PTR *pCounterValue);
+typedef void *ALF_Compat_HANIMATIONBUFFER;
+
+typedef enum {
+ ALF_Compat_BPAS_NONE,
+ ALF_Compat_BPAS_LINEAR,
+ ALF_Compat_BPAS_CUBIC,
+ ALF_Compat_BPAS_SINE
+} ALF_Compat_BP_ANIMATIONSTYLE;
+
+typedef struct {
+ DWORD cbSize;
+ DWORD dwFlags;
+ ALF_Compat_BP_ANIMATIONSTYLE style;
+ DWORD dwDuration;
+} ALF_Compat_BP_ANIMATIONPARAMS;
+
+typedef struct {
+ DWORD cbSize;
+ DWORD dwFlags;
+ const RECT *prcExclude;
+ const BLENDFUNCTION *pBlendFunction;
+} ALF_Compat_BP_PAINTPARAMS;
+
+#ifndef TMT_TRANSITIONDURATION
+#define TMT_TRANSITIONDURATION 6000
+#endif
extern BOOL (WINAPI *ALF_Compat_IsAppThemed)(void);
extern UINT (WINAPI *ALF_Compat_GetDpiForWindow)(HWND);
@@ -53,3 +80,18 @@ extern BOOL (WINAPI *ALF_Compat_SetWindowSubclass)(HWND, ALF_COMPAT_SUBCLASSPROC
extern LRESULT (WINAPI *ALF_Compat_DefSubclassProc)(HWND, UINT, WPARAM, LPARAM);
extern BOOL (WINAPI *ALF_Compat_RemoveWindowSubclass)(HWND, ALF_COMPAT_SUBCLASSPROC, UINT_PTR);
extern BOOL (WINAPI *ALF_Compat_SystemParametersInfoForDpi)(UINT,UINT,PVOID,UINT,UINT);
+extern HTHEME (WINAPI *ALF_Compat_OpenThemeData)(HWND, LPCWSTR);
+extern HRESULT (WINAPI *ALF_Compat_CloseThemeData)(HTHEME);
+extern BOOL (WINAPI *ALF_Compat_IsThemeBackgroundPartiallyTransparent)(HTHEME,int,int);
+extern HRESULT (WINAPI *ALF_Compat_DrawThemeParentBackground)(HWND,HDC,RECT *);
+extern HRESULT (WINAPI *ALF_Compat_DrawThemeBackground)(HTHEME, HDC, int, int, const RECT *, const RECT *);
+extern HRESULT (WINAPI *ALF_Compat_GetThemeBackgroundContentRect)(HTHEME,HDC,int,int,const RECT *,RECT *);
+extern HRESULT (WINAPI *ALF_Compat_GetThemeTextExtent)(HTHEME,HDC,int,int,LPCWSTR,int,DWORD,const RECT *, RECT *);
+extern HRESULT (WINAPI *ALF_Compat_DrawThemeText)(HTHEME,HDC,int,int,LPCWSTR,int,DWORD,DWORD,const RECT *);
+extern BOOL (WINAPI *ALF_Compat_TrackMouseEvent)(LPTRACKMOUSEEVENT tme);
+extern HRESULT (WINAPI *ALF_Compat_BufferedPaintInit)(void);
+extern HRESULT (WINAPI *ALF_Compat_BufferedPaintUnInit)(void);
+extern ALF_Compat_HANIMATIONBUFFER (WINAPI *ALF_Compat_BeginBufferedAnimation)(HWND,HDC,const RECT *,DWORD,ALF_Compat_BP_PAINTPARAMS *,ALF_Compat_BP_ANIMATIONPARAMS *,HDC *,HDC *);
+extern HRESULT (WINAPI *ALF_Compat_EndBufferedAnimation)(ALF_Compat_HANIMATIONBUFFER,BOOL);
+extern BOOL (WINAPI *ALF_Compat_BufferedPaintRenderAnimation)(HWND,HDC);
+extern HRESULT (WINAPI *ALF_Compat_GetThemeTransitionDuration)(HTHEME,int,int,int,int,DWORD*);
diff --git a/widgetfactory.cpp b/widgetfactory.cpp
index e22f4d9..8f7961c 100644
--- a/widgetfactory.cpp
+++ b/widgetfactory.cpp
@@ -17,6 +17,8 @@ enum {
ID_BC1,
ID_BC2,
ID_BC3,
+ ID_BC4,
+ ID_BC5,
ID__MAX
};
@@ -164,6 +166,30 @@ WinMain
ALF_AddButton(panel, ID_BC3, 2, 0, TEXT("3"));
ALF_AddSpacer(panel, (WORD)-1, 0, 1, 5000, 0, ALF_VEXPAND);
+ HWND hwndBc4 = CreateWindowEx(0,
+ TEXT("BUTTON"),
+ TEXT("4"),
+ WS_CHILD | WS_TABSTOP | WS_VISIBLE | BS_PUSHBUTTON,
+ 0, 0, 100, 100,
+ panel,
+ (HMENU)(int)ID_BC4,
+ (HINSTANCE)GetWindowLongPtr(panel, GWLP_HINSTANCE),
+ NULL);
+ HWND hwndBc5 = CreateWindowEx(0,
+ TEXT("BUTTON"),
+ TEXT("5"),
+ WS_CHILD | WS_TABSTOP | WS_VISIBLE | BS_PUSHBUTTON,
+ 0, 0, 100, 100,
+ panel,
+ (HMENU)(int)ID_BC5,
+ (HINSTANCE)GetWindowLongPtr(panel, GWLP_HINSTANCE),
+ NULL);
+ EnableWindow(hwndBc5, FALSE);
+ ALF_AddWidget(panel, 3, 0, hwndBc4, 1000, 0, ALF_MESSAGEFONT);
+ ALF_AddWidget(panel, 4, 0, hwndBc5, 1000, 0, ALF_MESSAGEFONT);
+
+ EnableWindow(ALF_WidgetHwndById(win, ID_BC2), FALSE);
+
ALF_ApplyFonts(win);
ALF_RecalculateLayout(win);
ALF_SetDefaultButton(win, ID_B2);