Мой код, который использует UpdateLayeredWindow, не работает - PullRequest
1 голос
/ 17 марта 2012

Я попытался нарисовать неправильное окно с помощью UpdateLayeredWindow (), в msvc2008, xp sp3.
Вот часть моего кода:

//Add something(CreateWindowEx()):
hwndCyauWnd = CreateWindowEx(
    /*WS_EX_TOOLWINDOW |*/ WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_LAYERED,
    lpwsCyauClassName,
    lpwsCyauWndName,
    WS_CLIPSIBLINGS | WS_POPUP,
    GetSystemMetrics(SM_CXSCREEN)-320,
    GetSystemMetrics(SM_CYSCREEN)-232,
    320, 200,
    NULL,
    NULL,
    hInstance,
    NULL);

//Skip Lines
HDC hdcCyauWnd = GetDC(hwndCyauWnd);
HDC hdcBuffer = CreateCompatibleDC(hdcCyauWnd);
//HBITMAP hbmCyau = CreateCompatibleBitmap(hdcBuffer,120, 93);
//SelectObject(hdcBuffer, hbmCyau);

POINT ptZero = {0, 0};
POINT ptDrawPos = {0, 0};
RECT rctCyauWnd;
GetWindowRect(hwndCyauWnd, &rctCyauWnd);
SIZE szCyauWnd={rctCyauWnd.right - rctCyauWnd.left, rctCyauWnd.bottom - rctCyauWnd.top};
BLENDFUNCTION blendPixelFunction = { AC_SRC_OVER, 0, 100, AC_SRC_ALPHA};

Graphics gphCyauWnd(hdcBuffer);
Image imgCyau(L"surface0000.png");
gphCyauWnd.DrawImage(&imgCyau, 0, 0, 125, 93);

UpdateLayeredWindow(hwndCyauWnd,
    hdcCyauWnd, &ptZero,
    &szCyauWnd,
    hdcBuffer, &ptZero,
    0, //RGB(255, 255, 255),
    &blendPixelFunction,
    ULW_ALPHA);

while (GetMessage(&msg, NULL, 0, 0))    
{
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}
return msg.wParam;

Я пробовал несколько способов использовать эту функцию, но все не удалось, НИЧЕГО НЕ ПОЯВЛЯЕТСЯ на экране.
Может кто-нибудь сказать мне, что происходит и как это сделать?

Добавить:
Весь исходный файл был загружен в мой переходник , любой может редактировать, большое спасибо!(Теперь я стал слабым неудачником ...)

Ответы [ 2 ]

1 голос
/ 18 марта 2012

Если вы хотите, чтобы GDI + рисовал изображение с альфа-каналом, вы должны рисовать в растровом изображении, а не в HDC, и вы должны указать, что формат растрового изображения имеет альфа-канал.Чтобы сделать это с помощью HBITMAP, вы также должны указать GDI + на биты битовой карты.

Примерно так:

BITMAPINFOHEADER bih;
HBITMAP hbmp;
HDC hdc;
void *bits;

bih.biSize = sizeof(bih);
bih.biWidth = width;
bih.biHeight = -height;
bih.biPlanes = 1;
bih.biBitCount = 32;
bih.biCompression = BI_RGB;
bih.biSizeImage = 0;
bih.biXPelsPerMeter = 0;
bih.biYPelsPerMeter = 0;
bih.biClrUsed = 0;
bih.biClrImportant = 0;

hdc = CreateCompatibleDC(NULL);

hbmp = CreateDIBSection(hdc, (BITMAPINFO*)&bih, DIB_RGB_COLORS, &bits, NULL, 0);

Bitmap bitmap(width, height, 0, PixelFormat32bppPARGB, bits);

Graphics graphics(bitmap);

graphics->DrawWhatever(...);

graphics->Flush();

SelectObject(hdc, hbitmap);

UpdateLayeredWindow(hwnd, hdc, ...
1 голос
/ 17 марта 2012

Вы смешали GDI и GDI +, что не очень хорошая идея. Вот рабочий пример:

hWnd = CreateWindowEx(WS_EX_LAYERED, szWindowClass, szTitle, 0,
     CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

// Load PNG
CImage img;
img.Load("BACKGR.png");
// Get image sizes
int nWidth = img.GetWidth();
int nHeight = img.GetHeight();
// Create memory DC
HDC hdcScreen = GetDC(NULL);
HDC hDC = CreateCompatibleDC(hdcScreen);
// Create memory bitmap
HBITMAP hBmp = CreateCompatibleBitmap(hdcScreen, nWidth, nHeight);
HBITMAP hBmpOld = (HBITMAP)SelectObject(hDC, hBmp);
// Draw image to memory bitmap (currently selected in memory DC)
img.Draw(hDC, 0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight);

// Call UpdateLayeredWindow
BLENDFUNCTION blend = {0};
blend.BlendOp = AC_SRC_OVER;
blend.SourceConstantAlpha = 128;// half transparent
blend.AlphaFormat = AC_SRC_ALPHA;
POINT ptLocation = {0, 0};
SIZE szWnd = {nWidth, nHeight};
POINT ptSrc = {0, 0};
UpdateLayeredWindow(hWnd, hdcScreen, &ptLocation, &szWnd, hDC, &ptSrc, 0, &blend, ULW_ALPHA);
ShowWindow(hWnd, SW_SHOW);

SelectObject(hDC, hBmpOld);
DeleteObject(hBmp);
DeleteDC(hDC);
ReleaseDC(NULL, hdcScreen);
...