Why using the TTF_CENTERTIP flag makes the ToolTip balloon style back to Windows XP style?

Carlos Barreto Feitoza Filho 21 Reputation points
2022-03-24T14:47:48.16+00:00

I noticed that using the TTF_CENTERTIP flag when adding a ToolTip setting using TTM_ADDTOOL to a ToolTip window that has the TTS_BALLOON style causes this ToolTip to not appear with the Windows 10 style. In other words the balloon appears with rounded edges, as was the style of balloons in Windows XP.

186456-image.png

Without using TTF_CENTERTIP the balloon appears with the correct style as seen above, however...

186533-image.png

When using the TTF_CENTERTIP flag the style changes to "old style". The question is simple, why does this happen and how to make the balloons always have the latest style according to the OS on which the application runs?

Below is the code I use, written in Delphi but easy to understand. The peculiarity of this example lies in the fact that I am trying to show a line of text without breaks and setting the maximum width of the ToolTip to 300 pixels

unit Unit1;  
  
interface  
  
uses  
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,  
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ComCtrls;  
  
type  
  TForm1 = class(TForm)  
    BUTN1: TButton;  
    BUTN2: TButton;  
    procedure FormCreate(Sender: TObject);  
    procedure FormDestroy(Sender: TObject);  
  private  
    { Private declarations }  
    FHwndTip: HWND;  
  public  
    { Public declarations }  
  end;  
  
var  
  Form1: TForm1;  
  
implementation  
  
uses  
  Winapi.CommCtrl;  
  
{$R *.dfm}  
  
procedure TForm1.FormCreate(Sender: TObject);  
var  
  TI: TToolInfo;  
begin  
  FHwndTip := CreateWindowEx(WS_EX_NOACTIVATE or WS_EX_TOPMOST  
                            ,TOOLTIPS_CLASS  
                            ,nil  
                            ,TTS_ALWAYSTIP or TTS_BALLOON  
                            ,0,0,0,0  
                            ,Self.Handle  
                            ,0  
                            ,HInstance  
                            ,nil);  
  
  SendMessage(FHwndTip,TTM_SETTITLE,TTI_INFO,LPARAM(PChar('Title')));  
  SendMessage(FHwndTip,TTM_SETMAXTIPWIDTH,0,300);  
  
  ZeroMemory(@TI,SizeOf(TToolInfo));  
  
  TI.cbSize := SizeOf(TToolInfo);  
  TI.hwnd := Self.Handle; // The Form (or window) in which the button is  
  
  TI.uId := BUTN1.Handle;  
  TI.lpszText := 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque tincidunt dictum dui vel luctus. Duis ornare arcu a varius pharetra. Curabitur tempor sit amet dui id malesuada. Aliquam efficitur, massa consectetur tristique iaculis, dolor diam tincidunt.';  
  TI.uFlags := TTF_IDISHWND or TTF_SUBCLASS;  
  SendMessage(FHwndTip,TTM_ADDTOOL,0,LPARAM(@TI));  
  
  TI.uId := BUTN2.Handle;  
  TI.lpszText := 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque tincidunt dictum dui vel luctus. Duis ornare arcu a varius pharetra. Curabitur tempor sit amet dui id malesuada. Aliquam efficitur, massa consectetur tristique iaculis, dolor diam tincidunt.';  
  TI.uFlags := TTF_IDISHWND or TTF_SUBCLASS or TTF_CENTERTIP;  
  SendMessage(FHwndTip,TTM_ADDTOOL,0,LPARAM(@TI));  
end;  
  
procedure TForm1.FormDestroy(Sender: TObject);  
begin  
  DestroyWindow(FHwndTip);  
end;  
  
end.  

As the ToolTips display depends on manifests, below is the manifest that my application currently uses, in case that is relevant.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>  
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">  
  <asmv3:application>  
    <asmv3:windowsSettings>  
      <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/pm</dpiAware>  
      <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>  
    </asmv3:windowsSettings>  
  </asmv3:application>  
  <dependency>  
    <dependentAssembly>  
      <assemblyIdentity  
        type="win32"  
        name="Microsoft.Windows.Common-Controls"  
        version="6.0.0.0"  
        publicKeyToken="6595b64144ccf1df"  
        language="*"  
        processorArchitecture="*"/>  
    </dependentAssembly>  
  </dependency>  
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">  
    <security>  
      <requestedPrivileges>  
        <requestedExecutionLevel  
          level="asInvoker"  
          uiAccess="false"  
        />  
      </requestedPrivileges>  
    </security>  
  </trustInfo>  
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">   
	<application>   
		<!--The ID below indicates app support for Windows Vista -->  
		<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>   
		<!--The ID below indicates app support for Windows 7 -->  
		<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>  
		<!--The ID below indicates app support for Windows 8 -->  
		<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>  
		<!--The ID below indicates app support for Windows 8.1 -->  
		<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>  
		<!--The ID below indicates app support for Windows 10 -->  
		<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>			  
	</application>   
</compatibility>  
</assembly>  
Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
2,428 questions
{count} votes