2013-09-23 2 views
2

Я пытаюсь использовать TCustomHint, чтобы показать сообщение моему пользователю, которое легко исчезает и выходит, чтобы не быть слишком отвлекающим. Однако, когда я вызываю ShowHint на моем объекте с точкой, поле подсказки кажется центрированным вокруг точки, которую я даю. Я бы хотел, чтобы мой ящик выглядел таким, что его верхняя левая координата - это точка.Остановить TCustomHint от центрирования себя вокруг моей точки

Вот код, я использую так показать подсказку:

procedure ShowNotification(ATitle: UnicodeString; AMsg: UnicodeString); 
var 
    Box: TCustomHint; 
    P: TPoint; 
begin 
    Box := TCustomHint.Create(MyForm); 
    Box.Title := ATitle; 
    Box.Description := AMsg; 
    Box.Delay := 0; 
    Box.HideAfter := 5000; 
    Box.Style := bhsStandard; 

    P.X := 0; 
    P.Y := 0; 

    Box.ShowHint(P); 
end; 

Я знаю, что координаты X/Y моей точки являются не по отношению к форме, и это не проблема.

Я проследил через то, что происходит, когда я называю ShowHint и, кажется, что если я могу каким-то образом контролировать конечную ширину базовой TCustomHintWindow внутри TCustomHint.ShowHint(Rect: TRect) тогда я могу быть в бизнесе.

Так что мой вопрос: есть ли очевидный способ остановить TCustomHint от центрирования себя по моей точке? Или мне придется пройти процесс наследования, переопределив метод draw и т. Д. И т. Д.? Надеюсь, я просто пропустил что-то простое.

ответ

2

Нет особо простого способа сделать то, что вы хотите. Класс TCustomHint предназначен для использования в очень специфической цели. Он был спроектирован для использования в собственности TControl.CustomHint. Вы можете увидеть, как это называется, просмотрев код для TCustomHint.ShowHint. Соответствующие выдержки:

if Control.CustomHint = Self then 
begin 
    .... 
    GetCursorPos(Pos); 
end 
else 
    Pos := Control.ClientToScreen(Point(Control.Width div 2, Control.Height)); 
ShowHint(Pos); 

Таким образом, либо управления показаны по центру в горизонтальном направлении вокруг текущей позиции курсора, или по центру по горизонтали вокруг середины связанного элемента управления.

Я думаю, что нижняя строка здесь состоит в том, что TCustomHint не предназначен для использования так, как вы используете это.

Во всяком случае, есть довольно ужасный способ заставить ваш код делать то, что вы хотите. Вы можете создать временный TCustomHintWindow, который вы никогда не показываете и не используете, чтобы выработать ширину окна подсказки, которое вы хотите показать. И затем используйте это, чтобы переместить точку, которую вы передаете в окно реального подсказки. Чтобы сделать это, вы должны взломать частных членов TCustomHintWindow.

type 
    TCustomHintWindowCracker = class helper for TCustomHintWindow 
    private 
    procedure SetTitleDescription(const Title, Description: string); 
    end; 

procedure TCustomHintWindowCracker.SetTitleDescription(const Title, Description: string); 
begin 
    Self.FTitle := Title; 
    Self.FDescription := Description; 
end; 

procedure ShowNotification(ATitle: UnicodeString; AMsg: UnicodeString); 
var 
    Box: TCustomHint; 
    SizingWindow: TCustomHintWindow; 
    P: TPoint; 
begin 
    Box := TCustomHint.Create(Form5); 
    Box.Title := ATitle; 
    Box.Description := AMsg; 
    Box.Delay := 0; 
    Box.HideAfter := 5000; 
    Box.Style := bhsStandard; 

    P := Point(0, 0); 
    SizingWindow := TCustomHintWindow.Create(nil); 
    try 
    SizingWindow.HintParent := Box; 
    SizingWindow.HandleNeeded; 
    SizingWindow.SetTitleDescription(ATitle, AMsg); 
    SizingWindow.AutoSize; 
    inc(P.X, SizingWindow.Width div 2); 
    finally 
    SizingWindow.Free; 
    end; 
    Box.ShowHint(P); 
end; 

Это делает то, что вы просили, но, честно говоря, это заставляет меня чувствовать себя довольно тошнотворно.

+1

Спасибо за ответ. Мне нужно будет попотеть, лучше ли это делать так, или если я просто использую TCustomHint как «вдохновение» и просто создаю свой собственный класс с нуля. Опираясь больше на второе. – bstamour

 Смежные вопросы

  • Нет связанных вопросов^_^