0

パネルのティアオフやドッキングなどのスマート機能をすべて備えた UI システムを開発しています。現在、私のタスクは、ティアオフまたはドッキング可能なパネルが着陸する位置を示す画面上のオーバーレイを作成することです。ビジュアルスタジオが持っているものとほとんど同じです。そのために、必要なときに表示されるカスタムのレイヤード ウィンドウ クラスを使用しています。その後、必要な効果を達成するために掘り始めました。以前は標準の GDI 関数を使用していましたが、基本的には問題ありません。しかし今回は、ドキュメントのアドバイスに従って、タスクに UpdateLayeredWindow を使用し、GDI 関数で描画する代わりにビットマップから 32 ビット イメージをロードしました。ここでは、アルファチャンネルが 222、RGB が 255 0 0 の 128x128 ピクセル幅の bmp があります。

初期化と描画に使用するメソッドを次に示します。

void Init(HDC in_hdc,HWND in_hwnd)
    {
        bf = { 0, 0, 200, AC_SRC_ALPHA };
        hwnd = in_hwnd;
        hdc_mem = CreateCompatibleDC(in_hdc);
        hBitmap_mem = CreateCompatibleBitmap(in_hdc, canvas_size.cx, canvas_size.cy);
        hBitmap_mem_default = (HBITMAP)SelectObject(hdc_mem, hBitmap_mem);
        hdc_bitmap = CreateCompatibleDC(in_hdc);
    }
    void DrawArea(RECT& in_rect)
    {
        hBitmap_area_default = (HBITMAP)SelectObject(hdc_bitmap, hBitmap_area);
        AlphaBlend(hdc_mem, in_rect.left, in_rect.top, in_rect.right, in_rect.bottom, hdc_bitmap, 0, 0, 2, 2, bf);
        hBitmap_area = (HBITMAP)SelectObject(hdc_bitmap, hBitmap_area_default);
    }
    void Update()
    {
        POINT p = { 0, 0 };
        HDC hdc_screen = GetDC(0);
        UpdateLayeredWindow(hwnd, hdc_screen, &p, &canvas_size, hdc_mem, &p, 0, &bf, ULW_ALPHA);
    }

ウィンドウ スタイルには、このエクストラがあります WS_EX_LAYERED|WS_EX_TRANSPARENT|WS_EX_TOPMOST

そして、ここに私が得るものがあります。ご覧のとおり、ブレンドはピクセルごとのアルファを考慮に入れていますが、ブレンド作業はうまくいきません。それを調整する方法はありますか? ここに画像の説明を入力

4

1 に答える 1

1

問題はソース ビットマップにあると思われます。これは、RGB 値がアルファで事前に乗算されていない場合に得られる種類の効果です。しかし、これを行うはるかに簡単な方法があるため、それを無視してください。

  • hbrBackground構造体に設定することで、無地の背景色を持つレイヤード ウィンドウを作成しますWNDCLASSEX

  • SetLayeredWindowAttributesを呼び出して、ウィンドウを部分的に透明にします。

  • 必要な場所にウィンドウを配置します。

それでおしまい。

この回答には、わずかに異なる目的のテクニックを示すコードがあります。

于 2015-04-16T12:21:30.667 に答える