More progress with the DWM blur-behind stuff. This is increasingly complicated; I can get rid of the alpha-blending OR keep the Aero animations...

This commit is contained in:
Pietro Gagliardi 2019-09-01 18:59:19 -04:00
parent 5c65e6d7fa
commit 6801cf5282
2 changed files with 135 additions and 35 deletions

View File

@ -43,6 +43,65 @@ static inline HRESULT lastErrorToHRESULT(DWORD lastError)
return HRESULT_FROM_WIN32(lastError); return HRESULT_FROM_WIN32(lastError);
} }
static void paintIntoBuffer(HWND hwnd, UINT uMsg, HDC dc, RECT *r)
{
HPAINTBUFFER bbuf;
HDC bdc;
HRESULT hr;
// TODO begin check errors
bbuf = BeginBufferedPaint(dc, r, BPBF_TOPDOWNDIB, NULL, &bdc);
if (uMsg == WM_PAINT)
SendMessageW(hwnd, WM_PRINTCLIENT, (WPARAM) bdc, PRF_CLIENT | PRF_ERASEBKGND);
else
SendMessageW(hwnd, WM_PRINT, (WPARAM) bdc, PRF_ERASEBKGND | PRF_NONCLIENT);
hr = BufferedPaintSetAlpha(bbuf, NULL, 255);
hr = EndBufferedPaint(bbuf, TRUE);
// TODO end check errors
}
static LRESULT CALLBACK buttonSubProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
PAINTSTRUCT ps;
HDC dc;
RECT r;
switch (uMsg) {
case WM_PAINT:
// TODO begin check errors
#if 0
dc = BeginPaint(hwnd, &ps);
// paintIntoBuffer(hwnd, uMsg, dc, &(ps.rcPaint));
DefSubclassProc(hwnd, uMsg, (WPARAM) dc, lParam);
EndPaint(hwnd, &ps);
#else
DefSubclassProc(hwnd, uMsg, wParam, lParam);
if (0) {
RECT r;
GetClientRect(hwnd, &r);
MapWindowRect(hwnd, GetParent(hwnd), &r);
InvalidateRect(GetParent(hwnd), &r, TRUE);
}
#endif
// TODO end check errors
return 0;
//TODO case WM_NCPAINT:
// TODO begin check errors
dc = GetDCEx(hwnd, (HRGN) wParam, DCX_WINDOW | DCX_INTERSECTRGN);
GetRgnBox((HRGN) wParam, &r);
paintIntoBuffer(hwnd, uMsg, dc, &r);
ReleaseDC(hwnd, dc);
// TODO end check errors
return 0;
case WM_NCDESTROY:
if (RemoveWindowSubclass(hwnd, buttonSubProc, uIdSubclass) == FALSE)
diele("RemoveWindowSubclass()");
break;
}
return DefSubclassProc(hwnd, uMsg, wParam, lParam);
}
HINSTANCE hInstance; HINSTANCE hInstance;
HRGN rgn; HRGN rgn;
BOOL created = FALSE; BOOL created = FALSE;
@ -66,30 +125,30 @@ void onWM_CREATE(HWND hwnd)
hr = DwmEnableBlurBehindWindow(hwnd, &dbb); hr = DwmEnableBlurBehindWindow(hwnd, &dbb);
if (hr != S_OK) if (hr != S_OK)
diehr("DwmEnableBlurBehindWindow()", hr); diehr("DwmEnableBlurBehindWindow()", hr);
CreateWindowExW(0, HWND w1=CreateWindowExW(0,
L"BUTTON",L"Hello", L"BUTTON",L"Hello",
WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,
3*OURWIDTH/4,150, 3*OURWIDTH/4,150,
OURWIDTH/6,25, OURWIDTH/6,25,
hwnd,NULL,hInstance,NULL); hwnd,NULL,hInstance,NULL);
SetWindowTheme(CreateWindowExW(0, //SetWindowSubclass(w1, buttonSubProc, 0, 0);
HWND w2=CreateWindowExW(0,
L"BUTTON",L"Hello", L"BUTTON",L"Hello",
WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,
3*OURWIDTH/4,200, 3*OURWIDTH/4,200,
OURWIDTH/6,25, OURWIDTH/6,25,
hwnd,NULL,hInstance,NULL),L"",L""); hwnd,NULL,hInstance,NULL);
SetWindowTheme(w2,L"",L"");
//SetWindowSubclass(w2, buttonSubProc, 0, 0);
} }
void onWM_PAINT(HWND hwnd) void doPaint(HWND hwnd, HDC dc, RECT *rcPaint)
{ {
HDC dc; RECT r, r2;
PAINTSTRUCT ps; HPAINTBUFFER bbuf;
RECT r; HDC bdc;
HRESULT hr;
ZeroMemory(&ps, sizeof (PAINTSTRUCT));
dc = BeginPaint(hwnd, &ps);
if (dc == NULL)
diele("BeginPaint()");
// First, fill with BLACK_BRUSH to satisfy the DWM // First, fill with BLACK_BRUSH to satisfy the DWM
r.left = 0; r.left = 0;
r.top = 0; r.top = 0;
@ -97,29 +156,49 @@ void onWM_PAINT(HWND hwnd)
r.bottom = OURHEIGHT; r.bottom = OURHEIGHT;
// TODO check error // TODO check error
FillRect(dc, &r, (HBRUSH) GetStockObject(BLACK_BRUSH)); FillRect(dc, &r, (HBRUSH) GetStockObject(BLACK_BRUSH));
static DWORD c=GetSysColor(COLOR_BTNFACE);
BYTE x[4]; r.left = OURWIDTH / 2;
x[3]=0xFF; // TODO check error
x[2]=GetRValue(c); IntersectRect(&r2, &r, rcPaint);
x[1]=GetGValue(c); bbuf = BeginBufferedPaint(dc, &r, BPBF_TOPDOWNDIB, NULL, &bdc);
x[0]=GetBValue(c); if (bbuf == NULL)
static HBITMAP b=CreateBitmap(1,1,1,32,x); diele("BeginBufferedPaint()");
if(b==NULL)diele("CreateBitmap()"); // TODO start check errors
HDC dc2=CreateCompatibleDC(dc); FillRect(bdc, &r, GetSysColorBrush(COLOR_BTNFACE));
if(dc==NULL)diele("CreateCompatibleDC()"); r.left = 3 * OURWIDTH / 4;
HGDIOBJ prev=SelectObject(dc2,b); r.top = 100;
StretchBlt(dc,OURWIDTH/2,0,OURWIDTH/2,OURHEIGHT, r.right = 7 * OURWIDTH / 8;
dc2,0,0,1,1,SRCCOPY); r.bottom = 25;
SelectObject(dc2,prev); auto m = SetBkMode(bdc,TRANSPARENT);
DeleteDC(dc2); TextOutW(bdc, r.left, r.top, L"Hello", 5);
DeleteObject(b); SetBkMode(bdc, m);
r.left=3*OURWIDTH/4; // TODO end check errors
r.top=100; hr = BufferedPaintSetAlpha(bbuf, NULL, 255);
r.right=7*OURWIDTH/8; if (hr != S_OK)
r.bottom=25; diehr("BufferedPaintSetAlpha()", hr);
auto m=SetBkMode(dc,TRANSPARENT); hr = EndBufferedPaint(bbuf, TRUE);
TextOutW(dc,r.left,r.top,L"Hello",5); if (hr != S_OK)
SetBkMode(dc, m); diehr("EndBufferedPaint()", hr);
}
void onWM_PAINT(HWND hwnd, WPARAM wParam)
{
HDC dc;
PAINTSTRUCT ps;
RECT rcPaint;
if (wParam != 0) {
// TODO check errors
GetClientRect(hwnd, &rcPaint);
doPaint(hwnd, (HDC) wParam, &rcPaint);
return;
}
ZeroMemory(&ps, sizeof (PAINTSTRUCT));
dc = BeginPaint(hwnd, &ps);
if (dc == NULL)
diele("BeginPaint()");
doPaint(hwnd, dc, &(ps.rcPaint));
EndPaint(hwnd, &ps); EndPaint(hwnd, &ps);
} }
@ -130,7 +209,9 @@ LRESULT CALLBACK wndproc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
onWM_CREATE(hwnd); onWM_CREATE(hwnd);
break; break;
case WM_PAINT: case WM_PAINT:
onWM_PAINT(hwnd); // case WM_PRINTCLIENT:
// case WM_ERASEBKGND:
onWM_PAINT(hwnd, wParam);
break; break;
case WM_CLOSE: case WM_CLOSE:
PostQuitMessage(0); PostQuitMessage(0);
@ -174,6 +255,10 @@ int main(int argc, char *argv[])
if (hDefaultCursor == NULL) if (hDefaultCursor == NULL)
diele("LoadCursorW(IDC_ARROW)"); diele("LoadCursorW(IDC_ARROW)");
hr = BufferedPaintInit();
if (hr != S_OK)
diehr("BufferedPaintInit()", hr);
ZeroMemory(&wc, sizeof (WNDCLASSW)); ZeroMemory(&wc, sizeof (WNDCLASSW));
wc.lpszClassName = L"mainwin"; wc.lpszClassName = L"mainwin";
wc.lpfnWndProc = wndproc; wc.lpfnWndProc = wndproc;
@ -218,5 +303,6 @@ int main(int argc, char *argv[])
DispatchMessageW(&msg); DispatchMessageW(&msg);
} }
} }
BufferedPaintUnInit();
return 0; return 0;
} }

View File

@ -0,0 +1,14 @@
http://www.danielmoth.com/Blog/Vista-Glass-Answers-And-DwmEnableBlurBehindWindow.aspx
https://weblogs.asp.net/kennykerr/Windows-Vista-for-Developers-_1320_-Part-3-_1320_-The-Desktop-Window-Manager
https://stackoverflow.com/questions/7981322/strategy-for-creating-a-layered-window-with-child-windows-controls
https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-printwindow
http://www.danielmoth.com/Blog/glass-nugget.aspx
https://weblogs.asp.net/kennykerr/controls-and-the-desktop-window-manager
https://docs.microsoft.com/en-us/windows/win32/api/uxtheme/nf-uxtheme-bufferedpaintinit
https://docs.microsoft.com/en-us/windows/win32/api/uxtheme/nf-uxtheme-beginbufferedpaint
https://docs.microsoft.com/en-us/windows/win32/api/uxtheme/nf-uxtheme-bufferedpaintsetalpha
https://docs.microsoft.com/en-us/windows/win32/api/uxtheme/nf-uxtheme-endbufferedpaint
https://docs.microsoft.com/en-us/windows/win32/api/uxtheme/nf-uxtheme-bufferedpaintuninit
https://weblogs.asp.net/kennykerr/Windows-Vista-for-Developers-_1320_-Part-1-_1320_-Aero-Wizards
https://weblogs.asp.net/kennykerr/Windows-Vista-for-Developers-_1320_-Part-2-_1320_-Task-Dialogs-in-Depth
https://weblogs.asp.net/kennykerr/Windows-Vista-for-Developers-_1320_-Part-6-_1320_-The-New-File-Dialogs