Windows API: UpdateLayeredWindow возвращает значения

У меня есть многоуровневое окно в моей программе, и кажется (визуально), чтобы работать нормально, но код возврата от UpdateLayeredWindow должен быть ненулевым значением в случае успеха. В моем случае это 0, а GetLastError возвращает 87, то есть для неверного параметра. Может кто-нибудь сказать мне, если что-то не так с моей настройкой? Вот полная функция, стили окна WS_EX_LAYERED|WS_EX_TOPMOST а также 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;
}

2

Решение

Ты звонишь SetLayeredWindowAttributes() а также UpdateLayeredWindow() на том же HWND. Это не сработает, и в документации очень ясно об этом:

http://msdn.microsoft.com/en-us/library/windows/desktop/ms633540(v=vs.85).aspx

Обратите внимание, что как только SetLayeredWindowAttributes был вызван для многоуровневого окна, последующие вызовы UpdateLayeredWindow завершатся неудачно, пока бит стиля расслоения не будет очищен и установлен снова.

Не использовать SetLayeredWindowAttributes() а также UpdateLayeredWindow() все вместе. Это очень разные методологии. Либо использовать SetLayeredWindowAttributes() с традиционными WM_PAINT рисование или использование UpdateLayeredWindow() с растровым изображением в памяти. Не используйте оба. Исходя из того, что вы показали, вы должны использовать UpdateLayeredWindow() само собой. Он установит растровое изображение в качестве содержимого окна и одновременно установит прозрачность / альфа-окно.

И не использовать Begin/EndPaint() вне WM_PAINT обработчик.

6

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]