2012-12-14 66 views
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來繪製背景矩形,但沒有工作,正如你可以從我已經嘗試使用分層窗口方法的例子看到的,再次無濟於事。

任何人都可以幫助我獲得我的工具提示背景的透明度?


這裏是工具提示的不透明度的圖片
[拐角已recoloured白色能見度 - 這些需要是透明的部件]
(文本顯示爲空白)
Tooltip without transparency

+0

呃。透明工具提示的概念非常奇怪。它應該清楚地看到它與任何重疊的部分,因此尖端易於閱讀。我懷疑你需要SetWindowRgn()。 –

+0

工具提示是圖片中的顏色,它只是需要透明的角落(它們是圓形的) - 授予圖片不是很清楚,但您應該能夠確定它們是紅色的。他們是需要透明度的部分。 – Daboyzuk

+0

對於SetWindowRgn()來說,角落現在是白色以提高可視性 – Daboyzuk

回答

1

您可以使用SetWindowRgn來使部分窗口透明(使用CreateRoundRectRgn創建區域)。

或者,您可以使用SetLayeredWindowAttributes來使用真正的alpha混合來使窗口的某些部分透明。

+0

我不確定真正的阿爾法混合是我想要的,但我想如果我控制wm_paint我想我只是忽略窗口應該是透明的和事實上的事實...我會給它一個當我可以 – Daboyzuk

+0

SetWindowRgn和CreateRoundRectRgn已經完成了這項工作,謝謝! – Daboyzuk

2

在處理控件和透明度時,我發現WS_EX_TRANSPARENT exStyle可以爲您節省一些時間。此外,您可能想要檢查工具提示是否將WM_CTLCOLORSTATIC消息發送到主窗口,如果它確實需要發回空心(空)筆刷句柄作爲響應。您可能還需要在該時間點通過調用WM_CTLCOLORSTATIC消息提供的hDC上的SetBkMode來將背景模式設置爲透明。

對不起,沒有測試任何這一點,但它適用於靜態和組控制。到目前爲止,我證明的唯一控制是對此方法無響應的複選框按鈕,我無法爲其設置背景透明度。

問候。

+0

感謝您的回覆......我沒有想過處理彩信......我真的應該有。是的,我已經嘗試ws_ex_transparant已與其他樣式,雖然我忽略提及它...將看看如果通過一個空心畫筆可以幫助我,雖然 – Daboyzuk

+0

@Daboyzuk不客氣。不要忘記設置後臺模式 – mkey

+0

對於響應延遲感到抱歉,看起來(除非我做錯了什麼,或者阻止它們)工具提示實際上並沒有收到任何WM_CTLCOLOR消息,我覺得有點奇怪。 – Daboyzuk