2014-10-08 24 views
8

Cách hiển thị biểu tượng 'x' (đóng) trong TBalloonHint?Hiển thị biểu tượng 'x' trong TBalloonHint

enter image description here

Tôi muốn lập trình hiển thị gần một điều khiển vào mẫu một gợi ý bóng trông như thông báo ở khay hệ thống. Nếu đây không phải là những gì TBalloonHint có thể làm, tôi nên sử dụng những gì?

+1

Nút đóng được thêm bằng cách đặt kiểu 'TTS_CLOSE' trên điều khiển chú giải công cụ Windows bên dưới. Tôi không biết làm thế nào bạn sẽ làm điều đó trong Delphi tuy nhiên. –

+3

'TBalloonHint' xuất phát từ' TCustomHint', bao bọc điều khiển chú giải công cụ Windows, nhưng 'TBalloonHint' không sử dụng kiểu' TTS_BALLOON', mà 'TTS_CLOSE' yêu cầu. 'TBalloonHint' là một chú giải công cụ được vẽ tùy chỉnh bắt chước chú giải công cụ chú giải quả bóng mà không thực sự là một chú giải, theo như Windows liên quan. Bạn có thể lấy được từ 'TBalloonHint' và ghi đè' PaintHint() 'để vẽ nút đóng của riêng bạn, nhưng nó sẽ không hoạt động như một nút. –

Trả lời

7

Trước tiên, bạn cần một thủ tục để hiển thị gợi ý của bạn:

uses 
    CommCtrl; 

// hWnd - control window handle to attach the baloon to. 
// Icon - icon index; 0 = none, 1 = info, 2 = warning, 3 = error. 
// BackCL - background color or clDefault to use system setting. 
// TextCL - text and border colors or clDefault to use system setting. 
// Title - tooltip title (bold first line). 
// Text - tooltip text. 

procedure ShowBalloonTip(hWnd: THandle; Icon: integer; BackCL, TextCL: TColor; Title: pchar; Text: PWideChar); 
const 
    TOOLTIPS_CLASS = 'tooltips_class32'; 
    TTS_ALWAYSTIP = $01; 
    TTS_NOPREFIX = $02; 
    TTS_BALLOON = $40; 
    TTF_SUBCLASS = $0010; 
    TTF_TRANSPARENT = $0100; 
    TTF_CENTERTIP = $0002; 
    TTM_ADDTOOL = $0400 + 50; 
    TTM_SETTITLE = (WM_USER + 32); 
    ICC_WIN95_CLASSES = $000000FF; 
type 
    TOOLINFO = packed record 
    cbSize: integer; 
    uFlags: integer; 
    hWnd: THandle; 
    uId: integer; 
    rect: TRect; 
    hinst: THandle; 
    lpszText: PWideChar; 
    lParam: integer; 
    end; 

var 
    hWndTip: THandle; 
    ti: TOOLINFO; 
begin 
    hWndTip := CreateWindow(TOOLTIPS_CLASS, nil, WS_POPUP or TTS_CLOSE or TTS_NOPREFIX or TTS_BALLOON or TTS_ALWAYSTIP, 0, 0, 0, 0, hWnd, 0, HInstance, nil); 

    if hWndTip <> 0 then 
    begin 
    SetWindowPos(hWndTip, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE); 

    ti.cbSize := SizeOf(ti); 
    ti.uFlags := TTF_CENTERTIP or TTF_TRANSPARENT or TTF_SUBCLASS; 
    ti.hWnd := hWnd; 
    ti.lpszText := Text; 

    Windows.GetClientRect(hWnd, ti.rect); 
    if BackCL <> clDefault then 
     SendMessage(hWndTip, TTM_SETTIPBKCOLOR, BackCL, 0); 

    if TextCL <> clDefault then 
     SendMessage(hWndTip, TTM_SETTIPTEXTCOLOR, TextCL, 0); 

    SendMessage(hWndTip, TTM_ADDTOOL, 1, integer(@ti)); 
    SendMessage(hWndTip, TTM_SETTITLE, Icon mod 4, integer(Title)); 

    //TTM_TRACKACTIVATE => Makes sure you have to close the hint you self 
    SendMessage(hWndTip, TTM_TRACKACTIVATE, integer(true), integer(@ti)); 
    end; 
end; 

Sau đó gọi nó là:

ShowBalloonTip(Button1.Handle, 4, clDefault, clRed, 'Baloon Title', 'Baloon text'); 

Gợi ý: nếu bạn không có hWnd (ví dụ nút Speed ​​hoặc đồ họa khác thành phần) hoặc muốn hiển thị baloon ở nơi khác, hãy gửi tin nhắn TTM_TRACKPOSITION sau TTM_SETTITLE.

***** EDIT *****

này cũng có thể được thực hiện thông qua một lớp helper

Đầu tiên tạo ra một đơn vị với một helper Lớp

unit ComponentBaloonHintU; 

interface 
uses 
    Controls, CommCtrl, Graphics; 

{$SCOPEDENUMS ON} 

type 
    TIconKind = (None = TTI_NONE, Info = TTI_INFO, Warning = TTI_WARNING, Error = TTI_ERROR, Info_Large = TTI_INFO_LARGE, Warning_Large = TTI_WARNING_LARGE, Eror_Large = TTI_ERROR_LARGE); 
    TComponentBaloonhint = class helper for TWinControl 
    public 
    procedure ShowBalloonTip(Icon: TIconKind; const Title, Text: string); 
    end; 

implementation 
uses 
    Windows; 

{ TComponentBaloonhint } 

procedure TComponentBaloonhint.ShowBalloonTip(Icon: TIconKind; const Title, Text: string); 
var 
    hWndTip: THandle; 
    ToolInfo: TToolInfo; 
    BodyText: pWideChar; 
begin 
    hWndTip := CreateWindow(TOOLTIPS_CLASS, nil, WS_POPUP or TTS_CLOSE or TTS_NOPREFIX or TTS_BALLOON or TTS_ALWAYSTIP, 0, 0, 0, 0, Handle, 0, HInstance, nil); 

    if hWndTip = 0 then 
    exit; 

    GetMem(BodyText, 2 * 256); 

    try 
    ToolInfo.cbSize := SizeOf(TToolInfo); 
    ToolInfo.uFlags := TTF_CENTERTIP or TTF_TRANSPARENT or TTF_SUBCLASS; 
    ToolInfo.hWnd := Handle; 
    ToolInfo.lpszText := StringToWideChar(Text, BodyText, 2 * 356); 
    SetWindowPos(hWndTip, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE); 
    ToolInfo.Rect := GetClientRect; 

    SendMessage(hWndTip, TTM_ADDTOOL, 1, integer(@ToolInfo)); 
    SendMessage(hWndTip, TTM_SETTITLE, integer(Icon), integer(PChar(Title))); 
    SendMessage(hWndTip, TTM_TRACKACTIVATE, integer(true), integer(@ToolInfo)); 
    finally 
    FreeMem(BodyText); 
    end; 
end; 

end. 

Sau đó gọi:

uses 
    ComponentBaloonHintU; 

procedure TForm1.Button1Click(Sender: TObject); 
begin 
    Button1.ShowBalloonTip(TIconKind.Eror_Large, 'Baloon Title', 'Baloon text'); 
end; 
+1

Rất đẹp! Lưu ý rằng trên các phiên bản mới hơn của Delphi (Tôi đang sử dụng XE5), bạn không nên sử dụng các hằng số này và bản ghi TOOLINFO vì chúng không phải là các phiên bản Unicode. Những cái đúng được xác định trong CommCtrl bây giờ. Các số nguyên phôi trong SendMessage nên được thay đổi thành wparam và lparam phôi. – MarkF

+1

Cảm ơn bạn đã cập nhật @MarkF Tôi đã nghĩ đến việc tạo nó thành một thành phần, và sau đó tôi có thể khắc phục các vấn đề bạn vừa liệt kê –

+1

Hoạt động rất tốt. Trên Windows Vista và phiên bản mới hơn, chúng tôi cũng có thể sử dụng các biểu tượng sau: 4 = TTI_INFO_LARGE, 5 = TTI_WARNING_LARGE, 6 = TTI_ERROR_LARGE (http://msdn.microsoft.com/en-us/library/windows/desktop/bb760414(v=vs. 85) .aspx) – Pol

Các vấn đề liên quan