PB 3.93 et formatage dans un EditorGadget

Programmation d'applications complexes
tme007
Messages : 57
Inscription : mar. 26/oct./2004 12:34

PB 3.93 et formatage dans un EditorGadget

Message par tme007 »

L'une de mes applications, un éditeur HTML avec colorisation syntaxique ne fonctionne plus lorsque compilée avec PB 3.93. Dés que j'envoie ce type de 'SendMessage' à l'EditorGadget, mon application est bloquée et je suis bon pour faire un kill du process (si compilée) ou un quit dans le debugger (si je suis en phase de test).

Code : Tout sélectionner

SendMessage_(GadgetID(#Editor_1), #EM_SETSEL, StartPos, Endpos)
SendMessage_(GadgetID(#Editor_1), #EM_SETCHARFORMAT, #SCF_SELECTION, @Format)
Alors que compilée en PB 3.92, il n'y avait aucun problème. Après de nombreux tests, je remarque que cela arrive toujours avec un SendMessage contenant une adresse de variable avec un '@' ...

J'ai le même problème avec ce SendMessage :

Code : Tout sélectionner

SendMessage_(GadgetID(#Editor_1), #EM_SETSEL, StartPos, Endpos)
SendMessage_(GadgetID(#Editor_1), #EM_REPLACESEL, #True, @Minuscule$)
Quelqu'un a t'il déjà rencontré le même problème ? Auriez-vous une idée pour moi ?

Merci d'avance
tme007
Messages : 57
Inscription : mar. 26/oct./2004 12:34

PB 3.93 et formatage dans un EditorGadget

Message par tme007 »

Après des tests supplémentaires, je me suis rendu compte que je me suis complètement planté dans ma première investigation.

Le code ci-dessous est chargé de la colorisation syntaxique du texte contenu dans l'EditorGadget. Il utilise un callback dans lequel j'intercepte la notification EN_CHANGE pour l'EditorGadget, ce qui permet de coloriser le texte au fur et à mesure de la frappe des caractères.

Ce code fonctionne à la perfection sauf dans un cas précis, si l'on modifie le texte de la ligne qui se trouve sous le curseur, le programme boucle sans fin (voir dans la procédure de callback, le HIGHLIGHTLINE(CurrentLine).

Code : Tout sélectionner

Procedure HighlightLine(Line)
  Protected LineText.s, StartPos, Endpos, Left, Right
  Protected Minuscule.s, inst$, Format.CHARFORMAT

  LineText = UCase(GetGadgetItemText(#Editor_1, Line, 0)) 
  StartPos = SendMessage_(GadgetID(#Editor_1), #EM_LINEINDEX, Line, 0)
  Endpos = StartPos + Len(LineText)
  Format\cbSize = SizeOf(CHARFORMAT)
  Format\dwMask = #CFM_COLOR | #CFM_BOLD | #CFM_ITALIC
  SendMessage_(GadgetID(#Editor_1), #EM_SETSEL, StartPos, Endpos)  
  Format\crTextColor = #COLOR_Text
  Format\dwEffects = #EFFECTS_Text 
  SendMessage_(GadgetID(#Editor_1), #EM_SETCHARFORMAT, #SCF_SELECTION, @Format)
  
  ForEach TagHTML()   
    For mode.b = 1 To 2
      Left = StartPos  
      Repeat  
        If mode = 1
          inst$ = TagHTML()\ouvrant
        Else
          If TagHTML()\fermant <> ""
            inst$ = TagHTML()\fermant 
          EndIf
        EndIf
        
        Right = FindString(LineText, inst$, Left - StartPos + 1) + StartPos
        
        If Right = StartPos
          Left = Endpos
        Else
          Left = Right - 1
          Right + Len(inst$) - 1
          SendMessage_(GadgetID(#Editor_1), #EM_SETSEL, Left, Right) 
          Minuscule = LCase(inst$) 
          SendMessage_(GadgetID(#Editor_1), #EM_REPLACESEL, #True, @Minuscule)
          SendMessage_(GadgetID(#Editor_1), #EM_SETSEL, Left, Right)
          Left = Right
          Format\crTextColor = COLOR_Symbol
          Format\dwEffects = #EFFECTS_Symbol  
          SendMessage_(GadgetID(#Editor_1), #EM_SETCHARFORMAT, #SCF_SELECTION, @Format)  
        EndIf
      Until Left = Endpos
    Next mode
  Next  
EndProcedure

Procedure WindowCallback(hWnd, uMsg, wParam, lParam)
  Protected ReturnValue, CurrentLine, CurrentStartPos
  ReturnValue = #PB_ProcessPureBasicEvents
  Select uMsg
    Case #WM_COMMAND
      If wParam >> 16 = #EN_CHANGE And lParam = GadgetID(#Editor_1)
        SendMessage_(GadgetID(#Editor_1), #EM_GETSEL, @CurrentStartPos, @CurrentLine) 
        CurrentLine = SendMessage_(GadgetID(#Editor_1), #EM_LINEFROMCHAR, CurrentStartPos, 0) 
        SendMessage_(GadgetID(#Editor_1), #EM_HIDESELECTION, 1, 0)   
        ;HighlightLine(CurrentLine)    -----> Si active, le prog boucle
        If GetAsyncKeyState_(#VK_return) & 1 = 1 
          HighlightLine(CurrentLine - 1)
        EndIf 
        SendMessage_(GadgetID(#Editor_1), #EM_SETSEL, CurrentStartPos, CurrentStartPos)
        SendMessage_(GadgetID(#Editor_1), #EM_HIDESELECTION, 0, 0)
      EndIf
  EndSelect 
  ProcedureReturn ReturnValue  
EndProcedure
Ce code fonctionnait parfaitement en PB 3.92 et plus en PB 3.93

Quelqu'un verrait-il une raison à ce problème ?
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

à partir du moment ou tu modifie le texte, tu as forcément un #em_change, c'est ça ?
et comme tu modifie le texte pour le coloriser, ça tourne en rond

enfin je pense que le prob vient de la. sans le code complet, c'est pas facile de voir :wink:
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
tme007
Messages : 57
Inscription : mar. 26/oct./2004 12:34

PB 3.93 et Formatage dans un EditorGadget

Message par tme007 »

Oui c'est cela, j'ai placé un SETEVENTMASK avec la valeur ENM_CHANGE sur l'EditorGadget, ce qui me permet de détecter toute altération du texte.
Ce qui me rend perplexe est que, en travaillant avec le debugger en step by step, j'ai découvert que lorsque j'active la ligne

Code : Tout sélectionner

HighLightLine(Line)
dans la callback, celle-ci boucle en permanence et ne continue pas le flux du code ... comme si le compteur d'instructions était gelé à cet endroit.

Alors que si je la mets en remarque, le

Code : Tout sélectionner

HighLightLine(Line-1)
colorise bien la ligne juste au-dessus ... et donc altère aussi le texte mais dans ce cas, le flux d'instructions suit son cours normalement et sort de la procédure de callback après avoir replacé le curseur à sa place initiale.

Pourquoi ce comportement est-il apparu dés la béta 3 de PB 3.93 (la seule que j'ai téléchargé avant la release officielle) et pas en PB 3.92, mystère !

Le coeur du code est la callback et la procédure Highlightline.

J'ai également une procédure de surlignage complet, qui en fait parcours toutes les lignes de l'EditorGadget et pour chacune d'elle appelle la procédure Highlighline, qui altère le texte et là aussi le comportement est tout à fait normal et le texte se trouve bien colorisé et transformé en minuscule. Même si la ligne bloquante reste activée !!!

Je m'arrache les cheveux là-dessus depuis quelques jours maintenant.

Quelqu'un pourrait me dire les modifications qui ont été apportées dans l'EditorGadget, autres que celles mentionnées dans l'historique ?

Merci d'avance
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

Message par Progi1984 »

Est ce que cela n'est pas du au fait que Windows commence ces lignes à 1 et le Purebasic commence à compter dans son éditeur à partir de 0 ?
tme007
Messages : 57
Inscription : mar. 26/oct./2004 12:34

PB 3.93 et Formatage de l'EditorGadget

Message par tme007 »

Non car dans cette partie du code :

Code : Tout sélectionner

SendMessage_(GadgetID(#Editor_1), #EM_GETSEL, @CurrentStartPos, @CurrentLine) 
CurrentLine = SendMessage_(GadgetID(#Editor_1), #EM_LINEFROMCHAR, CurrentStartPos, 0) 
je récupère la ligne de l'EditorGadget (ou plus précisément du contrôle Richedit) où mon curseur se trouve et la numérotation commençant à 0, cela correspond à ce que Purebasic attend.

Dans la batterie de tests que j'ai réalisé, j'ai remarqué que le problème pouvait survenir à n'importe quel endroit du richedit, pour autant que je tente de surligner la ligne où se trouve mon curseur. Je l'ai vu lorsque j'ai chargé un fichier dans le richedit, qui a été colorisé correctement, et que j'ai tenté de modifier la 5ème ligne ... et là: "Bardaf, c'est l'embardée !" (comme disait notre regretté Manu Thoreau dans "Faux Contact")

Mais je souligne encore ce fait, mon code fonctionnait parfaitement lorsque compilé en PB 3.92 ...
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

Message par Progi1984 »

Attends ! As tu la dernière version de la lib RichEdit recompilée avec la 3.93 car c'est peut-être du à cela ?
Avatar de l’utilisateur
cederavic
Messages : 1338
Inscription : lun. 09/févr./2004 23:38
Localisation : Bordeaux

Re: PB 3.93 et Formatage de l'EditorGadget

Message par cederavic »

tme007 a écrit :Non car dans cette partie du code :

Code : Tout sélectionner

SendMessage_(GadgetID(#Editor_1), #EM_GETSEL, @CurrentStartPos, @CurrentLine) 
CurrentLine = SendMessage_(GadgetID(#Editor_1), #EM_LINEFROMCHAR, CurrentStartPos, 0) 
Et le bug est là :wink:
Voilas la description du message EM_LINEFROMCHAR :
The EM_EXLINEFROMCHAR message determines which line contains the specified character in a rich edit control.

Syntax

To send this message, call the SendMessage function as follows.
lResult = SendMessage( // returns LRESULT in lResult (HWND) hWndControl, // handle to destination control (UINT) EM_EXLINEFROMCHAR, // message ID (WPARAM) wParam, // = (WPARAM) () wParam; (LPARAM) lParam // = (LPARAM) () lParam; );

Parameters

wParam
This parameter is not used; it must be zero.

lParam
Zero-based index of the character.

Return Value

This message returns the zero-based index of the line.
Donc tu as inverser wParam et lParam...
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

Message par Progi1984 »

Tout simplement !
tme007
Messages : 57
Inscription : mar. 26/oct./2004 12:34

PB 3.93 et Formatage

Message par tme007 »

Cederavic, la doc que tu as sortie concerne le message EM_EXLINEFROMCHAR ... et non EM_LINEFROMCHAR que j'utilise dans mon code, et dans ce cas de figure, il s'agit encore d'une joyeuseté de Microsoft qui a inversé l'ordre des paramètres entre leurs 2 API !

Voici ce qu'en dit MSDN pour EM_LINEFROMCHAR:
The EM_LINEFROMCHAR message retrieves the index of the line that contains the specified character index in a multiline edit control. A character index is the zero-based index of the character from the beginning of the edit control. You can send this message to either an edit control or a rich edit control.

Syntax


To send this message, call the SendMessage function as follows.
lResult = SendMessage( // returns LRESULT in lResult (HWND) hWndControl, // handle to destination control (UINT) EM_LINEFROMCHAR, // message ID (WPARAM) wParam, // = (WPARAM) () wParam; (LPARAM) lParam // = 0; not used, must be zero );
Parameters

wParam
Specifies the character index of the character contained in the line whose number is to be retrieved. If this parameter is –1, EM_LINEFROMCHAR retrieves either the line number of the current line (the line containing the caret) or, if there is a selection, the line number of the line containing the beginning of the selection.

lParam
This parameter is not used.
Donc mes paramètres wParam et lParam sont dans le bon sens ...

Et en me relisant, je viens de voir que si j'utilisais '-1' comme wParam, ce message me renvoie la ligne contenant le curseur, j'économiserai donc le message EM_GETSEL précédant celui-ci ...

En ce qui concerne la lib Richedit, je suppose que j'ai la dernière version puisque le SmartUpdate ne me propose pas de la mettre à jour ?

Progi1948, tu pourrais me donner les infos de version afin que je compare avec la mienne ?
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

Message par Progi1984 »

Attends normalement la lib richEdit est un lib à dl a part créé par un anglais El_Choni donc ffaudrait voir avec lui pour un test !
Avatar de l’utilisateur
cederavic
Messages : 1338
Inscription : lun. 09/févr./2004 23:38
Localisation : Bordeaux

Message par cederavic »

autant pour moi... j'avais mal lus :oops:
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

Message par Progi1984 »

Errare humanu Est
tme007
Messages : 57
Inscription : mar. 26/oct./2004 12:34

PB 3.93 et formatage

Message par tme007 »

En premier lieu, merci de votre aide à tous ...

Bon là j'en ai eu marre de ce foutu problème ! Donc, comme je stocke tout ce que je trouve sur Pure, j'ai utilisé ta lib 'LibEditorPlus' (que j'ai dû recompilé en PB 3.93 car j'avais plein de messages d'erreur du linker) et avec quelques bricolages, cela donne le résultat que je souhaitais.

Voilà .. voilà ....

A bientôt, les fanas du Pure !
Répondre