我正在創建一個帶有附加樣式的氣球工具提示 ( TTS_BALLOON ),該樣式使“X”出現在此氣球的右上角以關閉它 ( TTS_CLOSE )。
我正在創建的工具提示型別是“跟蹤”,即我通過TTM_TRACKACTIVATE訊息按需顯示工具提示,正如 MSDN 上正確解釋的那樣。ToolTip 作業正常,在發送訊息TTM_TRACKACTIVATE時顯示/隱藏,但是,在顯示 ToolTip 并單擊“X”后,它被正確隱藏,但不再可能以任何方式再次顯示 ToolTip,甚至使用TTM_TRACKACTIVATE,也不使用TTM_POPUP。在 Visual Studio 論壇(https://social.msdn.microsoft.com/Forums/vstudio/en-US/8ff12b85-c0a5-4a69-87d5-0a13ea9c43b0/help-with-ttsclose-style)和直到今天,作者也沒有得到答案。
說到TTM_POPUP及其對應物TTM_POP,在發送TTM_POP訊息后,“從螢屏上洗掉工具提示”,我無法再顯示它,無論是使用TTM_POPUP還是使用TTM_TRACKACTIVATE,即TTM_POP具有與單擊相同的效果“X”,據我了解,它只會破壞工具提示并使其無法使用。
我正在用 Pascal (Delphi) 開發一個類,以促進 ToolTips 的創建和操作,現在我正在處理TTS_CLOSE,我不明白為什么會發生這種情況。這是正常的?它是 Windows API 錯誤嗎?
下面是一個示例代碼。要重現此問題,請創建一個型別為Windows VCL Application的專案,其唯一的 TForm 稱為Form1 ,并在此 TForm 中放置一個名為BUTNHint的 TButton。然后將下面的代碼完全粘貼到 TForm 的單元中,然后雙擊添加的按鈕和 TForm 的 OnShow 和 OnCreate 事件以連接處理程式。
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
BUTNHint: TButton;
procedure FormCreate(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure BUTNHintClick(Sender: TObject);
private
{ Private declarations }
FToolTipWindowHandle: HWND;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses
Winapi.CommCtrl;
{$R *.dfm}
procedure TForm1.BUTNHintClick(Sender: TObject);
var
ToolInfo: TToolInfo;
begin
if not (SendMessage(FToolTipWindowHandle,TTM_GETCURRENTTOOL,0,0) > 0) then
begin
ZeroMemory(@ToolInfo,SizeOf(TToolInfo));
ToolInfo.cbSize := SizeOf(TToolInfo);
SendMessage(FToolTipWindowHandle,TTM_TRACKACTIVATE,WPARAM(True),LPARAM(@ToolInfo));
end
else
begin
ZeroMemory(@ToolInfo,SizeOf(TToolInfo));
ToolInfo.cbSize := SizeOf(TToolInfo);
SendMessage(FToolTipWindowHandle,TTM_TRACKACTIVATE,WPARAM(False),LPARAM(@ToolInfo));
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
FToolTipWindowHandle := CreateWindowEx(WS_EX_NOACTIVATE or WS_EX_TOPMOST
,TOOLTIPS_CLASS
,nil
,TTS_NOPREFIX or TTS_ALWAYSTIP or TTS_BALLOON or TTS_CLOSE
,0,0,0,0
,TApplication(Owner).Handle
,0
,HInstance
,nil);
SendMessage(FToolTipWindowHandle,TTM_SETMAXTIPWIDTH,0,500);
SendMessage(FToolTipWindowHandle,TTM_SETTITLE,TTI_INFO,LPARAM(PChar('Título do ToolTip neste SSCCE')));
end;
procedure TForm1.FormShow(Sender: TObject);
var
ToolInfo: TToolInfo;
begin
ZeroMemory(@ToolInfo,SizeOf(TToolInfo));
ToolInfo.cbSize := SizeOf(TToolInfo);
ToolInfo.uFlags := TTF_TRACK or TTF_PARSELINKS;
ToolInfo.lpszText := 'Lorem ipsum dolor <a id="zzz">sit</a> amet, consectetur adipiscing ' 'elit. Nunc eu vulputate ipsum, in dignissim velit. Donec vitae massa rhoncus, tincidunt enim sit amet, venenatis augue. Fusce fringilla pellentesque ligula, ac facilisis enim feugiat a. Nam lacinia eu sed.';
SendMessage(FToolTipWindowHandle,TTM_ADDTOOL,0,LPARAM(@ToolInfo));
end;
end.
運行程式時,按下按鈕顯示工具提示并再次單擊它以隱藏工具提示。請注意,這可以一遍又一遍地完成,但是,如果您通過單擊其關閉按鈕 ( X ) 來關閉 ToolTip,則 ToolTip 將不再出現,即使多次單擊 TForm 上的現有按鈕也是如此。
uj5u.com熱心網友回復:
在Sertac Akyuz發現單擊具有TTS_CLOSE樣式集的工具提示氣球上的“X”按鈕時實際發生的情況后,我能夠通過簡單地在實際顯示之前強制隱藏工具提示來解決問題:
procedure TForm1.BUTNHintClick(Sender: TObject);
var
ToolInfo: TToolInfo;
begin
if not (SendMessage(FToolTipWindowHandle,TTM_GETCURRENTTOOL,0,0) > 0) then
begin
ZeroMemory(@ToolInfo,SizeOf(TToolInfo));
ToolInfo.cbSize := SizeOf(TToolInfo);
// Hide the ToolTip window to somehow "synchronize" the internal state of it with the
// real visibility state, so, the message to show will be successful
SendMessage(FToolTipWindowHandle,TTM_TRACKACTIVATE,WPARAM(False),LPARAM(@ToolInfo));
SendMessage(FToolTipWindowHandle,TTM_TRACKACTIVATE,WPARAM(True),LPARAM(@ToolInfo));
end
else
begin
ZeroMemory(@ToolInfo,SizeOf(TToolInfo));
ToolInfo.cbSize := SizeOf(TToolInfo);
SendMessage(FToolTipWindowHandle,TTM_TRACKACTIVATE,WPARAM(False),LPARAM(@ToolInfo));
end;
end;
根據Sertac Akyuz的發現,我得出的結論是,當使用“X”關閉氣球時,TooTip 視窗是隱藏的,但是它的一些內部控制,指的是 TTM_TRACKACTIVATE 訊息的處理沒有更新,這這樣,在內部,工具提示視窗“認為”它已經可見,并簡單地忽略應該顯示它的 TTM_TRACKACTIVATE 訊息。在顯示之前隱藏工具提示視窗會導致實際發生的事情和視窗“認為”正在發生的事情之間的一種同步。
對我來說這是一個錯誤,因為在官方檔案中沒有提到單擊“X”按鈕時會發生什么,如果沒有檔案說這是功能,主要是因為它是這樣作業的在我看來,這確實是一個錯誤。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/440062.html
下一篇:C:Windows沒有找到HARDWARE\DEVICEMAP\SERIALCOMM,即使可以使用regedit找到它
