Page 1 of 2

Posted: Tue Mar 25, 2003 1:56 am
by BackupUser
Restored from previous forum. Originally posted by LJ.

Here is the code Timo posted that does not leak. The only difference is the procedure AddButtonToolTip(Handle,Text$) and the calls to it. The .exe leaks about 4K every 3 clicks of the button. The leak must be in the AddButtonToolTip procedure. Is this an incorrect use of the AddButtonToolTip procedure or is it a leak bug?

Procedure AddButtonToolTip(Handle,Text$)
#TTS_BALLOON = $40
ToolTipControl=CreateWindowEx_(0,"tooltips_class32","",$D0000000|#TTS_BALLOON,0,0,0,0,WindowID(),0,GetModuleHandle_(0),0)
sendMessage_(ToolTipControl,1044,0 ,0) ;ForeColor Tooltip
sendMessage_(ToolTipControl,1043,$58F5D6,0) ;BackColor Tooltip
sendMessage_(ToolTipControl,1048,0,180) ;Maximum Width of tooltip
Button.TOOLINFO\cbSize=84 ; SizeOf( TOOLINFO )
Button\uFlags=$11
Button\hWnd=Handle
Button\uId=Handle
Button\lpszText=@Text$
SendMessage_(ToolTipControl,$0404,0,Button)
EndProcedure

OpenWindow(1, 128, 96, 320, 256, #PB_Window_SystemMenu|#PB_Window_MinimizeGadget, "Background image example")
CreateGadgetList(WindowID())
CreateImage(1, WindowWidth(), WindowHeight())
StartDrawing(ImageOutput())
Box(0, 0, WindowWidth(), WindowHeight(), $ff)
FrontColor(0, 0, 0)
DrawingMode(1)
DrawingFont(LoadFont(0, "Times New Roman", 16))
Locate(64, 32)
DrawText("Background image")
StopDrawing()
ImageGadget(1, 0, 0, WindowWidth(), WindowHeight(), UseImage(1))
ButtonGadget = ButtonGadget(0, 80, 64, 160, 128, "My Button")
AddButtonToolTip(ButtonGadget,"Test message.")

LoadFont(0, "Times New Roman", 16)

Repeat
EventID = WaitWindowEvent()
If EventID = #PB_EventGadget
Select EventGadgetID()

Case 0
Gosub UpdateWindow

EndSelect
EndIf


Until EventID = #PB_EventCloseWindow
End

UpdateWindow:
FreeGadget (0)
UseImage(1)
StartDrawing(ImageOutput())
Box(0, 0, WindowWidth(), WindowHeight(), $ff)
FrontColor(0, 0, 0)
DrawingMode(1)
DrawingFont(UseFont(0))
Locate(64, 32)
DrawText("Test image")
StopDrawing()
ButtonGadget = ButtonGadget(0, 80, 64, 160, 128, "My Button")
AddButtonToolTip(ButtonGadget,"Test message.")
SetGadgetState(1, UseImage(1))
ActivateGadget(0)
Return

Posted: Tue Mar 25, 2003 8:34 am
by BackupUser
Restored from previous forum. Originally posted by fred.

You create everytime a new window 'ToolTipControl' without free it...

Fred - AlphaSND

Posted: Tue Mar 25, 2003 2:33 pm
by BackupUser
Restored from previous forum. Originally posted by ebs.

I use the same code, but I made a procedure called "ChangeButtonToolTip(Handle, Text$)". It doesn't create a new window, it just changes the text in the existing window.

To make "ChangeButtonToolTip()", all you need to do is remove the first four lines of the "AddButtonToolTip()" procedure, so it starts with the line:

Button.TOOLINFO\cbSize=84 ; SizeOf( TOOLINFO )

Use "AddButtonToolTip()" to initially create the tooltip, then use "ChangeButtonToolTip()" from then on to change the tooltip text. I use this method to show descriptions of each item in a ListIconGadget and I haven't had any memory leak problems.

Eric
Originally posted by fred

You create everytime a new window 'ToolTipControl' without free it...

Fred - AlphaSND

Posted: Tue Mar 25, 2003 2:44 pm
by BackupUser
Restored from previous forum. Originally posted by LJ.

Eric: The problem with that is in my application is that the button is destroyed and so a new association with a tooltip needs to be established when the button is created again as in the example code I posted.

Posted: Tue Mar 25, 2003 3:10 pm
by BackupUser
Restored from previous forum. Originally posted by Pupil.

LJ: you need to destroy the old tooltipwindow before creating a new one, as to the question you ask in the topic of this thread - "Programming error" is the right answer :wink:

Posted: Tue Mar 25, 2003 3:14 pm
by BackupUser
Restored from previous forum. Originally posted by ebs.

LJ,

Right - I guess I should have read your posted code more carefully!

Couldn't you just save the tooltip window handle and do something like this?

DestroyWindow_(ToolTipControl)

Regards,
Eric


Originally posted by LJ

Eric: The problem with that is in my application is that the button is destroyed and so a new association with a tooltip needs to be established when the button is created again as in the example code I posted.

Posted: Tue Mar 25, 2003 3:43 pm
by BackupUser
Restored from previous forum. Originally posted by LJ.

That's okay Eric, I thank you for posting. I've been trying the Destroy Window and nothing works. Here's the code:


Procedure AddButtonToolTip(Handle,Text$)
#TTS_BALLOON = $40
ToolTipControl=CreateWindowEx_(0,"tooltips_class32","",$D0000000|#TTS_BALLOON,0,0,0,0,WindowID(),0,GetModuleHandle_(0),0)
sendMessage_(ToolTipControl,1044,0 ,0) ;ForeColor Tooltip
sendMessage_(ToolTipControl,1043,$58F5D6,0) ;BackColor Tooltip
sendMessage_(ToolTipControl,1048,0,180) ;Maximum Width of tooltip
Button.TOOLINFO\cbSize=84 ; SizeOf( TOOLINFO )
Button\uFlags=$11
Button\hWnd=Handle
Button\uId=Handle
Button\lpszText=@Text$
SendMessage_(ToolTipControl,$0404,0,Button)
EndProcedure

OpenWindow(1, 128, 96, 320, 256, #PB_Window_SystemMenu|#PB_Window_MinimizeGadget, "Background image example")
CreateGadgetList(WindowID())
CreateImage(1, WindowWidth(), WindowHeight())
StartDrawing(ImageOutput())
Box(0, 0, WindowWidth(), WindowHeight(), $ff)
FrontColor(0, 0, 0)
DrawingMode(1)
DrawingFont(LoadFont(0, "Times New Roman", 16))
Locate(64, 32)
DrawText("Background image")
StopDrawing()
ImageGadget(1, 0, 0, WindowWidth(), WindowHeight(), UseImage(1))
ButtonGadget = ButtonGadget(0, 80, 64, 160, 128, "My Button")
AddButtonToolTip(ButtonGadget,"Test message.")
LoadFont(0, "Times New Roman", 16)
DestroyWindow_(ToolTipControl)

Repeat
EventID = WaitWindowEvent()
If EventID = #PB_EventGadget
Select EventGadgetID()

Case 0
Gosub UpdateWindow

EndSelect
EndIf


Until EventID = #PB_EventCloseWindow
End

UpdateWindow:
;DestroyWindow_(ButtonGadget)
DestroyWindow_(ToolTipControl)
FreeGadget (0)
UseImage(1)
StartDrawing(ImageOutput())
Box(0, 0, WindowWidth(), WindowHeight(), $ff)
FrontColor(0, 0, 0)
DrawingMode(1)
DrawingFont(UseFont(0))
Locate(64, 32)
DrawText("Test image")
StopDrawing()
ButtonGadget = ButtonGadget(0, 80, 64, 160, 128, "My Button")
AddButtonToolTip(ButtonGadget,"Test message.")
SetGadgetState(1, UseImage(1))
ActivateGadget(0)
Return

As you can see, under UpdateWindow: I've tried destroying both tooltipcontrol and the buttongadget (; remed one so you could see) and the .exe still links about 4K every few clicks of the button, any suggestions?

Posted: Tue Mar 25, 2003 3:56 pm
by BackupUser
Restored from previous forum. Originally posted by ebs.

LJ,

Is ToolTipControl a Global variable? If not, the calls to DestroyWindow_(ToolTipControl) won't work, since ToolTipControl has a value of zero outside of the AddButtonToolTip() procedure.

I would suggest either: make ToolTipControl a Global variable, or change AddButtonToolTip to return it's value, like this:

Code: Select all

Procedure.l AddButtonToolTip(Handle,Text$)
 #TTS_BALLOON = $40
ToolTipControl=CreateWindowEx_(0,"tooltips_class32","",$D0000000|#TTS_BALLOON,0,0,0,0,WindowID(),0,GetModuleHandle_(0),0) 
sendMessage_(ToolTipControl,1044,0 ,0)          ;ForeColor Tooltip
sendMessage_(ToolTipControl,1043,$58F5D6,0)     ;BackColor Tooltip
sendMessage_(ToolTipControl,1048,0,180)         ;Maximum Width of tooltip
Button.TOOLINFO\cbSize=84 ; SizeOf( TOOLINFO )
Button\uFlags=$11
Button\hWnd=Handle
Button\uId=Handle
Button\lpszText=@Text$
SendMessage_(ToolTipControl,$0404,0,Button)
ProcedureReturn ToolTipControl
EndProcedure
This way, you can save the tooltip window handle when you create it:

Code: Select all

hToolTip.l = AddButtonToolTip(ButtonGadget,"Test message.")
and use the saved handle for DestroyWindow_:

Code: Select all

DestroyWindow_(hToolTip)
I haven't tried it, but I think this should work.

Eric

Originally posted by LJ

That's okay Eric, I thank you for posting. I've been trying the Destroy Window and nothing works. Here's the code:


Procedure AddButtonToolTip(Handle,Text$)
#TTS_BALLOON = $40
ToolTipControl=CreateWindowEx_(0,"tooltips_class32","",$D0000000|#TTS_BALLOON,0,0,0,0,WindowID(),0,GetModuleHandle_(0),0)
sendMessage_(ToolTipControl,1044,0 ,0) ;ForeColor Tooltip
sendMessage_(ToolTipControl,1043,$58F5D6,0) ;BackColor Tooltip
sendMessage_(ToolTipControl,1048,0,180) ;Maximum Width of tooltip
Button.TOOLINFO\cbSize=84 ; SizeOf( TOOLINFO )
Button\uFlags=$11
Button\hWnd=Handle
Button\uId=Handle
Button\lpszText=@Text$
SendMessage_(ToolTipControl,$0404,0,Button)
EndProcedure

OpenWindow(1, 128, 96, 320, 256, #PB_Window_SystemMenu|#PB_Window_MinimizeGadget, "Background image example")
CreateGadgetList(WindowID())
CreateImage(1, WindowWidth(), WindowHeight())
StartDrawing(ImageOutput())
Box(0, 0, WindowWidth(), WindowHeight(), $ff)
FrontColor(0, 0, 0)
DrawingMode(1)
DrawingFont(LoadFont(0, "Times New Roman", 16))
Locate(64, 32)
DrawText("Background image")
StopDrawing()
ImageGadget(1, 0, 0, WindowWidth(), WindowHeight(), UseImage(1))
ButtonGadget = ButtonGadget(0, 80, 64, 160, 128, "My Button")
AddButtonToolTip(ButtonGadget,"Test message.")
LoadFont(0, "Times New Roman", 16)
DestroyWindow_(ToolTipControl)

Repeat
EventID = WaitWindowEvent()
If EventID = #PB_EventGadget
Select EventGadgetID()

Case 0
Gosub UpdateWindow

EndSelect
EndIf


Until EventID = #PB_EventCloseWindow
End

UpdateWindow:
;DestroyWindow_(ButtonGadget)
DestroyWindow_(ToolTipControl)
FreeGadget (0)
UseImage(1)
StartDrawing(ImageOutput())
Box(0, 0, WindowWidth(), WindowHeight(), $ff)
FrontColor(0, 0, 0)
DrawingMode(1)
DrawingFont(UseFont(0))
Locate(64, 32)
DrawText("Test image")
StopDrawing()
ButtonGadget = ButtonGadget(0, 80, 64, 160, 128, "My Button")
AddButtonToolTip(ButtonGadget,"Test message.")
SetGadgetState(1, UseImage(1))
ActivateGadget(0)
Return

As you can see, under UpdateWindow: I've tried destroying both tooltipcontrol and the buttongadget (; remed one so you could see) and the .exe still links about 4K every few clicks of the button, any suggestions?

Posted: Tue Mar 25, 2003 4:15 pm
by BackupUser
Restored from previous forum. Originally posted by fred.

you need to put 'ToolTipContro' Shared or global.. it's a local variable.

Fred - AlphaSND

Posted: Wed Mar 26, 2003 8:40 am
by BackupUser
Restored from previous forum. Originally posted by gnozal.

This should work.
;
; Use AddButtonToolTip() to create a tooltip,
; Use ChangeButtonToolTip() to change an existing tooltip,
; Use DestroyWindow_() to free the tooltip.
;
; --------------
; Create Tooltip
Procedure.l AddButtonToolTip(Handle.l,Text.s)
#TTS_BALLOON = $40
ToolTipControl.l = CreateWindowEx_(0,"tooltips_class32","",$D0000000|#TTS_BALLOON,0,0,0,0,WindowID(),0,GetModuleHandle_(0),0)
sendMessage_(ToolTipControl,1044,0 ,0) ; ForeColor Tooltip
sendMessage_(ToolTipControl,1043,$58F5D6,0) ; BackColor Tooltip
sendMessage_(ToolTipControl,1048,0,180) ; Maximum Width of tooltip
Button.TOOLINFO\cbSize=84 ; SizeOf( TOOLINFO )
Button\uFlags=$11
Button\hWnd=Handle
Button\uId=Handle
Button\lpszText=@Text
SendMessage_(ToolTipControl,$0404,0,Button)
ProcedureReturn ToolTipControl
EndProcedure
; Change text of an existing ToolTip
Procedure ChangeButtonToolTip(ToolTipControl.l,Handle.l,Text.s)
Button.TOOLINFO\cbSize=84 ; SizeOf( TOOLINFO )
Button\uFlags=$11
Button\hWnd=Handle
Button\uId=Handle
Button\lpszText=@Text
SendMessage_(ToolTipControl,$0404,0,Button)
EndProcedure
; ----------
; Exemple
; Create button and his tooltip
HandleButtonGadget.l = ButtonGadget(#Gadget, 80, 64, 160, 128, "My Button")
HandleButtonToolTip.l = AddButtonToolTip(HandleButtonGadget,"Test message 1.")
; or
HandleButtonToolTip.l = AddButtonToolTip(GadgetID(#Gadget),"Test message 1.")
; Change tooltip
ChangeButtonToolTip(HandleButtonToolTip,HandleButtonGadget,"Test message 2.")
; Destroy button and free the tooltip
DestroyWindow_(HandleButtonToolTip)
FreeGadget(#Gadget)
; HandleButtonToolTip & HandleButtonGadget are global

Posted: Wed Mar 26, 2003 2:50 pm
by BackupUser
Restored from previous forum. Originally posted by LJ.

Gnozal: code very buggy, doesn't work but thank you.

Pupil: Yes, and the person who created the AddToolTip API code needs to be punished for not including the code that destroys the ToolTip Window for us beginners. :wink:

Fred and Ebs: Thank you, got it. The DestroyWindow destroys only one instance of the ToolTip. If multiple ToolTips are added on multiple buttons, then the DestroyWindow doesn't work for all of them. The workaround is to create an AddToolTip procedure for each button that has a tool tip, this way seperate handles are created for each tooltip window so that it can be destroyed.

To illustrate how NOT to destroy a tool tip, the code is below. Notice that a tool tip is added to 2 buttons, then the destroy window command is called; however, the code still leaks because 2 buttons share the addtooltip window handle:

Global ToolTipControl

Procedure AddButtonToolTip(Handle,Text$)
#TTS_BALLOON = $40
ToolTipControl=CreateWindowEx_(0,"tooltips_class32","",$D0000000|#TTS_BALLOON,0,0,0,0,WindowID(),0,GetModuleHandle_(0),0)
sendMessage_(ToolTipControl,1044,0 ,0) ;ForeColor Tooltip
sendMessage_(ToolTipControl,1043,$58F5D6,0) ;BackColor Tooltip
sendMessage_(ToolTipControl,1048,0,180) ;Maximum Width of tooltip
Button.TOOLINFO\cbSize=84 ; SizeOf( TOOLINFO )
Button\uFlags=$11
Button\hWnd=Handle
Button\uId=Handle
Button\lpszText=@Text$
SendMessage_(ToolTipControl,$0404,0,Button)
EndProcedure

OpenWindow(1, 0, 0, 796, 550, #PB_Window_SystemMenu|#PB_Window_MinimizeGadget, "Background image example")
CreateGadgetList(WindowID())
CreateImage(1, WindowWidth(), WindowHeight())
StartDrawing(ImageOutput())
Box(0, 0, WindowWidth(), WindowHeight(), $ff)
FrontColor(0, 0, 0)
DrawingMode(1)
DrawingFont(LoadFont(0, "Times New Roman", 16))
Locate(64, 32)
DrawText("Background image")
StopDrawing()
ImageGadget(1, 0, 0, WindowWidth(), WindowHeight(), UseImage(1))
ButtonGadget = ButtonGadget(0, 80, 64, 160, 128, "My Button")
ButtonGadgettwo = ButtonGadget(2, 80, 204, 160, 128, "My Button Two")
AddButtonToolTip(ButtonGadget,"Test message for Button 1")
AddButtonToolTip(ButtonGadgettwo,"Test message for Button 2")
LoadFont(0, "Times New Roman", 16)

Repeat
EventID = WaitWindowEvent()
If EventID = #PB_EventGadget
Select EventGadgetID()

Case 0
Gosub UpdateWindow

Case 2
Gosub UpdateWindow

EndSelect
EndIf


Until EventID = #PB_EventCloseWindow
End

UpdateWindow:
DestroyWindow_(ToolTipControl)
FreeGadget (0):FreeGadget(2)
UseImage(1)
StartDrawing(ImageOutput())
Box(0, 0, WindowWidth(), WindowHeight(), $ff)
FrontColor(0, 0, 0)
DrawingMode(1)
DrawingFont(UseFont(0))
Locate(64, 32)
DrawText("Test image")
StopDrawing()
ButtonGadget = ButtonGadget(0, 80, 64, 160, 128, "My Button")
ButtonGadgettwo = ButtonGadget(2, 80, 204, 160, 128, "My Button Two")
AddButtonToolTip(ButtonGadget,"Test message for Button 1")
AddButtonToolTip(ButtonGadgettwo,"Test message for Button 2")
SetGadgetState(1, UseImage(1))
ActivateGadget(0)
Return

Posted: Wed Mar 26, 2003 3:09 pm
by BackupUser
Restored from previous forum. Originally posted by fred.

The way you use the handle is not ideal. Just returns its value with a ProcedureReturn and store it in a variable in your program to allow the free later:

Procedure AddButtonToolTip(Handle,Text$)
#TTS_BALLOON = $40
ToolTipControl=CreateWindowEx_(0,"tooltips_class32","",$D0000000|#TTS_BALLOON,0,0,0,0,WindowID
[....]
ProcedureReturn ToolTipControl ; Return the handle !
EndProcedure


ToolTipHandle1 = AddButtonToolTip(...)
ToolTipHandle2 = AddButtonToolTip(...)
ToolTipHandle3 = AddButtonToolTip(...)
....

Then free them all:

DestroyWindow_(ToolTipHandle1)
DestroyWindow_(ToolTipHandle2)
DestroyWindow_(ToolTipHandle3)

I hope this helps..

Fred - AlphaSND

Posted: Wed Mar 26, 2003 4:57 pm
by BackupUser
Restored from previous forum. Originally posted by ebs.

Fred,

I've got the tooltips working well in my application, but I wonder if you know how to use bold text in a tip? For example, like the tooltip on the Win XP shutdown dialog that has "Turn Off" in bold at the top, then the rest of the text not bolded? I can see a way to make all the text bold by changing the font used in the tip, but that's not quite what I'm after. Do tooltips allow any sort of rich text or html format?

Thanks,
Eric

Posted: Wed Mar 26, 2003 8:03 pm
by BackupUser
Restored from previous forum. Originally posted by fred.

I can't exactly remember but I read somewhere than new tooltips supports HTML.. try a :).

Fred - AlphaSND

Posted: Wed Mar 26, 2003 9:52 pm
by BackupUser
Restored from previous forum. Originally posted by Berikco.

HTML...maybe....:)

This should work

Code: Select all

#TTM_SETTITLE = #WM_USER + 32
#TTS_BALLOON = $40
Procedure BaloonTip(WindowID,Gadget,Text$)
  Baloon=CreateWindowEx_(0,"ToolTips_Class32","",$D0000000|#TTS_BALLOON,0,0,0,0,WindowID(WindowID),0,GetModuleHandle_(0),0)
  SendMessage_(Baloon,1044,0,0)
  SendMessage_(Baloon,1043,$DFFFFF,0)
  SendMessage_(Baloon,1048,0,180)
  Parent.TOOLINFO\cbSize=SizeOf(TOOLINFO)
  Parent\uFlags=$11
  Parent\hWnd=GadgetID(Gadget)
  Parent\uId=GadgetID(Gadget)
  Parent\lpszText=@Text$
  SendMessage_(Baloon,$0404,0,Parent)
  Title$="PureBasic, feel the pure power..."
  SendMessage_(Baloon,#TTM_SETTITLE ,1,@Title$)

EndProcedure


OpenWindow(1,200,200,400,300,#PB_Window_SystemMenu,"BaloonTips")
CreateGadgetList(WindowID())
ButtonGadget(1,50,50,150,150,"Ok")
BaloonTip(1,1,"This is the normal text")

Repeat
  EventID=WaitWindowEvent()
Until EventID=#PB_Event_CloseWindow 

Regards,

Berikco

http://users.pandora.be/berikco/purebasic.htm