CallBack et Userlibrairie

Sujets variés concernant le développement en PureBasic
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

CallBack et Userlibrairie

Message 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
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message 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.

:)
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message 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.
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

Message par Progi1984 »

Bah merci, si j'ai des questions, je vous contacte !
Répondre