我想知道如何用 C++ 制作一个透明的程序,我的意思是你能看到的只是窗口的内容(文本/内容)。我也不想使用像 Qt 这样的库,而只使用默认库(如果需要,还可以使用 SDL/OpenGL)。
我不是在控制台之后,我想要一个可以显示图像和文本的窗口。
系统:Windows 7
它应该是这样的:
SetLayeredWindowAttributes(GetActiveWindow(), NULL, Alpha, LWA_ALPHA);
在这种情况下Alpha
是变量 [0; 255] 这决定了透明度的程度。您还需要检查返回值是否为TRUE
.
我在 github 上有一个项目,它创建了一个带有一些自定义的半透明窗口
按钮-> https://github.com/xx4g/twlekezexe
有一个文件 transparentwindowbuilder.cpp 它包含以下功能。
使用 updatelayeredwindow 进行渲染时,我的运气会更好。
通常,当我只想要一个不可见的窗口时,我会使用 setlayeredwindow。
例子 :
WndProc:重要的是要注意我们必须自己发送 WM_NCLBUTTONDOWN 消息:
LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) /* handle the messages */
{
case WM_MOVE:
UpdatePosProc();
return DefWindowProc(hwnd, message, wParam, lParam);
break;
case WM_DESTROY:/* the window was destroyed */
PostQuitMessage(0); /* send a WM_QUIT to the message queue */
break;
case WM_LBUTTONDOWN:/* the left mouse button was clicked */
mouseHit = true;
::PostMessage(hwnd,WM_NCLBUTTONDOWN,HTCAPTION,lParam); /* send a HTCAPTION to the message queue */
return DefWindowProc(hwnd, message, wParam, lParam);
break;
default: /* for messages that we don't deal with */
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
}
//In main.cpp somewhere
hWndParent = MakeTransparentWindowProc(hThisInstance, SW_HIDE, L"back1.png", L"PNGDialog1", L"winexe", width, height, WindowProcedure, false,HWND_DESKTOP);
//transparentwindowbuilder.cpp
HWND MakeTransparentWindowProc (HINSTANCE hThisInstance,
int nCmdShow,
const wchar_t* ImagePng1, /* This is the PNG image path */
const wchar_t* windowClassName1,/* This is the class name */
const wchar_t* windowName1, /* This is the application name */
int width, /* This is the window width */
int height,/* This is the window height */
WNDPROC windocProcedure,
bool toolwindow,HWND Parent)
{
/* Start GDIPlus */
ULONG_PTR gdiplusStartupToken; /* GDIPlus Startup Token */
Gdiplus::GdiplusStartupInput gdiInput;
Gdiplus::GdiplusStartup(&gdiplusStartupToken, &gdiInput, NULL);
/* Make a transparent Window*/
/* Local Variables*/
HWND hwnd; /* This is the handle for our window */
/* Make Transparent Window */
auto result = makeTransParentWindow(hThisInstance, /* the hInstance, Should use WinMains HInstance */
hwnd, /* This is the handle for our window */
nCmdShow, /* The show Window Flag */
ImagePng1, /* The path to the Image File */
windocProcedure, /* The pointer to the window procedure */
windowClassName1, /* The name of the NEw class to create */
width,/* The length */
height,/* The width */
windowName1, toolwindow, Parent);
/* Shut down GDIPlus*/
Gdiplus::GdiplusShutdown(gdiplusStartupToken);
return result ? hwnd : nullptr;
}
bool makeTransParentWindow(HINSTANCE& hThisInstance, HWND& hWnd, int& nCmdShow, const wchar_t*& imagePath, WNDPROC lpfnWndProc, const wchar_t*& szClassName, int Width, int Height, const wchar_t*& szWindowName,bool toolwindow,HWND Parent)
{
WNDCLASSEX wincl; /* Data structure for the windowclass */
if (!RegisterWindowClass(wincl, hThisInstance, szClassName, lpfnWndProc)) return false;
/* The class is registered, let's create the program*/
if (!CreateWindowPane(hWnd, szClassName, Width, Height, hThisInstance, szWindowName, toolwindow, Parent)) return false;
/* Make the window visible on the screen */
ShowWindow(hWnd, nCmdShow);
RenderWindow(hWnd, imagePath);
return true;
}
void RenderWindow(HWND& hWnd, const wchar_t*& imagePath)
{
RECT wndRect;
::GetWindowRect(hWnd, &wndRect);
SIZE wndSize = { wndRect.right - wndRect.left,wndRect.bottom - wndRect.top };
DrawSizedWindow(hWnd, wndSize, imagePath);
}
void DrawSizedWindow(HWND& hWnd, SIZE& wndSize, const wchar_t*& imagePath)
{
HDC hdc = ::GetDC(hWnd);
HDC memDC = ::CreateCompatibleDC(hdc);
HBITMAP memBitmap = ::CreateCompatibleBitmap(hdc, wndSize.cx, wndSize.cy);
SelectAndDrawObject(memDC, memBitmap, imagePath, wndSize);
HDC screenDC = GetDC(NULL);
BlendLayeredWindow(hWnd, screenDC, wndSize, memDC);
CleanUpObjects(memDC, memBitmap, hWnd, screenDC);
}
void SelectAndDrawObject(HDC& memDC, const HBITMAP& memBitmap, const wchar_t*& imagePath, SIZE& wndSize)
{
::SelectObject(memDC, memBitmap);
::DrawGdiImage(imagePath, memDC, wndSize);
}
void BlendLayeredWindow(HWND& hWnd, const HDC& screenDC, SIZE& wndSize, const HDC& memDC)
{
POINT ptSrc = { 0,0 };
BLENDFUNCTION blendFunction;
::SetBlendFunctionSetiings(blendFunction);
::UpdateLayeredWindow(hWnd, screenDC, &ptSrc, &wndSize, memDC, &ptSrc, 0, &blendFunction, 2);
}
void CleanUpObjects(const HDC& memDC, const HBITMAP& memBitmap, HWND& hWnd, const HDC& screenDC)
{
::DeleteDC(memDC);
::DeleteObject(memBitmap);
::ReleaseDC(hWnd, screenDC);
}
void DrawGdiImage(const wchar_t*& imagePath, const HDC& memDC, SIZE& wndSize)
{
Gdiplus::Image image(imagePath);
Gdiplus::Graphics graphics(memDC);
graphics.DrawImage(&image, 0, 0, wndSize.cx, wndSize.cy);
}
bool CreateWindowPane(HWND& hWnd, const wchar_t*& szClassName, int Width, int Height, HINSTANCE& hThisInstance, const wchar_t*& windowName,bool toolwindow,HWND Owner)
{
if (toolwindow)
{
hWnd = CreateWindowEx(
WS_EX_LAYERED | WS_EX_NOACTIVATE, /* Extended possibilites for variation */
szClassName, /* Classname */
windowName, /* Title Text */
WS_POPUPWINDOW | WS_CHILD, /* default window */
CW_USEDEFAULT, /* Windows decides the position */
CW_USEDEFAULT, /* where the window ends up on the screen */
Width, /* The programs width */
Height, /* and height in pixels */
Owner, /* The window is a child-window to desktop */
NULL, /* No menu */
hThisInstance, /* Program Instance handler */
NULL /* No Window Creation data */
);
}
else
{
hWnd = CreateWindowEx(
WS_EX_LAYERED, /* Extended possibilites for variation */
szClassName, /* Classname */
windowName, /* Title Text */
WS_POPUPWINDOW, /* default window */
CW_USEDEFAULT, /* Windows decides the position */
CW_USEDEFAULT, /* where the window ends up on the screen */
Width, /* The programs width */
Height, /* and height in pixels */
HWND_DESKTOP, /* The window is a child-window to desktop */
NULL, /* No menu */
hThisInstance, /* Program Instance handler */
NULL /* No Window Creation data */
);
}
return hWnd != nullptr;
}
bool RegisterWindowClass(WNDCLASSEX& wincl, HINSTANCE& hThisInstance, const wchar_t*& szClassName, const WNDPROC& lpfnWndProc)
{
/* The Window structure */
wincl.hInstance = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = lpfnWndProc; /* This function is called by windows */
wincl.style = CS_DBLCLKS; /* Catch double-clicks */
wincl.cbSize = sizeof(WNDCLASSEX);
/* Use default icon and mouse-pointer */
wincl.hIcon = LoadIcon(hThisInstance, MAKEINTRESOURCE(IDI_WINEXE));
wincl.hIconSm = LoadIcon(hThisInstance, MAKEINTRESOURCE(IDI_WINEXE));
wincl.hCursor = LoadCursor(NULL, IDC_ARROW);
wincl.lpszMenuName = NULL; /* No menu */
wincl.cbClsExtra = 0; /* No extra bytes after the window class */
wincl.cbWndExtra = 0; /* structure or the window instance */
/* Use Windows's default colour as the background of the window */
wincl.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
/* Register the window class, and if it fails quit the program */
if (!RegisterClassEx(&wincl))
{
return false;
}
return true;
}
void SetBlendFunctionSetiings(BLENDFUNCTION& blendFunction)
{
blendFunction.AlphaFormat = AC_SRC_ALPHA;
blendFunction.BlendFlags = 0;
blendFunction.BlendOp = AC_SRC_OVER;
blendFunction.SourceConstantAlpha = 220;
}