diff --git a/_doc/misctests/windwmblurbehindtest.cpp b/_doc/misctests/windwmblurbehindtest.cpp new file mode 100644 index 00000000..1e469ed1 --- /dev/null +++ b/_doc/misctests/windwmblurbehindtest.cpp @@ -0,0 +1,222 @@ +// 31 august 2019 +#define UNICODE +#define _UNICODE +#define STRICT +#define STRICT_TYPED_ITEMIDS +#define WINVER 0x0600 /* from Microsoft's winnls.h */ +#define _WIN32_WINNT 0x0600 +#define _WIN32_WINDOWS 0x0600 /* from Microsoft's pdh.h */ +#define _WIN32_IE 0x0700 +#define NTDDI_VERSION 0x06000000 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// cl windwmblurbehindtest.cpp -MT -link user32.lib kernel32.lib gdi32.lib comctl32.lib uxtheme.lib msimg32.lib dwmapi.lib windows.res + +void diele(const char *func) +{ + DWORD le; + + le = GetLastError(); + fprintf(stderr, "%s: %I32u\n", func, le); + exit(EXIT_FAILURE); +} + +void diehr(const char *func, HRESULT hr) +{ + fprintf(stderr, "%s: 0x%08I32X\n", func, hr); + exit(EXIT_FAILURE); +} + +// TODO if we merge this into libui proper, this will need to be deduplicated +static inline HRESULT lastErrorToHRESULT(DWORD lastError) +{ + if (lastError == 0) + return E_FAIL; + return HRESULT_FROM_WIN32(lastError); +} + +HINSTANCE hInstance; +HRGN rgn; +BOOL created = FALSE; +HBRUSH opaquebrush; + +#define OURWIDTH 320 +#define OURHEIGHT 240 + +void onWM_CREATE(HWND hwnd) +{ + DWM_BLURBEHIND dbb; + HRESULT hr = S_OK; + + rgn = CreateRectRgn(0, 0, OURWIDTH / 2, OURHEIGHT); + if (rgn == NULL) + diele("CreateRectRgn()"); + ZeroMemory(&dbb, sizeof (DWM_BLURBEHIND)); + dbb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION; + dbb.fEnable = TRUE; + dbb.hRgnBlur = NULL;//rgn; + hr = DwmEnableBlurBehindWindow(hwnd, &dbb); + if (hr != S_OK) + diehr("DwmEnableBlurBehindWindow()", hr); +CreateWindowExW(0, +L"BUTTON",L"Hello", +WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, +3*OURWIDTH/4,150, +OURWIDTH/6,25, +hwnd,NULL,hInstance,NULL); +SetWindowTheme(CreateWindowExW(0, +L"BUTTON",L"Hello", +WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, +3*OURWIDTH/4,200, +OURWIDTH/6,25, +hwnd,NULL,hInstance,NULL),L"",L""); +} + +void onWM_PAINT(HWND hwnd) +{ + HDC dc; + PAINTSTRUCT ps; + RECT r; + + ZeroMemory(&ps, sizeof (PAINTSTRUCT)); + dc = BeginPaint(hwnd, &ps); + if (dc == NULL) + diele("BeginPaint()"); + // First, fill with BLACK_BRUSH to satisfy the DWM + r.left = 0; + r.top = 0; + r.right = OURWIDTH; + r.bottom = OURHEIGHT; + // TODO check error + FillRect(dc, &r, (HBRUSH) GetStockObject(BLACK_BRUSH)); +static DWORD c=GetSysColor(COLOR_BTNFACE); +BYTE x[4]; +x[3]=0xFF; +x[2]=GetRValue(c); +x[1]=GetGValue(c); +x[0]=GetBValue(c); +static HBITMAP b=CreateBitmap(1,1,1,32,x); +if(b==NULL)diele("CreateBitmap()"); +HDC dc2=CreateCompatibleDC(dc); +if(dc==NULL)diele("CreateCompatibleDC()"); +HGDIOBJ prev=SelectObject(dc2,b); +StretchBlt(dc,OURWIDTH/2,0,OURWIDTH/2,OURHEIGHT, +dc2,0,0,1,1,SRCCOPY); +SelectObject(dc2,prev); +DeleteDC(dc2); +DeleteObject(b); +r.left=3*OURWIDTH/4; +r.top=100; +r.right=7*OURWIDTH/8; +r.bottom=25; +auto m=SetBkMode(dc,TRANSPARENT); +TextOutW(dc,r.left,r.top,L"Hello",5); +SetBkMode(dc, m); + EndPaint(hwnd, &ps); +} + +LRESULT CALLBACK wndproc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) { + case WM_CREATE: + onWM_CREATE(hwnd); + break; + case WM_PAINT: + onWM_PAINT(hwnd); + break; + case WM_CLOSE: + PostQuitMessage(0); + break; + } + return DefWindowProcW(hwnd, uMsg, wParam, lParam); +} + +EXTERN_C IMAGE_DOS_HEADER __ImageBase; + +int main(int argc, char *argv[]) +{ + STARTUPINFOW si; + int nCmdShow; + INITCOMMONCONTROLSEX icc; + HICON hDefaultIcon; + HCURSOR hDefaultCursor; + DWORD dwStyle, dwExStyle; + RECT r; + WNDCLASSW wc; + HWND mainwin; + MSG msg; + HRESULT hr; + + hInstance = (HINSTANCE) (&__ImageBase); + nCmdShow = SW_SHOWDEFAULT; + GetStartupInfoW(&si); + if ((si.dwFlags & STARTF_USESHOWWINDOW) != 0) + nCmdShow = si.wShowWindow; + + ZeroMemory(&icc, sizeof (INITCOMMONCONTROLSEX)); + icc.dwSize = sizeof (INITCOMMONCONTROLSEX); + icc.dwICC = ICC_STANDARD_CLASSES | ICC_BAR_CLASSES | ICC_COOL_CLASSES; + if (InitCommonControlsEx(&icc) == 0) + diele("InitCommonControlsEx()"); + + hDefaultIcon = LoadIconW(NULL, IDI_APPLICATION); + if (hDefaultIcon == NULL) + diele("LoadIconW(IDI_APPLICATION)"); + hDefaultCursor = LoadCursorW(NULL, IDC_ARROW); + if (hDefaultCursor == NULL) + diele("LoadCursorW(IDC_ARROW)"); + + ZeroMemory(&wc, sizeof (WNDCLASSW)); + wc.lpszClassName = L"mainwin"; + wc.lpfnWndProc = wndproc; + wc.hInstance = hInstance; + wc.hIcon = hDefaultIcon; + wc.hCursor = hDefaultCursor; + wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1); + if (RegisterClassW(&wc) == 0) + diele("RegisterClassW()"); + + dwStyle = WS_OVERLAPPEDWINDOW & ~(WS_THICKFRAME | WS_MAXIMIZEBOX); + dwExStyle = 0; + r.left = 0; + r.top = 0; + r.right = OURWIDTH; + r.bottom = OURHEIGHT; + if (AdjustWindowRectEx(&r, dwStyle, FALSE, dwExStyle) == 0) + diele("AdjustWindowRectEx()"); + mainwin = CreateWindowExW(dwExStyle, + L"mainwin", L"Main Window", + dwStyle, + CW_USEDEFAULT, CW_USEDEFAULT, + r.right - r.left, r.bottom - r.top, + NULL, NULL, hInstance, NULL); + if (mainwin == NULL) + diele("CreateWindowExW(L\"mainwin\")"); + + ShowWindow(mainwin, nCmdShow); + if (UpdateWindow(mainwin) == 0) + diele("UpdateWindow()"); + + for (;;) { + int res; + + res = GetMessageW(&msg, NULL, 0, 0); + if (res < 0) + diele("GetMessageW()"); + if (res == 0) + break; + if (IsDialogMessageW(mainwin, &msg) == 0) { + TranslateMessage(&msg); + DispatchMessageW(&msg); + } + } + return 0; +}