Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在透明窗口中绘制半透明矩形_C++_Winapi_Gdi - Fatal编程技术网

C++ 在透明窗口中绘制半透明矩形

C++ 在透明窗口中绘制半透明矩形,c++,winapi,gdi,C++,Winapi,Gdi,我在stackoverflow中发现了这段代码,它使用位图在透明窗口上绘制了一个矩形。但不知何故,我无法改变矩形的透明度。更准确地说,我可以,但它会变得更暗。就像位图本身有黑色背景一样。如何使矩形透明 void paintRect(HDC hdc, RECT dim, COLORREF penCol, COLORREF brushCol, int opacity) { HDC tempHDC = CreateCompatibleDC(hdc);

我在stackoverflow中发现了这段代码,它使用位图在透明窗口上绘制了一个矩形。但不知何故,我无法改变矩形的透明度。更准确地说,我可以,但它会变得更暗。就像位图本身有黑色背景一样。如何使矩形透明

void paintRect(HDC hdc, RECT dim, COLORREF penCol, COLORREF brushCol, int opacity)
    {
        HDC tempHDC = CreateCompatibleDC(hdc);
    
        BITMAPINFO bitmapInfo;
        ZeroMemory(&bitmapInfo, sizeof(BITMAPINFO));
    
        bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        bitmapInfo.bmiHeader.biWidth = dim.right - dim.left;
        bitmapInfo.bmiHeader.biHeight = dim.bottom - dim.top;
        bitmapInfo.bmiHeader.biPlanes = 1;
        bitmapInfo.bmiHeader.biBitCount = 32;
        bitmapInfo.bmiHeader.biCompression = BI_RGB;
        bitmapInfo.bmiHeader.biSizeImage = (dim.right - dim.left) * (dim.bottom - dim.top) * 4;
    
        HBITMAP hBitmap = CreateDIBSection(tempHDC, &bitmapInfo, DIB_RGB_COLORS, NULL, NULL, 0x0);
    
        SelectObject(tempHDC, hBitmap);
        SetDCPenColor(tempHDC, RGB(0, 0, 255));
        SetDCBrushColor(tempHDC, RGB(0, 0, 255));
        FillRect(tempHDC, &dim, CreateSolidBrush(RGB(0, 0, 255)));
    
        BLENDFUNCTION blend = { AC_SRC_OVER, 0, 255, 0 };
        AlphaBlend(hdc, dim.left, dim.top, dim.right, dim.bottom, tempHDC, dim.left, dim.top, dim.right, dim.bottom, blend);
    }
完整代码

#include <Windows.h>

int wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow);
LRESULT CALLBACK windowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
    WNDCLASS windowClass {};

    windowClass.lpfnWndProc = windowProc;
    windowClass.hInstance = hInstance;
    windowClass.lpszClassName = L"Keystrokes";
    windowClass.style = CS_NOCLOSE;
    windowClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);

    if (!RegisterClass(&windowClass))
    {
        return 0;
    }

    HWND hwnd = CreateWindowEx(WS_EX_LAYERED | WS_EX_TOPMOST | WS_EX_TOOLWINDOW, L"Keystrokes", L"Keystrokes", WS_POPUP, 0, 0, 148, 140, 0, 0, hInstance, 0);

    if (!hwnd)
    {
        return 0;
    }

    SetLayeredWindowAttributes(hwnd, RGB(0, 0, 0), 0, LWA_COLORKEY);

    ShowWindow(hwnd, nCmdShow);

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

    return 0;
}

void paintRect(HDC hdc, RECT dim, COLORREF penCol, COLORREF brushCol, int opacity)
{
    HDC tempHDC = CreateCompatibleDC(hdc);

    BITMAPINFO bitmapInfo;
    ZeroMemory(&bitmapInfo, sizeof(BITMAPINFO));

    bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bitmapInfo.bmiHeader.biWidth = dim.right - dim.left;
    bitmapInfo.bmiHeader.biHeight = dim.bottom - dim.top;
    bitmapInfo.bmiHeader.biPlanes = 1;
    bitmapInfo.bmiHeader.biBitCount = 32;
    bitmapInfo.bmiHeader.biCompression = BI_RGB;
    bitmapInfo.bmiHeader.biSizeImage = (dim.right - dim.left) * (dim.bottom - dim.top) * 4;

    HBITMAP hBitmap = CreateDIBSection(tempHDC, &bitmapInfo, DIB_RGB_COLORS, NULL, NULL, 0x0);

    SelectObject(tempHDC, hBitmap);
    SetDCPenColor(tempHDC, RGB(0, 0, 255));
    SetDCBrushColor(tempHDC, RGB(0, 0, 255));
    FillRect(tempHDC, &dim, CreateSolidBrush(RGB(0, 0, 255)));

    BLENDFUNCTION blend = { AC_SRC_OVER, 0, 255, 0 };
    AlphaBlend(hdc, dim.left, dim.top, dim.right, dim.bottom, tempHDC, dim.left, dim.top, dim.right, dim.bottom, blend);
}

LRESULT CALLBACK windowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
        case WM_LBUTTONDOWN:
        {
            SendMessage(hwnd, WM_NCLBUTTONDOWN, HTCAPTION, 0);
        }
        
        break;

        case WM_MBUTTONDOWN:
        {
            PostQuitMessage(0);
        }

        break;

        case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hDC = BeginPaint(hwnd, &ps);

            paintRect(hDC, { 0, 0, 48, 48 }, RGB(255, 0, 0), RGB(255, 255, 255), 255);

            EndPaint(hwnd, &ps);
        }
    }

    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
#包括
int wWinMain(HINSTANCE HINSTANCE、HINSTANCE hPrevInstance、PWSTR pCmdLine、int nCmdShow);
LRESULT回调windowProc(HWND-HWND、UINT-uMsg、WPARAM-WPARAM、LPARAM-LPARAM);
int APICENT wWinMain(HINSTANCE HINSTANCE、HINSTANCE hPrevInstance、PWSTR pCmdLine、int nCmdShow)
{
WNDCLASS windowClass{};
windowClass.lpfnWndProc=windowProc;
windowClass.hInstance=hInstance;
windowClass.lpszClassName=L“击键”;
windowClass.style=CS\u NOCLOSE;
windowClass.hbrBackground=(HBRUSH)GetStockObject(黑色画笔);
windowClass.hCursor=LoadCursor(空,IDC_箭头);
if(!RegisterClass(&windowClass))
{
返回0;
}
HWND HWND=CreateWindowEx(WS|u EX|u分层的| WS|u EX|u最顶层的| WS|u EX|u工具窗口,L“击键”,L“击键”,WS|u弹出窗口,0,0,148,140,0,0,hInstance,0);
如果(!hwnd)
{
返回0;
}
SetLayeredWindowAttributes(hwnd、RGB(0、0、0)、0、LWA_颜色键);
显示窗口(hwnd、nCmdShow);
MSG{};
while(GetMessage(&msg,NULL,0,0))
{
翻译信息(&msg);
发送消息(&msg);
}
返回0;
}
void paintRect(HDC HDC、RECT dim、COLORREF penCol、COLORREF brushCol、int不透明)
{
HDC tempHDC=CreateCompatibleDC(HDC);
BITMAPINFO BITMAPINFO;
零内存(&bitmapInfo,sizeof(bitmapInfo));
bitmapInfo.bmiHeader.biSize=sizeof(bitmapInfo头文件);
bitmapInfo.bmiHeader.biWidth=dim.right-dim.left;
bitmapInfo.bmiHeader.biHeight=dim.bottom-dim.top;
bitmapInfo.bmiHeader.biPlanes=1;
bitmapInfo.bmiHeader.biBitCount=32;
bitmapInfo.bmiHeader.biCompression=BI_RGB;
bitmapInfo.bmiHeader.biSizeImage=(dim.right-dim.left)*(dim.bottom-dim.top)*4;
HBITMAP HBITMAP=CreateDIBSection(tempHDC,&bitmapInfo,DIB_RGB_颜色,NULL,NULL,0x0);
选择对象(tempHDC、hBitmap);
SetDCPenColor(tempHDC,RGB(0,0255));
SetDCBrushColor(tempHDC,RGB(0,0255));
FillRect(tempHDC,&dim,CreateSolidBrush(RGB(0,0255));
BLENDFUNCTION blend={AC_SRC_OVER,0,255,0};
AlphaBlend(hdc、dim.left、dim.top、dim.right、dim.bottom、tempHDC、dim.left、dim.top、dim.right、dim.bottom、blend);
}
LRESULT回调windowProc(HWND HWND、UINT uMsg、WPARAM WPARAM、LPARAM LPARAM)
{
开关(uMsg)
{
案例WM_LBUTTONDOWN:
{
发送消息(hwnd、WM_nclubuttondown、HTCAPTION、0);
}
打破
案例WM_mbutdown:
{
PostQuitMessage(0);
}
打破
案例WM_油漆:
{
PAINTSTRUCT-ps;
HDC HDC=开始喷漆(hwnd和ps);
paintRect(hDC,{0,0,48,48},RGB(255,0,0),RGB(255,255,255),255);
端漆(hwnd和ps);
}
}
返回DefWindowProc(hwnd、uMsg、wParam、lParam);
}
“就像位图本身有黑色背景一样。”

因为您的背景设置为:

windowClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
当然,您可以将其设置为
NULL\u BRUSH
,使其看起来透明:

windowClass.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);

但当您移动它时,您会发现这并不是要使窗口透明,而是要停止绘制背景:

正如@Ben所回答的:

您没有使窗口透明,只是停止绘制背景。你所看到的背景就是第一次绘制窗口时在窗口下面发生的事情

你需要参考

不能直接在窗口上添加矩形,应使用分层窗口,然后添加所需内容

以下是您可以参考的示例:

#include <Windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(_In_  HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_  LPSTR szCmdLine, _In_  int iCmdShow)
{
    static TCHAR szAppName[] = TEXT("test window");
    HWND hwnd;
    MSG msg;
    WNDCLASS wndclass;
    wndclass.style = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc = WndProc;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hInstance = hInstance;
    wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wndclass.lpszMenuName = NULL;
    wndclass.lpszClassName = szAppName;
    if (!RegisterClass(&wndclass))
    {
        MessageBox(NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR);
    }

    hwnd = CreateWindowEx(WS_EX_LAYERED | WS_EX_TOPMOST | WS_EX_TOOLWINDOW, szAppName,
        TEXT("the hello program"),
        WS_POPUP,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        148,
        148,
        NULL,
        NULL,
        hInstance,
        NULL);
    SetLayeredWindowAttributes(hwnd, 0, 1, LWA_ALPHA);
    ShowWindow(hwnd, iCmdShow);
    UpdateWindow(hwnd);
    while (GetMessageW(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessageW(&msg);
    }
    return msg.wParam;
}
VOID FadeRect(RECT* prc, HDC hdc)
{
    BOOL fFade = FALSE;
    static HWND hwnd;
    SIZE size;
    POINT ptSrc = { 0, 0 };
    BLENDFUNCTION blend;

    SystemParametersInfo(SPI_GETSELECTIONFADE, 0, &fFade, 0);
    if (!fFade)
        return;
    if (!hwnd) hwnd = CreateWindowEx(WS_EX_LAYERED | 
        WS_EX_TRANSPARENT | 
        WS_EX_TOPMOST | WS_EX_TOOLWINDOW,
        L"static", L"static", WS_POPUP | WS_VISIBLE, prc->left,
        prc->top, prc->right, prc->bottom, NULL, (HMENU)0, NULL, NULL);
    else MoveWindow(hwnd, prc->left, prc->top, prc->right, prc->bottom, TRUE);

    RECT rect{ prc->left,prc->top,prc->right,prc->bottom };
    size.cx = prc->right - prc->left;
    size.cy = prc->bottom - prc->top;

    blend.BlendOp = AC_SRC_OVER;
    blend.BlendFlags = 0;
    blend.AlphaFormat = 0;
    blend.SourceConstantAlpha = 150;
    UpdateLayeredWindow(hwnd, NULL, NULL, &size, hdc, &ptSrc, 0,
        &blend, ULW_ALPHA);
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_LBUTTONDOWN:
    {
        SendMessage(hwnd, WM_NCLBUTTONDOWN, HTCAPTION, 0);
        InvalidateRect(hwnd, NULL, TRUE);
    }
    break;
    case WM_MBUTTONDOWN:
    {
        PostQuitMessage(0);
    }

    break;

    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        RECT rect;
        GetClientRect(hwnd, &rect);
        MapWindowPoints(hwnd, GetParent(hwnd), (LPPOINT)&rect, 2);
        HDC hDC = BeginPaint(hwnd, &ps);
        RECT rc{ rect.left,rect.top,rect.left + 48,rect.top + 48 };
        FadeRect(&rc, hDC);
        EndPaint(hwnd, &ps);
    }
    break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    }

    return DefWindowProc(hwnd, message, wParam, lParam);
}
#包括
LRESULT回调WndProc(HWND、UINT、WPARAM、LPARAM);
int WINAPI WinMain(_In_uuhinstance HINSTANCE,_In_uopt_uuuhinstance hPrevInstance,_In_uustrszcmdline,u In_uuint iCmdShow)
{
静态TCHAR szAppName[]=文本(“测试窗口”);
HWND-HWND;
味精;
WNDCLASS WNDCLASS;
wndclass.style=CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc=WndProc;
wndclass.cbClsExtra=0;
wndclass.cbWndExtra=0;
wndclass.hInstance=hInstance;
wndclass.hIcon=LoadIcon(空,IDI_应用程序);
wndclass.hCursor=LoadCursor(空,IDC_箭头);
wndclass.hbrBackground=(HBRUSH)GetStockObject(白色画笔);
wndclass.lpszMenuName=NULL;
wndclass.lpszClassName=szAppName;
if(!RegisterClass(&wndclass))
{
MessageBox(NULL,文本(“此程序需要Windows NT!”),szAppName,MB_ICONERROR);
}
hwnd=CreateWindowEx(WS_EX_分层的| WS_EX_顶层的| WS_EX_工具窗口,szAppName,
文本(“hello程序”),
WS_弹出窗口,
CW_使用默认值,
CW_使用默认值,
148,
148,
无效的
无效的
hInstance,
无效);
SetLayeredWindowAttributes(hwnd、0、1、LWA_ALPHA);
显示窗口(hwnd、iCmdShow);
更新窗口(hwnd);
while(GetMessageW(&msg,NULL,0,0))
{
翻译信息(&msg);
DispatchMessageW(&msg);
}
返回msg.wParam;
}
无效安装(矩形*prc、HDC、HDC)
{
BOOL-fFade=假;
静态HWND-HWND;
大小;
点ptSrc={0,0};
混合功能混合;
系统参数信息(SPI_GETSELECTIONFADE,0和fFade,0);
如果(!fFade)
返回;
如果(!hwnd)hwnd=CreateWindowEx(WS_EX_LAYERED |
WS_exu|u TRANSPARENT|
WS_EX_TOPMOST | WS_EX_TOOLWINDOW,
L“静态”,L“静态”,WS|u弹出窗口| WS|u可见,prc->左侧,
prc->top,prc->right,prc->bottom,空,(HMENU)0,空,空);
else移动窗口(hwnd,prc->左,prc->顶,prc->右,prc->底,真);
RECT RECT{prc->左,prc->上,prc->右,p