Сделать родительское окно прозрачным, а дочернее окно непрозрачным с помощью CEF - PullRequest
0 голосов
/ 21 ноября 2018

В Windows я пытаюсь использовать CEF (Chromium Embedded Framework) для создания оконного приложения с прозрачным родительским окном и непрозрачным дочерним окном (я хочу иметь закругленный угол и стрелку, указывающую настрока состояния в дочернем окне).Что-то похожее на:

enter image description here

Я пытался использовать SetLayeredWindowAttributes, чтобы сделать родительское окно прозрачным, но оно также делает прозрачным дочернее окно.Есть ли способ сделать это в Windows?

1 Ответ

0 голосов
/ 03 декабря 2018

SetLayeredWindowAttributes нужен цвет для прозрачности.Убедитесь, что цвет прозрачности не используется дочерним окном.Вы можете выбрать случайный цвет, например RGB(255, 0, 254), и предположить, что дочернее окно его не использует.

Если у вас нет контроля над дочерним окном, и вы не можете быть уверены, какие цвета оно может использовать, тогда SetWindowRgn - это еще один вариант создания непрямоугольных окон.

В приведенном ниже примере показано, как установить область так, чтобы углы были круглыми с треугольником сверху.

Вы можете использовать GDI + для большей гибкости при рисовании области и для эффекта сглаживания, чтобы границы выглядели более плавными.

#include <Windows.h>

int triangle_height = 30;
int corner_size = 20;
int caption_height = 60;

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
    switch(msg)
    {
    case WM_CREATE:
    {
        //create a child button for testing
        CreateWindowW(L"BUTTON", L"Close", WS_CHILD | WS_VISIBLE,
            10, caption_height + 10, 100, 30,
            hwnd, HMENU(100), GetModuleHandle(NULL), NULL);

        RECT rc;
        GetClientRect(hwnd, &rc);

        //create a triangle region
        int w = rc.right;
        int h = rc.bottom;
        int z = triangle_height;
        POINT pt[3];
        pt[0] = { w / 2, 0 };
        pt[1] = { w / 2 - z, z };
        pt[2] = { w / 2 + z, z };
        HRGN htri = CreatePolygonRgn(pt, 3, WINDING);

        //create a round rectangle region
        HRGN hrgn = CreateRoundRectRgn(0, z, w, h - z, corner_size, corner_size);

        //combine the triangle with round rectangle
        CombineRgn(hrgn, htri, hrgn, RGN_OR);

        //set the new region
        SetWindowRgn(hwnd, hrgn, TRUE);

        DeleteObject(htri);
        DeleteObject(hrgn);
        return 0;
    }

    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hwnd, &ps);
        RECT rc = ps.rcPaint;

        //we don't have a standard title bar, paint one here:
        rc.bottom = caption_height;
        SetDCBrushColor(hdc, RGB(80, 80, 80));
        FillRect(hdc, &rc, (HBRUSH)GetStockObject(DC_BRUSH));

        //paint the background
        rc = ps.rcPaint;
        rc.top = caption_height;
        SetDCBrushColor(hdc, RGB(240, 240, 240));
        FillRect(hdc, &rc, (HBRUSH)GetStockObject(DC_BRUSH));

        //use FrameRgn to paint a border around the region
        HRGN hrgn = CreateRectRgn(0, 0, 0, 0);
        GetWindowRgn(hwnd, hrgn);
        SetDCBrushColor(hdc, RGB(128, 128, 128));
        FrameRgn(hdc, hrgn, (HBRUSH)GetStockObject(DC_BRUSH), 1, 1);
        DeleteObject(hrgn);

        EndPaint(hwnd, &ps);

        return 0;
    }

    case WM_NCHITTEST:
    {
        //we don't have a standard title-bar
        //respond to our custome title-bar manually:
        POINT pt;
        GetCursorPos(&pt);
        ScreenToClient(hwnd, &pt);
        if(pt.y < caption_height)
            return HTCAPTION;
        break;
    }

    case WM_COMMAND:
        if(HIWORD(wparam) == BN_CLICKED)
            if(LOWORD(wparam) == 100)
                SendMessage(hwnd, WM_CLOSE, 0, 0);
        break;

    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }

    return DefWindowProc(hwnd, msg, wparam, lparam);
}

int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE, LPTSTR, int)
{
    WNDCLASSEXW wcex = { sizeof(wcex) };
    wcex.style = CS_DROPSHADOW;
    wcex.lpfnWndProc = WndProc;
    wcex.hInstance = hInstance;
    wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground = NULL;
    wcex.lpszClassName = L"classname";
    RegisterClassExW(&wcex);

    CreateWindowW(wcex.lpszClassName, L"Test", WS_VISIBLE | WS_POPUP,
        200, 200, 600, 400, 0, 0, hInstance, 0);

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

    return (int)msg.wParam;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...