我需要在另一个应用程序窗口的顶部绘制边框(主要目的是突出显示用户从运行的应用程序列表中选择的窗口)。我试图在本机窗口边框的顶部绘制边框,但未绘制边框。这是代码:

HPEN framePen = ::CreatePen(PS_SOLID, 5, RGB(255, 0, 0));
HWND handle = FindWindow(L"ConsoleWindowClass", L"C:\\WINDOWS\\system32\\cmd.exe");

WINDOWPLACEMENT winPlacement;
GetWindowPlacement(handle, &winPlacement);
if (winPlacement.showCmd == SW_SHOWMINIMIZED)
{
    ShowWindow(handle, SW_RESTORE);
}

SetWindowPos(handle, HWND_TOP, 0, 0, 0, 0, SWP_ASYNCWINDOWPOS | SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
SetForegroundWindow(handle);

PAINTSTRUCT ps;
RECT rect = {};
::GetClientRect(handle, &rect);
HDC hdc = ::BeginPaint(handle, &ps);
::SelectObject(hdc, framePen);
::Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom);
::EndPaint(handle, &ps);

在此示例中,使用了cmd窗口的句柄,但实际上并不重要。
您能告诉我为什么没有画边框以及如何画边框吗?
谢谢。

最佳答案

您不能直接在另一个窗口上绘图,因为系统可能会随时刷新该窗口,从而覆盖您的绘图。

为了使您的图形具有持久性,请在另一个窗口的顶部创建一个layered window

  • 使用 WS_EX_LAYERED 标志创建窗口。
  • 将颜色键传递给 SetLayeredWindowAttributes()
  • WM_PAINT处理程序中,使用颜色键(通过将其用于画笔)绘制矩形的内部。使用色键绘制的所有内容都将变为透明。用所需的颜色绘制矩形的边框(通过将其用于笔)。

  • 这是一个入门的最小示例。可以通过拖放操作来移动框架。

    请注意,没有错误处理可以使示例代码保持简洁。您应该检查每个Windows API调用的返回值。
    #include <windows.h>
    
    const COLORREF MY_COLOR_KEY = RGB( 255, 0, 255 );
    
    int APIENTRY wWinMain(
        HINSTANCE hInstance, HINSTANCE /*hPrevInst*/, LPWSTR /*lpCmdLine*/, int nCmdShow )
    {
        WNDCLASSW wc{ sizeof( wc ) };
        wc.hInstance = hInstance;
        wc.style = CS_HREDRAW | CS_VREDRAW;
        wc.hCursor = LoadCursor( nullptr, IDC_ARROW );
        wc.hbrBackground = reinterpret_cast<HBRUSH>( COLOR_BTNFACE + 1 );
        wc.lpszClassName = L"MyTransparentFrame";
    
        wc.lpfnWndProc = []( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ) -> LRESULT
        {
            switch( msg )
            {
                case WM_PAINT:
                {
                    PAINTSTRUCT ps{};
                    HDC hdc = BeginPaint( hwnd, &ps );
    
                    RECT rc{}; GetClientRect( hwnd, &rc );
    
                    HPEN hPen = CreatePen( PS_SOLID, 20, GetSysColor( COLOR_HIGHLIGHT ) );
                    HBRUSH hBrush = CreateSolidBrush( MY_COLOR_KEY );
                    HGDIOBJ hOldPen = SelectObject( hdc, hPen );
                    HGDIOBJ hOldBrush = SelectObject( hdc, hBrush );
    
                    Rectangle( hdc, rc.left, rc.top, rc.right, rc.bottom );
    
                    if( hOldPen )
                        SelectObject( hdc, hOldPen );
                    if( hOldBrush )
                        SelectObject( hdc, hOldBrush );
                    if( hPen )
                        DeleteObject( hPen );
                    if( hBrush )
                        DeleteObject( hBrush );
    
                    EndPaint( hwnd, &ps );
                }
                break;
    
                case WM_DESTROY:
                    PostQuitMessage( 0 );
                break;
    
                case WM_NCHITTEST:
                    return HTCAPTION;  // to be able to drag the window around
                break;
    
                default:
                    return DefWindowProcW( hwnd, msg, wp, lp );
            }
    
            return 0;
        };
    
        RegisterClassW( &wc );
    
        HWND hwnd = CreateWindowExW( WS_EX_LAYERED, wc.lpszClassName, L"", WS_POPUP,
                             200, 200, 800, 600, nullptr, nullptr, hInstance, nullptr );
    
        SetLayeredWindowAttributes( hwnd, MY_COLOR_KEY, 255, LWA_COLORKEY );
        ShowWindow( hwnd, nCmdShow );
    
        MSG msg;
        while( GetMessage( &msg, nullptr, 0, 0 ) )
        {
            TranslateMessage( &msg );
            DispatchMessage( &msg );
        }
    
        return (int) msg.wParam;
    }
    

    07-28 01:26
    查看更多