Tab pour un alinéa dans EditorGadget

Programmation d'applications complexes
Aranoth
Messages : 293
Inscription : sam. 24/janv./2004 12:00
Localisation : Toulouse (31)
Contact :

Tab pour un alinéa dans EditorGadget

Message par Aranoth »

Bonjour !

J'aimerait que dans un EditorGadget, TAB fasse un aliné au lieu de donner le focus a un autre element !

Comme dans PureBASIC par exemple, ou comme le NotePad...

Merci :wink:
Débutant en programmation, notament en C++ ?
Vous souhaitez apprendre ?
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message par Dr. Dri »

il me semble qu'on a acces aux sources de l'éditeur PB
d'ailleurs si quelqu'un confirme j'aimerais savoir où :)

Dri

[edit]
ca n'a pas été difficile de trouver les sources...
http://www.purebasic.com/download/examples/Editor.zip

maintenant faut chercher dedans pour trouver comment c'est géré ^^

Dri ;)
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message par Dr. Dri »

j'ai trouvé cette procedure, faut que je trouve aussi son appel...

Code : Tout sélectionner

Procedure EditorKeyHandler(VirtualKey)
  Shared VK_ReturnState

  If VirtualKey = #VK_RETURN And VK_ReturnState = 0
  
    PreviousCursorX = CursorPositionX-1
    
    SyntaxHighlighting()
        
    *Line = AllocateMemory(#MEM_KEYHANDLER1, 2000, 0)
    PokeW(*Line, 1000)
    
                    SendMessage_(*RichEditGadget, #EM_GETSEL        , @StartPosition, 0)
    StartPosition = SendMessage_(*RichEditGadget, #EM_EXLINEFROMCHAR, 0             , StartPosition)
                    SendMessage_(*RichEditGadget, #EM_GETLINE       , StartPosition , *Line)   ; Get the current line buffer..
    
    VK_ReturnState = 1 ; Very tricky. This inform the WindowCallback to ignore the following #VK_RETURN return, else it's a dead loop
    
    SendMessage_(*RichEditGadget, #WM_KEYDOWN, #VK_RETURN, 1)
    
    ClearEffects() ; Reset all the font effects for the newline..
    
    *Cursor.Byte = UseMemory(#MEM_KEYHANDLER1)
    While *Cursor\b = ' ' And PreviousCursorX > 0   ; Insert space at the start of the newline (auto-indent)
      SendMessage_(*RichEditGadget, #WM_CHAR, ' ', 1)
      *Cursor+1
      PreviousCursorX-1
    Wend
    
    FreeMemory(#MEM_KEYHANDLER1)
    
  ElseIf VirtualKey = #VK_TAB
  
    If GetKeyState_(#VK_SHIFT) < 0
      ShiftMode = 1
    Else
      ShiftMode = 0
    EndIf
  
                       SendMessage_(*RichEditGadget, #EM_GETSEL        , @StartPosition, @EndPosition)
    FirstLineIndex   = SendMessage_(*RichEditGadget, #EM_EXLINEFROMCHAR, 0             , StartPosition)
    LastLineIndex    = SendMessage_(*RichEditGadget, #EM_EXLINEFROMCHAR, 0             , EndPosition)
    LastLinePosition = SendMessage_(*RichEditGadget, #EM_LINEINDEX     , LastLineIndex , 0)
  
    *Buffer = AllocateMemory(#MEM_KEYHANDLER2, EndPosition-StartPosition, 0)

    If LastLinePosition = EndPosition And LastLineIndex <> FirstLineIndex ; Needed to handle the case where the selection is at the very end of the
      LastLineIndex-1                                                      ; line and then the new line is take in count too.
    EndIf

    If FirstLineIndex <> LastLineIndex  ; Block indent when pressing TAB

      For k=FirstLineIndex To LastLineIndex

        LineIndex  = SendMessage_(*RichEditGadget, #EM_LINEINDEX , k        , 0)
        LineLength = SendMessage_(*RichEditGadget, #EM_LINELENGTH, LineIndex, 0)

        If LineLength > 0 And OldLineIndex+LineLength+1 <> EndPosition

          If ShiftMode
            If TabLength > LineLength
              RealTabLength = LineLength
            Else
              RealTabLength = TabLength
            EndIf

            SendMessage_(*RichEditGadget, #EM_SETSEL    , LineIndex, LineIndex+RealTabLength)
            SendMessage_(*RichEditGadget, #EM_GETSELTEXT, 0        , *Buffer)

            Counter = RealTabLength
            *Cursor = *Buffer
            While (*Cursor\b = 9 Or *Cursor\b = ' ') And Counter
              *Cursor+1
              Counter-1
            Wend
            
            If Counter < RealTabLength
              SendMessage_(*RichEditGadget, #EM_SETSEL, LineIndex, LineIndex+RealTabLength-Counter)
              SendMessage_(*RichEditGadget, #EM_REPLACESEL, 1, "")
            EndIf

            Offset-(RealTabLength-Counter)
          Else
            SendMessage_(*RichEditGadget, #EM_SETSEL, LineIndex, LineIndex) ; Cursor to the beginning of the line
                   
            ClearEffects() ; Reset all the font effects for the newline..

            SendMessage_(*RichEditGadget, #EM_REPLACESEL, 1, Space(TabLength))
            
            Offset+TabLength
          EndIf
        EndIf
      Next

      SendMessage_(*RichEditGadget, #EM_SETSEL, StartPosition, EndPosition+Offset)
    Else
      ClearEffects()  ; Reset all the font effects for start of the newline..

      RealTabLength = TabLength-MOD(CursorPositionX-1, TabLength)  ; Smart indent
      
      SendMessage_(*RichEditGadget, #EM_REPLACESEL, 1, Space(RealTabLength))
    EndIf
 
 Else 
   VK_ReturnState = 0
 EndIf
   
EndProcedure
Dri
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

Code : Tout sélectionner

  SetWindowLong_(GadgetID(0),#gwl_style,GetWindowLong_(GadgetID(0),#gwl_style)-#ws_tabstop)
Cette ligne permet de supprimer le changement du focus lors de l'appui sur la touche Tab, mais alors après... :?
Aranoth
Messages : 293
Inscription : sam. 24/janv./2004 12:00
Localisation : Toulouse (31)
Contact :

Message par Aranoth »

J'avais jamais tilter que l'IDE de PB était OpenSource^^ merci Dri :wink:

J'ai essayé le code de Nico (merci à toi !) et ca marche bien, après suffit d'ajouter quelques espaces à l'emplacement du curseur.

Mais comment connaitre l'emplacement du curseur ? c'est pas le role de GetGadgetState()...Et j'ai vu aucunes commandes clair pour cette utilisation dans la doc...

Si qq sais
Débutant en programmation, notament en C++ ?
Vous souhaitez apprendre ?
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

Oui bien sûr, tu peux facilement ajouter des espaces avec ce code par exemple:

Code : Tout sélectionner

      Case 256
        If EventwParam()=9
          For x=1 To 4
           keybd_event_($20, 0, 0, 0) 
           keybd_event_($20, 0, #KEYEVENTF_KEYUP, 0)
          Next c
        EndIf  
Mais le problème, c'est que ça n'as pas le même comportement qu'un vrai Tabstop qui s'arrête toujours au mêmes endroits quelque soit l'emplacement du curseur.(je sais pas si c'est clair mais disons que c'est pas pareil) :?

:)
Dernière modification par nico le lun. 06/sept./2004 20:44, modifié 1 fois.
Aranoth
Messages : 293
Inscription : sam. 24/janv./2004 12:00
Localisation : Toulouse (31)
Contact :

Message par Aranoth »

je vois ce que tu veut dire oui...
L'alinéa est une entitée à part entière

Remarque j'ai vu que Dreamweaver MX proposait le nombre d'espace composant un alinéa, meme les pros bidouillent :lol:

Mais je ne comprend pas ton code :?
Débutant en programmation, notament en C++ ?
Vous souhaitez apprendre ?
Avatar de l’utilisateur
ZapMan
Messages : 460
Inscription : ven. 13/févr./2004 23:14
Localisation : France
Contact :

Message par ZapMan »

Sendmessage_(GadgetID(0),#EM_GETSEL,@StartS, @EndS)
te permet de récupérer dans les variables StartS et EndS la position de départ et de fin de la sélection courante.

Il y a aussi
Sendmessage_(GadgetID(0),#EM_SETSEL,StartS, EndS)
qui te permet de fixer la sélection aux valeurs que tu souhaites.

Pour simuler une vrai tabulation qui permet de se positionner à un endroit fixe quelque soit l'endroit où l'on est au moment de l'appui, il faut :
- travailler avec une police non-proportionnelle (comme celle utilisée dans PureBasic) pour que tous les caractères aient la même largeur
- compter le nombre de caractères qu'il y a entre StartS et le précédent retour-chariot
- insérer le nombre d'espace nécessaire pour se rendre au point désiré

J'espère que je suis clair.
Tout obstacle est un point d'appui potentiel.

Bibliothèques PureBasic et autres codes à télécharger :https://www.editions-humanis.com/downlo ... ads_FR.htm
Aranoth
Messages : 293
Inscription : sam. 24/janv./2004 12:00
Localisation : Toulouse (31)
Contact :

Message par Aranoth »

oui super clair !

Je vais pouvoir implementer ca :P

Merci à tous !
Débutant en programmation, notament en C++ ?
Vous souhaitez apprendre ?
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message par Flype »

sinon un truc tout bête :

dans un editorgadget si on tape CTRL+TAB ca fait un vrai 'tab' :wink:
Image
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

Après expérimentation, ça donne ça:

Code : Tout sélectionner

;nico

  OpenWindow(1,200,200,400,400,#PB_Window_SystemMenu,"Fenêtre principale")
  test=1
  If CreateGadgetList(WindowID(1)) 
    EditorGadget (1,10,40,380,300,#PB_Container_Raised)
  EndIf 
  SetWindowLong_(GadgetID(1),#GWL_STYLE,GetWindowLong_(GadgetID(1),#GWL_STYLE)!#WS_TABSTOP)
  Repeat 
    EventID.l=WaitWindowEvent()
    Select EventID 
      Case #WM_KEYDOWN 
        If EventwParam()=9
          If test=1
            keybd_event_($11, 0, 0, 0)
            keybd_event_($9, 0, #KEYEVENTF_KEYUP, 0)
            keybd_event_($9, 0, 0, 0)
            keybd_event_($11, 0, #KEYEVENTF_KEYUP, 0)
            test=0
          EndIf
        EndIf
                    
      Case #WM_KEYUP       
        If EventwParam()=$11 
          test=1 
        EndIf 
          
      Case #PB_EventGadget
        Select EventGadgetID()
 
        EndSelect
        
      Case #WM_CLOSE
        Quit=1
    EndSelect 
  Until Quit=1
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message par Flype »

merci nico c super ce code. ca me servira.
par contre c rigolo parceque maintenant CTRL+Tab çà fait 2 'tab'.
Image
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

J'avais pas vu, c'est trop fort! :lol:
Aranoth
Messages : 293
Inscription : sam. 24/janv./2004 12:00
Localisation : Toulouse (31)
Contact :

Message par Aranoth »

nickel :D

bravo et merci à toi c'est sur que ca servira^^
:wink:
Débutant en programmation, notament en C++ ?
Vous souhaitez apprendre ?
Aranoth
Messages : 293
Inscription : sam. 24/janv./2004 12:00
Localisation : Toulouse (31)
Contact :

Message par Aranoth »

Désolé de remonter ce vieux sujet, mais je me suis remis à bosser sur mon éditeur de texte.


Pour l'alinéa, j'utilise le code de Nico, mais j'ai un petit problème: l'alinéa est trop grand...

Y'a t'il un moyen de réduire sa taille ? :?


Merci
Débutant en programmation, notament en C++ ?
Vous souhaitez apprendre ?
Répondre