Thursday, January 10, 2008

Way back into native: Tooltip

I love Delphi because of its components, I hate Delphi also because of its components. If you really care about user interface, you might find many minor differences between a standard Windows application and a Delphi application. For instance: All shortcuts of menu items are right aligned, when the menu is associated with an image list. When you press ALT, the first button on menubar should be selected. Missing support of chevron on toolbar. The tooltip (known as HintWindow in Delphi) looks different from the native tooltip. In this article I will started with tooltip and tell you how to make it nicer.

Background

In WindowsXP, even you are very careful, you might probably not mention the difference. A Delphi styled tooltip has a gray edge. (Actually it should be black) And there is no shadow under a tooltip either. This issue was not a real issue, until you upgrade to Windows Vista. A native tooltip in Vista [1][2] has rounded corners. Its background is gradient filled. (See the picture below)


Delphi style   vs.   Windows native style

No matter there is a manifest or not, you cannot change a tooltip to its native style. Why? I suppose, that Delphi engineers want to make the HintWindow more customizable, but it is quite difficult to start with the standard TOOLTIPS_CLASS, so they created a HintWindow as a WS_EX_TOOLWINDOW. Now it is easy to build your own styled tooltips, but it is also difficult to reproduce the native style, isn't it?

Solution

The idea is simple: if you do not intend to customize your tooltip, you can replace WS_EX_TOOLWINDOW with TOOLTIPS_CLASS. I have made a patch. You just have to include the NativeHintWindow.pas in your application and build your project again. Done, your nice tooltip is back. If you are using TntControls (or TMSUnicode Controls), there is an extra editon for you. Click here to download. It has been reported to QualityCentral [3] as well.

Conclusion

In this article [4], I have shown a visibility's issue of tooltip control (THintWindow) and have also implemented a patch to fix it. I hope Delphi engineers could pay more attention on such kind of issues. More posts about inconsistencies of user interface are coming soon. So stay tuned ;-)

References

  1. MSDN: Tooltips and Infotips
  2. MSDN: Top Guidelines Violations
  3. Related discuss at QualityCentral
  4. The Chinese version of this article (on my blog @csdn)

7 comments:

Anonymous said...

thanks very useful

Anonymous said...

Hi Stanley,

an annoying Issue - I've posted about it about one year before you ;)

http://qc.codegear.com/wc/qcmain.aspx?d=43452

Best regards
Arvid

stanleyxu (2nd) said...

Hi Arvid, you can replace all THintWindow declaration in your code to THintWindowFix. So far as I known, my modification does not work with DevExpress components.

It is also possible to patch THintWindow directly. You have to change several places in Forms.pas and Controls.pas. I did it once, but I do not recommend you this solution. Once you upgrade your Delphi IDE, you have to modify source again.

BTW: Although the original tooltip in Delphi looks different, it is very powerful for customization. Back to Win9x time, when THintWindow was introduced, it looks exactly as the native tooltip. Considering of backwards compatibility, I think Delphi engineers will probably not modify the existing implementation.

Anonymous said...

Hi Stanley,

Thank you for your reply! I haven't checked your fix, yet as I've already implemented my own fix.

The approach using Forms.pas and Controls.pas is somehow more difficult - I've also investigated this.

But as Borland did for Win9x I think that Embarcadero will be able to implement something comparable for Vista, too...

Regards Arvid

Michael Rockett said...

Hi All

I've had this component for ages - and find it a dream.

However, I wanted to introduce something new. I don't know how to do this, but surely you can customize native hints by sending Windows Messages to them? For example, the hints in Office 2007 have images, bold text, colored text etc.

Is there a way to do this?

Kind regards
Michael

Steve said...

Hello Stanley,

I'd like to ask for your help.

I've tried using your fix with Delphi7 and it works perfectly except for one important thing:

TListView's tooltips aren't shown. The screen is blinking for a sec but the tooltip is not properly shown.

Please note that I'm also using the OnInfoTip event to display custom tooltip text.

I've tried patching ComCtrls.pas and replacing

if Assigend(FOnIntoTip) then
Application.ActivateHint(Mouse.CursorPos);

with


if Assigend(FOnIntoTip) then
ApplicationActivateHint(Mouse.CursorPos);

but it didn't help.

Any ideas for a fix?

Thanks!

Max said...

In fact the default tooltip style was black frame back in win9x/2k times, it was gray only in Office 97/2000/2003.

Similarly, if you click the left mouse button in a left speedbutton (unthemed) and move the mouse away while button is held, the speedbutton will stay raised, instead of going back to its normal state like a TToolButton => consistent with Office 97/2000 behaviour but not with Windows/Shell Control behaviour.