Page 1 sur 1

CallBack et Userlibrairie

Publié : dim. 15/mai/2005 15:28
par Progi1984
Souahaitant l'incorporer dans ma lib, je souhaite personnaliser le numérotage des lignes : j'ai ce code, mais le probleme se pose vu que cela est un callback donc si quelqu'un pouvait m'aider !

Code : Tout sélectionner

Enumeration
  #Editor_0
EndEnumeration

Structure myPARAFORMAT2
  cbSize.l
  dwMask.l
  wNumbering.w
  wEffects.w
  dxStartIndent.l
  dxRightIndent.l
  dxOffset.l
  wAlignment.w
  cTabCount.w
  rgxTabs.l[#MAX_TAB_STOPS]
  dySpaceBefore.l
  dySpaceAfter.l
  dyLineSpacing.l
  sStyle.w
  bLineSpacingRule.b
  bOutlineLevel.b
  wShadingWeight.w
  wShadingStyle.w
  wNumberingStart.w
  wNumberingStyle.w
  wNumberingTab.w
  wBorderSpace.w
  wBorderWidth.w
  wBorders.w
EndStructure

egPara.myPARAFORMAT2
egPara\cbSize = SizeOf(myPARAFORMAT2)
egPara\dwMask = #PFM_NUMBERING | #PFM_NUMBERINGSTART | #PFM_NUMBERINGSTYLE | #PFM_NUMBERINGTAB
egPara\wNumbering = 2         ; 2 = 1..2..3 ; 3 = a..b..c ; 4 = A..B..C ; 5 = i...ii...iii ; 6 = I...II...III
egPara\wNumberingStart = 1    ; premier nombre à utiliser
egPara\wNumberingStyle = $300 ; 0 = NUM) ; $100 = (NUM) ; $300 = NUM
egPara\wNumberingTab = 700    ; esapce

 Global egPara
Procedure LineNumber(hWnd, msg, wParam, lParam)
  result = #PB_ProcessPureBasicEvents
  Shared previousLineCount
  Select msg
    Case #WM_COMMAND
      Select wParam>>16 &$FFFF
        Case #EN_CHANGE
          currentLineCount = SendMessage_(lParam, #EM_GETLINECOUNT , 0, 0)
          If currentLineCount <> previousLineCount
            currentLine = SendMessage_(lParam, #EM_LINEFROMCHAR, -1, 0)
            currentPos = SendMessage_(lParam, #EM_GETSEL, @startPos, @endPos)
            ;--> Get current scroll postion so we can come back here after re-writing itmes
            SendMessage_(lParam, #EM_GETSCROLLPOS, 0, @scrollP.POINT)
            egPara\wNumberingStart = currentLine+1
            ;--> Turn redraw off For EditorGadget To prevent scrolling when re-writing items
            SendMessage_(lParam, #WM_SETREDRAW, 0, 0)
            For a = currentLine-1 To currentLineCount -1
              egPara\wNumberingStart = a + 1
              t$ = GetGadgetItemText(#Editor_0, a, 0)
              ;--> Line numbering only continues with valid item text
              ;--> so we'll add a temporary space character
              If t$ = ""
                t$ = " "
              EndIf
              SetGadgetItemText(#Editor_0, a, t$, 0)
              SendMessage_(lParam, #EM_SETPARAFORMAT, 0, egPara)
              ;--> We can now remove the temporay space character
              If t$ = " "
                t$ = ""
                SetGadgetItemText(#Editor_0, a, t$, 0)
              EndIf
            Next a
           ; --> Put caret back To correct position
            SendMessage_(lParam, #EM_SETSCROLLPOS, 0, scrollP.POINT)
            SendMessage_(lParam, #EM_SETSEL, startPos, startPos)
           ; --> Turn redraw back on For EditorGadget
            SendMessage_(lParam, #WM_SETREDRAW, 1, 0)
           ; --> Redraw EditorGadget To show new line numbers
            InvalidateRect_(lParam, 0, 1)
          EndIf
          previousLineCount = SendMessage_(lParam, #EM_GETLINECOUNT , 0, 0)
      EndSelect
  EndSelect
  ProcedureReturn result
 EndProcedure
If OpenWindow(0, 0, 0, 600, 450, #PB_Window_SystemMenu | #PB_Window_ScreenCentered, "EditorGadget with Line Numbers") And CreateGadgetList(WindowID(0))
  EditorGadget (#Editor_0, 0, 0, 600, 450)
  SendMessage_(GadgetID(#Editor_0), #EM_SETCHARFORMAT, #SCF_ALL, @egFormat)
  SendMessage_(GadgetID(#Editor_0), #EM_SETEVENTMASK, 0, #ENM_CHANGE)
  For l = 1 To 300
    AddGadgetItem(#Editor_0, l, "Line " + Str(l))
    SendMessage_(GadgetID(#Editor_0), #EM_SETPARAFORMAT, 0, egPara)
    egPara\wNumberingStart +1
  Next
  Test(#Editor_0)
  SetWindowCallback(@LineNumber())
  Repeat
    event = WaitWindowEvent()
    
  Until event = #PB_Event_CloseWindow
EndIf
End

Publié : dim. 15/mai/2005 16:28
par nico
Malgré mon dernier exemple, je vois que tu n'as pas compris alors je l'ai adapté pour ton code, je l'ai testé.

Voici exactement comment faire:

Code : Tout sélectionner

;/ Debut de Lib
; Declaration des structures et des variables

Procedure InitlineNumber(window.l)
  OriginProc = SetWindowLong_(window, #GWL_WNDPROC, @LineNumber()) 
  SetProp_(window, "OriginProc", OriginProc) 
EndProcedure 

Procedure LineNumber(hWnd, Msg, wParam, lParam) 
  OriginProc.l= GetProp_(hWnd, "OriginProc") 
  Shared previousLineCount 
  Select Msg 
    Case #wm_command 
      ;//
      ;//----Le reste du code------
      ;//
    Case #WM_CLOSE
      RemoveProp_(hWnd,"OriginProc")
  EndSelect 
  
  ProcedureReturn CallWindowProc_(OriginProc,hWnd,Msg,wParam,lParam) 
EndProcedure 

;/ Fin de la Lib
 
If OpenWindow(0, 0, 0, 600, 450, #PB_Window_SystemMenu | #PB_Window_ScreenCentered, "EditorGadget with Line Numbers") And CreateGadgetList(WindowID(0)) 
  EditorGadget (#Editor_0, 0, 0, 600, 450) 
  SendMessage_(GadgetID(#Editor_0), #EM_SETCHARFORMAT, 2, @egFormat) 
  SendMessage_(GadgetID(#Editor_0), #EM_SETEVENTMASK, 0, #ENM_CHANGE) 
  For l = 1 To 300 
    AddGadgetItem(#Editor_0, l, "Line " + Str(l)) 
    SendMessage_(GadgetID(#Editor_0), #EM_SETPARAFORMAT, 0, egPara) 
    egPara\wNumberingStart +1 
  Next 
  InitlineNumber(WindowID(0))
  Repeat 
    event = WaitWindowEvent() 
    
  Until event = #PB_Event_CloseWindow 
EndIf 
End
Si tu éprouves toujours des difficultés, tu peux utiliser la Lib du Soldat.

:)

Publié : dim. 15/mai/2005 16:30
par Anonyme2
Le principe pour ta librairie

Tu crées (avec Tailbite il faut préciser la syntaxe, ajoute _init à la fin du nom de la procedure) une procedure d'initialisation ou tu crées une liste chainée te permetant de stocher l'ID du gadget (car les utilisateurs peuvent utiliser plusiers editorgadget), son Handle si besoin, l'adresse de la procedure Windows de gestion des événements (retournée par setwindowlong), et aussi toutes les données que tu as besoin (ça peut être les couleurs, les brush ou autre chose)

Tu crées aussi une procedure de fin de de prog qui lorsque le prog sera fini (avec Tailbite ajoute _End à la fin du nom de la procedure) permetra d'utiliser ClearList(ListeChainee()) pour libérer la mémoire utilisée par la liste chainée et toutes les choses que tu aurais besoin de faire comme par exemple utiliser l'API deleteobject pour libérer la mémoire lorsque tu créé des brush.

Maintenant, il faut créer une commande donc une procedure qui indique que l'on veut (ou non) numéroter les lignes. Cette commande vérifiera que le gadget est déjà subclassé (3 cas) :

Si oui, on ne le subclasse pas car la callback sera utilisée

Si non on le subclasse

Si le gadget n'existe pas c'est une erreur (qu'il faut prévoir car ça risque de planter)

Il reste à écrire le code de la callback et tout ce qui te semble utile pour la commande

Il ne faut qu'une seule et même callkback pour tous les événements que tu risques d'intercepter

Normalement, à la fin du prog, tu dois unsubclasser le gadget en redonnant l'adresse de la procedure windows comme procedure unique.

Je ne sais pas si c'est clair mais c'est quelque chose qui ressemble à ça, c'est ce que j'ai utilisé dans mes librairies.

Publié : dim. 15/mai/2005 16:56
par Progi1984
Bah merci, si j'ai des questions, je vous contacte !