Page 1 sur 3
Tab pour un alinéa dans EditorGadget
Publié : lun. 06/sept./2004 18:18
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

Publié : lun. 06/sept./2004 19:24
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

Publié : lun. 06/sept./2004 19:34
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
Publié : lun. 06/sept./2004 19:48
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...

Publié : lun. 06/sept./2004 20:15
par Aranoth
J'avais jamais tilter que l'IDE de PB était OpenSource^^ merci Dri
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
Publié : lun. 06/sept./2004 20:22
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)

Publié : lun. 06/sept./2004 20:32
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
Mais je ne comprend pas ton code

Publié : mer. 08/sept./2004 4:11
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.
Publié : mer. 08/sept./2004 13:04
par Aranoth
oui super clair !
Je vais pouvoir implementer ca
Merci à tous !
Publié : lun. 20/sept./2004 23:24
par Flype
sinon un truc tout bête :
dans un editorgadget si on tape CTRL+TAB ca fait un vrai 'tab'

Publié : mar. 21/sept./2004 20:29
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
Publié : mar. 21/sept./2004 20:51
par Flype
merci nico c super ce code. ca me servira.
par contre c rigolo parceque maintenant CTRL+Tab çà fait 2 'tab'.
Publié : mar. 21/sept./2004 21:00
par nico
J'avais pas vu, c'est trop fort!

Publié : mer. 22/sept./2004 11:07
par Aranoth
nickel
bravo et merci à toi c'est sur que ca servira^^

Publié : dim. 23/janv./2005 14:24
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