I have a layered window in my program and it seems(visually) to work fine, but the return code from UpdateLayeredWindow
is supposed to be a non-zero value on success. In my case, it is 0, and GetLastError
returns 87, that is for an incorrect parameter. Can someone please tell me if there is anything wrong with my setup? Here is the complete function, window styles are WS_EX_LAYERED|WS_EX_TOPMOST
and WS_POPUP
.
bool SplashScreen(HWND hwnd, HINSTANCE m_hinstance)
{
HBITMAP hBitmap = (HBITMAP)LoadImage(m_hinstance, "splash.bmp", IMAGE_BITMAP, 640, 640, LR_LOADFROMFILE);
PAINTSTRUCT ps;
HDC hdc;
BITMAP bitmap;
HDC hdcMem;
HGDIOBJ oldBitmap;
int result=0;
if(!SetLayeredWindowAttributes(hwnd, 0, (255 * 100) / 100, LWA_ALPHA))
{
char msg[255];
sprintf(msg,"Error SetLayeredWindowAttributes: %d",GetLastError());
MessageBox(hwnd,msg,"System",MB_OK);
return false;
}
hdc = BeginPaint(hwnd, &ps);
if(!hdc)
{
char msg[255];
sprintf(msg,"Error BeginPaint: %d",GetLastError());
MessageBox(hwnd,msg,"System",MB_OK);
return false;
}
hdcMem = CreateCompatibleDC(hdc);
if(!hdcMem)
{
char msg[255];
sprintf(msg,"Error CreateCompatibleDC: %d",GetLastError());
MessageBox(hwnd,msg,"System",MB_OK);
return false;
}
oldBitmap = SelectObject(hdcMem, hBitmap);
GetObject(hBitmap, sizeof(bitmap), &bitmap);
result=BitBlt(hdc, 0, 0, 640, 640, hdcMem, 0, 0, SRCCOPY);
if(result==0)
{
char msg[255];
sprintf(msg,"Error BitBlt: %d",GetLastError());
MessageBox(hwnd,msg,"System",MB_OK);
return false;
}
BLENDFUNCTION blend = { 0 };
blend.BlendOp = AC_SRC_OVER;
blend.SourceConstantAlpha = 255;
blend.AlphaFormat = AC_SRC_ALPHA;
result=UpdateLayeredWindow(hwnd,GetDC(NULL),NULL,NULL,hdcMem,NULL, RGB(0,0,0),&blend, ULW_ALPHA);// Returns non-zero on success(!), in reality works when 0 is returned.
if(result==0)
{
char msg[255];
sprintf(msg,"Error UpdateLayeredWindow: %d",GetLastError());// Error UpdateLayeredWindow: 87
MessageBox(hwnd,msg,"System",MB_OK);
return false;
}
result=SetLayeredWindowAttributes(hwnd, RGB(255,255,255), 0, ULW_COLORKEY);
if(result==0)
{
char msg[255];
sprintf(msg,"Error SetLayeredWindowAttributes: %d",GetLastError());
MessageBox(hwnd,msg,"System",MB_OK);
return false;
}
result=EndPaint(hwnd, &ps);
if(result==0)
{
char msg[255];
sprintf(msg,"Error EndPaint: %d",GetLastError());
MessageBox(hwnd,msg,"System",MB_OK);
return false;
}
SelectObject(hdcMem, oldBitmap);
DeleteDC(hdc);
DeleteObject(hdcMem);
return true;
}
You are calling
SetLayeredWindowAttributes()
andUpdateLayeredWindow()
on the same HWND. That will not work, and the documentation is very clear on that:http://msdn.microsoft.com/en-us/library/windows/desktop/ms633540(v=vs.85).aspx
Do not use
SetLayeredWindowAttributes()
andUpdateLayeredWindow()
together. They are very different methodologies. Either useSetLayeredWindowAttributes()
with traditionalWM_PAINT
drawing, or useUpdateLayeredWindow()
with an in-memory bitmap. Do not use both. Based on what you have shown, you should be usingUpdateLayeredWindow()
by itself. It will set a bitmap as the window contents and set the window's transparency/alpha at the same time.And do not use
Begin/EndPaint()
outside of aWM_PAINT
handler.