Le forum (ô combien francophone) des utilisateurs de Powerbuilder.
Bonjour tout le monde,
Après une migration de l'application 7=>12.6 , on a rencontré un problème sur la fonction ToolTipMsg
Appel de la fonction :
If ToolTipMsg( hWndTT, TTM_ADDTOOL, 0, ToolInfo ) = 0 Then message d'erreur
Déclaration :
Function integer ToolTipMsg(long hWnd, long uMsg, long wParam, REF TOOLINFO ToolInfo) library "user32.dll" Alias For "SendMessageA"
Merci d'avance
Hors ligne
Bonjour,
Tu ne nous dis pas non ce qu'est le problème rencontré, mais j'imagine qu'entre la version 7 et 12, il y a le passage à l'unicode; j'aurais bien penser à cela mais je vois que tu références toujours SendMessageA : peut-être ajouter le ";ansi" ?
Penser à vérifier le cbSize de la structure ToolInfo ainsi que le mapping de la structure elle même : https://msdn.microsoft.com/en-us/librar … p/bb760256(v=vs.85).aspx
Ou tout passer en unicode, mais cela risque de chambouler beaucoup de code ( SendMessageW + TTM_ADDTOOLW + REF TOOLINFO )
Hors ligne
Tout d'abord je te remercie pour ta réponse xlat.
La fonction ToolTipMsg retourne un 0 et le message d'erreur s'affiche et je n'arrive pas à voir les infos bulle dans les écran.
J'ai essayé de rajouter ";asni" mais il y a toujours le même problème.
la solution de passage à l'unicode je l'ai pas compris, merci de la détailler un peu.
Merci
Hors ligne
Salut Nico,
xlat a écrit:
entre la version 7 et 12, il y a le passage à l'unicode; j'aurais bien penser à cela mais je vois que tu références toujours SendMessageA : peut-être ajouter le ";ansi" ?
Certain que c'est ça, pour PB7 les appels à l'API utilisent des chaînes uniquement "ansi", alors que pour PB12 (en fait à partir de PB10) sans indication contraire les chaînes échangées avec l'API sont implicitement utf16.
Il faut donc patcher toutes les définitions d'external functions (uniquement si il y a un string dans les paramètres ou le type de retour et si la fonction est la version ansi, comme SendMessageA et pas si la fonction est "wide_char" comme SendMessageW) avec un alias qui précise ";ansi" à la fin.
Mohamed.zdeg a écrit:
J'ai essayé de rajouter ";asni" mais il y a toujours le même problème.
Attention c'est ";ansi" et pas ";asni" ! Par exemple
Alias For "SendMessageA;ansi"
Hors ligne
Voici la déclaration de la fonction
Function integer ToolTipMsg(long hWnd, long uMsg, long wParam, REF TOOLINFO ToolInfo) library "user32.dll" Alias For "SendMessageA;Ansi"
Hors ligne
à tous hazard, il faudrait vérifier tout les paramètres juste avant l'appel : surtout le hwnd et le contenu de la structure TOOLINFO.
Au fait c'est quoi exactement "le message d'erreur" ?
Hors ligne
La fonction retourne 0 :
ToolInfo.cbSize = 40 ToolInfo.uFlags = TTF_SUBCLASS //Flags ToolInfo.hWnd = Handle( ado_Object ) ToolInfo.hInstance= 0 // Not used ToolInfo.uID = ToolID iul_Handle[ToolID] = ToolInfo.hWnd ToolID++ ToolInfo.lpszText = LocalAlloc( 0, 120 ) POST LocalFree( ToolInfo.lpszText ) // Free Allocated Memory lStrCpy( ToolInfo.lpszText, Left( as_tiptext, 120 ) ) // Define the object as a rectangle ToolInfo.Rect.Left = 0 ToolInfo.Rect.Top = 0 ToolInfo.Rect.Right = UnitsToPixels( ado_Object.Width, XUnitsToPixels! ) ToolInfo.Rect.Bottom = UnitsToPixels( ado_Object.Height, YUnitsToPixels! ) if ToolTipMsg( hWndTT, TTM_ADDTOOL, 0, ToolInfo ) 0 then gnv_app.of_MessageBox( "Erreur", "Impossible d'enregistrer un objet dans le contrôle ToolWindow!", StopSign!, Ok!, 1 ) Return( -1 ) End IF
Hors ligne
un rapide test sur windows 7 ou windows 10 m'indique que cbSize devrait être = 72...
fichier a.c :
#include <stdio.h> #include <windows.h> #include <Commctrl.h> void main() { printf("TOOLINFO size = %d\n", sizeof( TOOLINFO )); printf("TOOLINFOW size = %d\n", sizeof( TOOLINFOW )); printf("TOOLINFOA size = %d\n", sizeof( TOOLINFOA )); }
gcc a.c && a.exe
Commence peut-être à revoir l'alimentation de cette structure.
Pour info, une balise code:pb avec BBCode c'est [c0de=pb]TON CODE PB[/c0de] (mais avec un vrai "o" dans c0de)
Hors ligne
Mohamed.zdeg a écrit:
Code: pb
ToolInfo.lpszText = LocalAlloc( 0, 120 ) POST LocalFree( ToolInfo.lpszText ) // Free Allocated Memory
C'est quand même extrêmement optimiste parce du coup le free() de la zone mémoire utiliséee pour transmettre les données du tooltip sera fait "plus tard" quand PB n'aura rien à faire, mais rien ne dit que le système aura eu le temps de traiter l'affichage du tool tip... Moi j'aurais mis le free() sans post() mais après l'appel à ToolTipMsg()...
xlat a écrit:
un rapide test sur windows 7 ou windows 10 m'indique que cbSize devrait être = 72...
ça je dirais que c'est moins grave d'allouer une zone mémoire trop grande, mais j'aurais ajouté un appel du type memset(0) ou calloc() ou l'équivalent WinAPI (je ne suis pas en ce moment sur un Windows pour tester) histoire de ne pas avoir un champ de la structure avec une valeur inconnue
Hors ligne
Hello SeKi,
seki a écrit:
...
xlat a écrit:
un rapide test sur windows 7 ou windows 10 m'indique que cbSize devrait être = 72...
ça je dirais que c'est moins grave d'allouer une zone mémoire trop grande, mais j'aurais ajouté un appel du type memset(0) ou calloc() ou l'équivalent WinAPI (je ne suis pas en ce moment sur un Windows pour tester) histoire de ne pas avoir un champ de la structure avec une valeur inconnue
En fait je parlais de l'initialisation de la structure via le cbSize qui est à 40 dans son code
+1 pour le POST optimiste : fait le test en commentant cette ligne (pas en prod : memory leaks)
Hors ligne
J'ai mis une taille de 72 pour la variable cbSize
et j'ai commenté le POST LocalFree( ToolInfo.lpszText ) (en le fait aprés l'appel de ToolTipMsg.
ToolInfo.cbSize = 72 ToolInfo.uFlags = TTF_SUBCLASS //Flags ToolInfo.hWnd = Handle( ado_Object ) ToolInfo.hInstance= 0 // Not used ToolInfo.uID = ToolID iul_Handle[ToolID] = ToolInfo.hWnd ToolID++ ToolInfo.lpszText = LocalAlloc( 0, 120 ) //POST LocalFree( ToolInfo.lpszText ) // Free Allocated Memory lStrCpy( ToolInfo.lpszText, Left( as_tiptext, 120 ) ) // Define the object as a rectangle ToolInfo.Rect.Left = 0 ToolInfo.Rect.Top = 0 ToolInfo.Rect.Right = UnitsToPixels( ado_Object.Width, XUnitsToPixels! ) ToolInfo.Rect.Bottom = UnitsToPixels( ado_Object.Height, YUnitsToPixels! ) if ToolTipMsg( hWndTT, TTM_ADDTOOL, 0, ToolInfo ) = 0 then gnv_app.of_MessageBox( "Erreur", "Impossible d'enregistrer un objet dans le contrôle ToolWindow!", StopSign!, Ok!, 1 ) Return( -1 ) End If POST LocalFree( ToolInfo.lpszText ) Return ( ToolID - 1 )
Hors ligne
Mais toujours le même problème.
Hors ligne
même en commentant totalement le LocalFree ?
A quelle ligne cela plante ?
Hors ligne
le retour de la fonction ToolTipMsg est 0, donc le message d'erreur s'affiche et la fonction retourne -1.
Hors ligne
xlat a écrit:
En fait je parlais de l'initialisation de la structure via le cbSize qui est à 40 dans son code
Ah oui, je n'avais pas vu. Bon faut dire que j'étais en train d'essayer de faire fonctionner Maven dans une version d'Eclipse dont la gestion du firewall est bugguée, c'était un peu éloigné du dev Windows
xlat a écrit:
+1 pour le POST optimiste : fait le test en commentant cette ligne (pas en prod : memory leaks)
Pas testé, ça ne libère rien ?
Bon sinon comme l'OP n'a pas publié un exemple minimal qui compile et permet de reproduire le cas, j'ai cherché et je suis tombé sur le code original (à mon avis) d'où provient ce wrapper du tool tip système.
On peut noter que sur la page il y a une version PB9 et une autre PB10 déjà convertie aux appels ansi. Cette version fonctionne tel-quel sur un PB11.5 ou 12.5, même avec une taille indiquée dans la structure de 40 octets. Je pense que l'indication de la taille dans la structure permet de gérer plusieurs versions de l'API.(*)
Par contre dans le sample, une fois qu'on a retiré les tooltips de la DW (bouton en bas à gauche) on n'arrive plus à les remettre. Ça fait même planter le PB (pas toujours, et parfois seulement à la fermeture de l'IDE). Et pourtant ToolTipMsg() retourne 1.
(*) EDIT: confirmé par ce post:
The correct size is 44 bytes for Win 2000 and Win XP without common controls 6.0, and 48 bytes for XP with common controls 6.0. If you use the wrong size some of the tooltip messages don't work, while others do.
Hors ligne
sur un pb11.5 en win10 je n'ai aucun problème avec ce code.
Hors ligne
Moi j'ai PB 12.6 et windows 7.
Hors ligne
As-tu essayé de télécharger le code pb10 référencé par seki plus haut ?
Il devrait marcher tel-quel sur ton poste, après une migration en pb12.6.
Hors ligne
xlat a écrit:
sur un pb11.5 en win10 je n'ai aucun problème avec ce code.
Et les 2 boutons Remove / Add tooltip fonctionnent ?
Ici le code a été testé sur un XP (oui, ça date un peu, il faut que je me remonte une machine une peu plus récente. Soyons fous: passons à Win7 ! ).
Ça peut expliquer une différence de fonctionnement.
Hors ligne
Ce code me semblait vaguement familier, et j'ai fini par me rappeler que j'avais déjà intégré cet objet n_tooltip dans pbregexcoach (entre autres ) et que là il ne pause aucun problème de plantage (il y a un menu qui permet d'enlever et remettre les tool tips à volonté).
Au passage il y eu une mise à jour mineure de pbregexcoach et de pbniregex (ce n'est pas un poisson ), et j'en prévois une prochainement car je viens de voir que
"abcd" =~ s/[abcd]/a/g abcd
C'était dans les tests unitaires de pbregexcoach, je n'avais jamais fais gaffe...
Hors ligne