0

我想创建一个分层窗口,其大小大于其内容(hdcSrc)的大小。例如,窗口是 900x900,我们可以将 300x300 的图像放置在我们想要的任何位置,而窗口的其余部分是透明的。

到目前为止,这是我的代码:

#include <Windows.h>
#include <string>

#include <objidl.h>
#include <gdiplus.h>
using namespace Gdiplus;
#pragma comment( lib, "Gdiplus.lib" )

HWND hwnd;

int screenWidth = GetSystemMetrics(SM_CXSCREEN);
int screenHeight = GetSystemMetrics(SM_CYSCREEN);

void updateTestWindow();

LRESULT CALLBACK windowProcedure(HWND hwnd, UINT message,
    WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    default:
        return DefWindowProc(hwnd, message, wParam, lParam);
    }
}

INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, PSTR, INT iCmdShow)
{
    MSG msg;

    // GDI+ elements
    GdiplusStartupInput gdiplusStartupInput;
    ULONG_PTR gdiplusToken;

    // Initialize GDI+.
    GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

    // Register Window Class

    WNDCLASS testWindowClass;

    testWindowClass.lpszClassName = TEXT("TestWindow");
    testWindowClass.hInstance = hInstance;
    testWindowClass.style = CS_HREDRAW | CS_VREDRAW;
    testWindowClass.lpfnWndProc = windowProcedure;
    testWindowClass.hIcon = 0;
    testWindowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    testWindowClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    testWindowClass.cbClsExtra = 0;
    testWindowClass.cbWndExtra = 0;
    testWindowClass.lpszMenuName = NULL;

    RegisterClass(&testWindowClass);

    // Create a layered window

    hwnd = CreateWindowEx(
        WS_EX_LAYERED,
        TEXT("TestWindow"), // window class name
        TEXT("TestWindow"), // window caption
        WS_POPUP,           // window style
        0,      // initial x position
        0,      // initial y position
        screenWidth,                    // initial x size
        screenHeight,                   // initial y size
        NULL,               // parent window handle
        NULL,               // window menu handle
        hInstance,          // program instance handle
        NULL);              // creation parameters

    ShowWindow(hwnd, iCmdShow);

    
    // Update the layered window using a custom function
    updateTestWindow();




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

    return 0;
}


void updateTestWindow()
{
    // Let's imagine that in reality we are drawing an image, but to test it, just draw a rectangle
    int imageWidth = 300;
    int imageHeight = 300;

    HDC screenDC = GetDC(NULL);

    // Create a DC for drawing
    HDC drawingDC = CreateCompatibleDC(screenDC);

    // Create a new bitmap for drawing on it
    HBITMAP newBitmap = CreateCompatibleBitmap(screenDC, imageWidth, imageHeight);

    // Select the new bitmap to draw on it and save the old one
    HBITMAP oldBitmap = (HBITMAP)SelectObject(drawingDC, newBitmap);

    // Create graphics object
    Graphics graphics(drawingDC);

    // Draw a rectangle
    Pen redPen(Color(255, 255, 0, 0), 15);
    Rect windowRect(0, 0, imageWidth, imageWidth);
    graphics.DrawRectangle(&redPen, windowRect);

    // The position of the layered window
    POINT windowPosition = { 0, 0 };
    
    // The size of the layered window   
    SIZE windowSize = { imageWidth, imageHeight };    // <----------------------------------!!!!

    POINT drawingDCPosition = { 0,0 };

    // Create a blend function
    BLENDFUNCTION blend = { 0 };
    blend.BlendOp = AC_SRC_OVER;
    blend.SourceConstantAlpha = 255;
    blend.AlphaFormat = AC_SRC_ALPHA;

    // Call UpdateLayeredWindow
    UpdateLayeredWindow(hwnd, screenDC, &windowPosition, &windowSize,
        drawingDC, &drawingDCPosition, 0, &blend, ULW_ALPHA);

    // Clean up
    SelectObject(drawingDC, oldBitmap);
    DeleteObject(newBitmap);
    DeleteDC(drawingDC);
    ReleaseDC(NULL, screenDC);
}

这将创建一个与在其上绘制的图像大小完全相同的窗口。我们可以减小窗口大小:SIZE windowSize = { imageWidth-100, imageHeight-100 };窗口将按预期绘制 - 尺寸更小,而图像大小相同但现在被剪裁(在这种情况下,矩形被剪裁)。

但是,如果我们想实现我在开始时描述的内容,那SIZE windowSize = { imageWidth+100, imageHeight+100 };是行不通的。该窗口根本没有呈现,但它打开了(窗口任务栏图标可见)。

我可能还不能完全理解分层窗口是如何工作的,这就是为什么我不明白为什么在这个例子中它没有被渲染。

有可能创建这样一个分层的窗口吗?如果是,那怎么办?

或者也许这根本不是我应该做的事情?

就像一个注释:我想这样做的原因是使用分层窗口作为一种覆盖,这将始终是屏幕的大小,但图像、图形和文本会被绘制在上面,并更新,搬家等等。

4

0 回答 0