I have a dll library that deals with windows: you can simply create windows, draw graphics, etc. Also this library provides you to make blurred windows for Win7 and Win10.
I have two almost same builds of library - one , older without sources, and one newer with sources.
I am writing some app in Win10 and have been using old library, but now decided to compile new build. It works almost the same, as I said, except blur - it doesn’t work. Here is the client code:
HWND hwnd; // here stored window created by library function
struct ACCENTPOLICY
{
int na;
int nf;
int nc;
int nA;
};
struct WINCOMPATTRDATA
{
int na;
PVOID pd;
ULONG ul;
};
const HINSTANCE hm = LoadLibrary(L"user32.dll");
if (hm)
{
typedef BOOL(WINAPI*pSetWindowCompositionAttribute)(HWND, WINCOMPATTRDATA*);
const pSetWindowCompositionAttribute SetWindowCompositionAttribute = (pSetWindowCompositionAttribute)GetProcAddress(hm, "SetWindowCompositionAttribute");
if (SetWindowCompositionAttribute)
{
ACCENTPOLICY policy = { 3, 0, 0, 0 }; // and even works 4,0,155,0 (Acrylic blur)
WINCOMPATTRDATA data = { 19, &policy,sizeof(ACCENTPOLICY) };
SetWindowCompositionAttribute(hwnd, &data);
}
FreeLibrary(hm);
}
It completely works in old library and doesn’t work in new - window is not transparent at all, and hence no blur.
Details
I am calling function from my library, that creates window, returns hwnd, then set background color with alfa, and then run code above. Nothing else.
In sources I have, window creates as CreateWindowEx
without WS_EX_LAYERED
. I tried to add this flag, add DwmBlurBehindWindow
call, add SetLayeredWindowAttribute
with LWA_ALPHA
or LWA_COLORKEY
, but the only result I got - transparency, without any blur.
Here is some code from WM_PAINT
:
hdc = BeginPaint(hwnd, &ps);
hdcc = CreateCompatibleDC(hdc);
BITMAPINFO bmi;
LPBYTE bits;
ZeroMemory(&bmi, sizeof(bmi));
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = ps.rcPaint.right - ps.rcPaint.left;
bmi.bmiHeader.biHeight = ps.rcPaint.bottom - ps.rcPaint.top;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 32;
bmi.bmiHeader.biCompression = BI_RGB;
bm = CreateDIBSection(hdcc, &bmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
//All draws here. The first one is Gdi+ background draw with alfa brush
SetStretchBltMode(hdc, COLORONCOLOR);
SetStretchBltMode(hdcc, COLORONCOLOR);
StretchBlt(hdc, ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right - ps.rcPaint.left, ps.rcPaint.bottom - ps.rcPaint.top, hdcc, 0, 0, ps.rcPaint.right - ps.rcPaint.left, ps.rcPaint.bottom - ps.rcPaint.top, SRCCOPY);
EndPaint(hwnd,&ps);
What did I miss?
Old library, same code in client:
New library, DwmBlurBehindWindow
call, setting WS_EX_LAYERED
or SetLayeredWindowAttribute
calling doesn’t make any effect, same code in client:
New library, without DwmBlurBehindWindow
, same code in client:
I do not really understand what I did, but now it works.
First of all, I should say, that library provides not just function, but an interface - abstract class.
The second one - HWND of created window is actually doesn’t returns, because function that creates window is void. I found window by FindWindow()
.
GetLastError()
after SetWindowCompositionAttribute()
returned 6, but now, if when it works it returns 10 - ERROR_BAD_ENVIRONMENT
10 (0xA)
The environment is incorrect.
Also I was getting crashes trying to call MessageBox()
to display the error code. The program crashed even if I just check whether hwnd
equals to NULL
or not.
Summary
As I mentioned in question, I decided to make new build, because I wanted sone new features. Seems, the abstract interface class in current fresh dll is not the same as in client, but in the old one dll is. I think the problem is in this.