我想创建一个分层窗口,其大小大于其内容(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 };
是行不通的。该窗口根本没有呈现,但它打开了(窗口任务栏图标可见)。
我可能还不能完全理解分层窗口是如何工作的,这就是为什么我不明白为什么在这个例子中它没有被渲染。
有可能创建这样一个分层的窗口吗?如果是,那怎么办?
或者也许这根本不是我应该做的事情?
就像一个注释:我想这样做的原因是使用分层窗口作为一种覆盖,这将始终是屏幕的大小,但图像、图形和文本会被绘制在上面,并更新,搬家等等。