1

ウィンドウに2つの領域があり、それぞれに独自のツールチップがあります。
これらのツールチップは、(ちらつきを防ぐために)WM_PAINTメッセージを処理することによってカスタム描画されます。

これは、ツールチップの作成です。

tooltips[MAIN_GRAPH_TT].tthWnd =  CreateWindowEx(WS_EX_TOPMOST,TOOLTIPS_CLASS,0,WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP | TTS_NOFADE,CW_USEDEFAULT, CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,0,0,g_hInst,0);  
tooltips[SECONDARY_GRAPH_TT].tthWnd =   CreateWindowEx(WS_EX_TOPMOST,TOOLTIPS_CLASS,0,WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP | TTS_NOFADE,CW_USEDEFAULT, CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,0,0,g_hInst,0);  

これはツールチップの初期化です。

if (tooltips[MAIN_GRAPH_TT].tthWnd)
{

    lpfnOldTTProc = (WNDPROC)SetWindowLong(tooltips[MAIN_GRAPH_TT].tthWnd,
        GWL_WNDPROC, (DWORD) TooltipProc);
    SetWindowLong(tooltips[MAIN_GRAPH_TT].tthWnd, GWL_EXSTYLE, WS_EX_LAYERED|WS_EX_TOOLWINDOW);
    SetLayeredWindowAttributes(tooltips[MAIN_GRAPH_TT].tthWnd,RGB(255,0,0),0,ULW_COLORKEY);
    SendMessage(tooltips[MAIN_GRAPH_TT].tthWnd,CWM_SETWNDPROC,0,(LPARAM)new WNDPROC(lpfnOldTTProc));
}

if (tooltips[SECONDARY_GRAPH_TT].tthWnd)
{

    lpfnOldTTProc = (WNDPROC)SetWindowLong(tooltips[SECONDARY_GRAPH_TT].tthWnd, GWL_WNDPROC, (DWORD) TooltipProc);
    SetWindowLong(tooltips[SECONDARY_GRAPH_TT].tthWnd, GWL_EXSTYLE, WS_EX_LAYERED|WS_EX_TOOLWINDOW);
    SetLayeredWindowAttributes(tooltips[SECONDARY_GRAPH_TT].tthWnd,RGB(255,0,0),0,ULW_COLORKEY);
    SendMessage(tooltips[SECONDARY_GRAPH_TT].tthWnd,CWM_SETWNDPROC,0,(LPARAM)new WNDPROC(lpfnOldTTProc));
}  

これは、カスタムツールチップWNDPROCのWM_PAINTです。

 case WM_PAINT:
     {

        const int FRAME_WIDTH = 1;
        const int CORNER_DIAMETER = 10;
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hWnd,&ps);
        HDC hMemDC;
        RECT cr;
        GetClientRect(hWnd,&cr);
        hMemDC = CreateCompatibleDC(hdc);
        HBITMAP memBM = CreateCompatibleBitmap(hdc, cr.right-cr.left, cr.bottom-cr.top);
        HBITMAP hOldBM = (HBITMAP) SelectObject(hMemDC,memBM);
        //drawing start [draw to hMemDC]
        {
            FillSolidRect(hMemDC,0,0,cr.right-cr.left,cr.bottom-cr.top,RGB(255,0,0));               
            HPEN hFramePen = CreatePen(PS_SOLID,FRAME_WIDTH,BLACK);
            HBRUSH hBGBrush = GetSysColorBrush(COLOR_INFOBK);
            SetTextColor(hMemDC,GetSysColor(COLOR_INFOTEXT));
            SetBkColor(hMemDC,WHITENESS);
            SetBkMode(hMemDC,TRANSPARENT);
            HBRUSH hOldBrush = (HBRUSH) SelectObject(hMemDC,hBGBrush);
            HPEN hOldPen = (HPEN) SelectObject(hMemDC,hFramePen);
            HFONT hOldFont = SelectFont(hMemDC,g_hFonts[FONT_TOOLTIP]);
            RoundRect(hMemDC,cr.left,cr.top,cr.right,cr.bottom,CORNER_DIAMETER,CORNER_DIAMETER);
            RECT textRec = cr;
            textRec.left += FRAME_WIDTH*2;
            textRec.right -= FRAME_WIDTH*2;
            textRec.top += FRAME_WIDTH*2;
            textRec.bottom -= FRAME_WIDTH*2;
            if(hWnd == tooltips[MAIN_GRAPH_TT].tthWnd)
                DrawText(hMemDC,tttBuffer[MAIN_GRAPH_TT],sizeof(tttBuffer),&textRec,DT_LEFT|DT_TOP);
            else if(hWnd == tooltips[SECONDARY_GRAPH_TT].tthWnd)
                DrawText(hMemDC,tttBuffer[SECONDARY_GRAPH_TT],sizeof(tttBuffer),&textRec,DT_LEFT|DT_TOP);
            SelectObject(hMemDC,hOldBrush);
            SelectObject(hMemDC,hOldPen);
            SelectObject(hMemDC,hOldFont);
            DeleteObject(hFramePen);
            DeleteObject(hBGBrush);

        }
        //drawing end
        BitBlt(hdc,
                cr.left,
                cr.top,
                cr.right-cr.left, cr.bottom-cr.top,
                hMemDC,
                0,
                0,
                SRCCOPY);
        SelectObject(hdc,hOldBM);
        DeleteObject(memBM);
        DeleteDC(hMemDC);
        EndPaint(hWnd,&ps);
     }
    break;

これらのツールチップの問題は、(丸い長方形の外側の)コーナーが透明であるはずですが、それらを消すことができないようです。
私は(素朴に)HOLLOW_BRUSHを使用して背景の四角形をペイントしようとしましたが、機能しませんでした。例からわかるように、レイヤードウィンドウアプローチを使用してみましたが、やはり役に立ちませんでした。

ツールチップの背景の透明度を取得するのを手伝ってくれる人はいますか?


これは、透明度のないツールチップの写真です
[視認性を高めるために角が白に変更されています。これらは透明度が必要な部分です]
(テキストは空白になっています)
透明性のないツールチップ

4

2 に答える 2

2

コントロールと透過性を扱う場合、WS_EX_TRANSPARENTexStyleを使用すると時間を節約できることがわかりました。また、ツールチップがWM_CTLCOLORSTATICメッセージをメインウィンドウに送信するかどうかを確認することもできます。送信する場合は、それに応じて中空(null)のブラシハンドルを返送することもできます。WM_CTLCOLORSTATICメッセージが提供するhDCでSetBkModeを呼び出すことにより、その時点でバックグラウンドモードを透過に設定する必要がある場合もあります。

これをテストしなかったことをお詫びしますが、静的コントロールとグループコントロールでうまく機能します。これまで私が証明した唯一のコントロールは、このメソッドに応答しないことです。チェックボックスボタンは、背景の透明度を設定できませんでした。

よろしく。

于 2012-12-14T20:26:58.183 に答える
1

を使用SetWindowRgnして、ウィンドウの一部を透明にすることができます ( を使用して領域を作成しますCreateRoundRectRgn)。

または、SetLayeredWindowAttributesトゥルー アルファ ブレンディングを使用してウィンドウの一部を透明にすることもできます。

于 2012-12-14T20:44:20.300 に答える