Page 2 sur 12

Re: ACME Software

Publié : jeu. 09/mars/2017 18:17
par Shadow
Le menu contextuel n'est pas possible. J'utilise le gadget editor et il ne supporte pas l'évènement clic droit (pourquoi ?)
Donc impossible de déclencher un menu contextuel sur ce gadget. :|
:mrgreen: HA HA HA HA HA, un gars aussi calé que toi HA HA HA HA (Pas méchant hein)
Évidement que c'est possible, largement même mon cher Marc et je vais te faire voir comment en plus !
Deja fais de nombreuse fois, dans mon editeur d'expression notamment !
C'est facile mais par des moyen détourner et sans API !
Et en plus c'est très propre je vais faire un exemple :)

Re: ACME Software

Publié : jeu. 09/mars/2017 18:31
par Marc56
D'accord, mais pour ne pas en faire une tartine,
modifie simplement la procédure (Send_CTRL_A()) de code pour qu'en cliquant sur le bouton
il fasse l'équivalent windows de CTRL+A

Code : Tout sélectionner

Enumeration FormWindow
  #Window_0
EndEnumeration

Enumeration FormGadget
  #Editor_0
  #Button_0
EndEnumeration

Procedure OpenWindow_0(x = 0, y = 0, width = 600, height = 400)
  OpenWindow(#Window_0, x, y, width, height, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  EditorGadget(#Editor_0, 10, 10, 580, 355)
  SetGadgetText(#Editor_0, "Hello World")
  ButtonGadget(#Button_0, 260, 370, 100, 25, "CTRL + A")
EndProcedure

Procedure Send_CTRL_A()
     Debug " Send_CTRL_A()"
EndProcedure

OpenWindow_0()

BindGadgetEvent(#Button_0, @Send_CTRL_A())

While WaitWindowEvent() <> #PB_Event_CloseWindow : Wend
Je ne pige rien aux API, c'est pour cela que je demande.
On ne sais pas tout.
Comme disait JCB sur Usenet: « La connaissance s'accroit quand on la partage » :wink:

Re: ACME Software

Publié : jeu. 09/mars/2017 18:31
par falsam
Shadow a écrit :Évidement que c'est possible, largement même mon cher Marc et je vais te faire voir comment en plus !
Benn oui bien sur que c'est évident et largement hahahaha (Moi je ne sais pas faire sans API). Quel insolence ce garçon !!!

Re: ACME Software

Publié : jeu. 09/mars/2017 18:38
par falsam
En cherchant sur le forum anglais c'est possible sans API
http://www.purebasic.fr/english/viewtop ... 5a#p484857

Re: ACME Software

Publié : jeu. 09/mars/2017 18:39
par Kwai chang caine
Quinquin d'énervé a écrit :Benn oui bien sur que c'est évident et largement hahahaha (Moi je ne sais pas faire sans API). Quel insolence ce garçon !!!
Image

Premier "psaume" verset 1 :mrgreen:
L'iremplacable MONSIEUR Gabin a écrit :Quand j'étais gosse, haut comme trois pommes,
J'parlais bien fort pour être un homme
J'disais, JE SAIS, JE SAIS, JE SAIS, JE SAIS
En savoir plus sur http://www.paroles.net/jean-gabin/parol ... Re7OPk8.99

Re: ACME Software

Publié : jeu. 09/mars/2017 18:51
par Marc56
Super Falsam, parfait pour le menu contextuel sur l’éditeur 8)

Il ne me reste plus qu'à trouver comment déclencher un raccourci système (CTRL+A +C +V etc) par une procédure.
(j'en ai testé des exemples à base de PostMesage, SendMessage_ WM_ VK_ ) :|

Mais pourquoi une fonction aussi lambda n'existe pas dans PB :?:

Re: ACME Software

Publié : ven. 10/mars/2017 8:53
par Marc56
Pour ceux que cela peut intéresser, voici le code le plus leger que j'ai pu trouver en suivant le lien de Falsam

Objectifs:

1. Ajouter un menu contextuel dans un EditorGadget (Ce gadget ne supporte pas nativement le clic droit)
:arrow: Solution: détection de #WM_RBUTTONDOWN sur le gadget

2. Affecter à ce menu les action systèmes: Couper, Copier, Coller (Ces actions n'ont pas de constante PB)
:arrow: Solution: Utilisation de SendMessage_(GadgetID(0), #WM_xxx)

Auteur: Shardik et probablement Rashad (je n'ai pas trouvé la source initiale)

Source: http://www.purebasic.fr/english/viewtop ... 68&start=6

Code : Tout sélectionner

; Source: http://www.purebasic.fr/english/viewtopic.php?f=13&t=63168&start=6
OpenWindow(0, 100, 100, 300, 190, "Display context menu on right click")
EditorGadget(0, 10, 10, 280, 170)

CompilerIf #PB_Compiler_OS = #PB_OS_Windows     
     If CreatePopupMenu(0)
          MenuItem(0, "Cut")
          MenuItem(1, "Copy")
          MenuItem(2, "Paste")
     EndIf
CompilerEndIf

Repeat
     Select WaitWindowEvent()
          Case #PB_Event_CloseWindow
               Break
               
               CompilerIf #PB_Compiler_OS = #PB_OS_Windows     
               Case #PB_Event_Menu
                    Select EventMenu()
                         Case 0
                              SendMessage_(GadgetID(0), #WM_CUT, 0, 0)
                         Case 1
                              SendMessage_(GadgetID(0), #WM_COPY, 0, 0)
                         Case 2
                              SendMessage_(GadgetID(0), #WM_PASTE, 0, 0)
                    EndSelect
                    
               Case #WM_RBUTTONDOWN
                    If EventGadget() = 0
                         DisplayPopupMenu(0, WindowID(0))
                    EndIf
               CompilerEndIf
     EndSelect
ForEver 
Voir aussi ce topic intéressant:
http://www.forums.purebasic.com/english ... 13&t=17167

Hope this help
:wink:

:idea: Mettre dans la FAQ ? ou mieux, dans les fonctions standard d'une prochaine version :?:

Edit: Après intégration dans mon application, je constate que ce système ne fonctionne pas d'une manière régulière :(
C'est peut-être pour cela que ce n'est pas intégré aux possibilités standard du GadgetEditor ? :|

Re: ACME Software

Publié : ven. 10/mars/2017 13:11
par ChrisR
Marc, pour "Coller", tu peux sans doute envoyer un #WM_CLEAR pour supprimer le texte sélectionné avant de coller

Code : Tout sélectionner

Case 2  
   SendMessage_(GadgetID(iGdgID), #WM_CLEAR, 0, 0) 
   SendMessage_(GadgetID(iGdgID), #WM_PASTE, 0, 0)
Et pour sélectionner tout le texte (Ctrl+A), j'ai trouvé ici http://www.forums.purebasic.com/english ... 13&t=59924
avec également une procédure Multi-Plateforme sur le dernier post

Code : Tout sélectionner

If Selectionner
  SendMessage_(GadgetID(iGdgID), #EM_SETSEL, 0, -1)
Else  ;Deselectionner
  SendMessage_(GadgetID(iGdgID), #EM_SETSEL, 0, 0)
EndIf
Marc56 a écrit :Après intégration dans mon application, je constate que ce système ne fonctionne pas d'une manière régulière
Il semble bien fonctionner ici avec ton code ci-dessus. Est-ce que tu sais reproduire le pb ?

Re: ACME Software

Publié : ven. 10/mars/2017 15:40
par Marc56
ChrisR a écrit :Il semble bien fonctionner ici avec ton code ci-dessus. Est-ce que tu sais reproduire le pb ?
Oui, maintenant.
Si je fais Copie alors que rien n'est sélectionné, alors à l'appel suivant le menu ne s'affiche pas.
Si je reclique, il s'affiche
Si je reclique il ne s'affiche plus du tout.

Il doit y avoir un buffer quelque part ?

C'est encore plus visible ici

Code : Tout sélectionner

; Source basée sur: http://www.purebasic.fr/english/viewtopic.php?f=13&t=63168&start=6
OpenWindow(0, 100, 100, 300, 190, "Display context menu on right click")
EditorGadget(0, 10, 10, 280, 170)

If CreatePopupMenu(0)
     MenuItem(0, "Cut")
     MenuItem(1, "Copy")
     MenuItem(2, "Paste")
     MenuItem(3, "Select All")
     MenuItem(4, "Clear Selection")
     MenuItem(5, "Select and Clear All")
EndIf


Repeat
     Select WaitWindowEvent()
          Case #PB_Event_CloseWindow
               Break
               
          Case #PB_Event_Menu
               Select EventMenu()
                    Case 0
                         SendMessage_(GadgetID(0), #WM_CUT, 0, 0)
                    Case 1
                         SendMessage_(GadgetID(0), #WM_COPY, 0, 0)
                    Case 2
                         SendMessage_(GadgetID(0), #WM_PASTE, 0, 0)
                    Case 3
                         SendMessage_(GadgetID(0), #EM_SETSEL, 0, -1)
                    Case 4
                         SendMessage_(GadgetID(0), #WM_CLEAR, 0, -1)                        
                    Case 5
                         SendMessage_(GadgetID(0), #EM_SETSEL, 0, -1)
                         SendMessage_(GadgetID(0), #WM_CLEAR, 0, -1)
               EndSelect
               
          Case #WM_RBUTTONDOWN
               If EventGadget() = 0
                    DisplayPopupMenu(0, WindowID(0))
               EndIf
               
     EndSelect
ForEver
(faire Copy plusieurs fois de suite en n'ayant rien dans le presse-papier)

:arrow: Il semble que quand SendMessage_ n'a aucune donnée il se bloque :?:

Re: ACME Software

Publié : ven. 10/mars/2017 16:57
par ChrisR
J'ai reproduis et j'ai essayé en contrôlant le texte sélectionné
Procédure du Soldat Inconnu

Code : Tout sélectionner

Procedure.s GetTextSelection(Gadget)
  Protected Debut_Position, Fin_position, Texte.s, Index.l
  Select GadgetType(Gadget)
    Case #PB_GadgetType_String
      SendMessage_(GadgetID(Gadget), #EM_GETSEL, @Debut_Position, @Fin_position) 
      Texte = GetGadgetText(Gadget)
      Texte = Mid(Texte, Debut_Position + 1, Fin_position - Debut_Position)
      
    Case #PB_GadgetType_Editor
      SendMessage_(GadgetID(Gadget), #EM_GETSEL, @Debut_Position, @Fin_position) 
      For Index = 0 To CountGadgetItems(Gadget) - 1
        If Texte <> ""
          Texte + Chr(10)
        EndIf
        Texte + GetGadgetItemText(Gadget, Index)
      Next
      Texte = Mid(Texte, Debut_Position + 1, Fin_position - Debut_Position)
  EndSelect
  ProcedureReturn Texte
EndProcedure
......................
Case 1
     SetActiveGadget(0)
     ;Debug GetTextSelection(0)
     If GetTextSelection(0) <> ""
       SendMessage_(GadgetID(0), #WM_COPY, 0, 0)
     EndIf
Mais malheureusement, il continue à bloquer :(

Edit: tu peux aussi remplacer le SendMessage_ WM_COPY par

Code : Tout sélectionner

TextSelected = GetTextSelection(0)
;Debug TextSelected 
If TextSelected <> ""
  SetClipboardText(TextSelected)
EndIf
mais sans plus de succès

Re: ACME Software

Publié : ven. 10/mars/2017 17:14
par Shadow
Je vous renvois encore une fois à ma méthode et mon exemple qui lui fonctionne !

Re: ACME Software

Publié : ven. 10/mars/2017 17:18
par Marc56
C'est pour ça que je n'aime pas utiliser les API directement, il faut ajouter des trucs avant et après pour tout gérer.

À noter un truc intéressant: après blocage, si on bouge la fenêtre, ou si on tape du texte :arrow: ça fonctionne à nouveau :o :!:

:idea: Ce qui me fait penser qu'il y a peut-être un truc à pousser dans la file d'évènements :?:
(peut-être qu'un PostEvent() "vide" pourrait libérer ?)



Edit: Oui, ça marche

Code : Tout sélectionner

                    Case 1
                         SendMessage_(GadgetID(0), #WM_COPY, 0, 0)
                         PostEvent(#PB_Event_Repaint)
Oh, ma logique de vieux shadock :mrgreen:

Re: ACME Software

Publié : ven. 10/mars/2017 17:28
par ChrisR
Je n'en sais pas beaucoup plus. mais il manque un petit truc.
Si j'ai bien compris, PostEvent envoi un événement au prog PB lui même, pas à la file d'attente Windows.

Il serait vraiment bon d'avoir le couper/copier/coller en PB natif pour l'Editor Gadget
mais il y a sans doute des pb de compatibilités multiOS.

Edit: réponse croisée, Cool qu'il fonctionne, bien joué :)
A+

Re: ACME Software

Publié : ven. 10/mars/2017 17:32
par Marc56
Comme ça ça marche pour tous

Code : Tout sélectionner

          Case #PB_Event_Menu
               Select EventMenu()
                    Case 0
                         SendMessage_(GadgetID(0), #WM_CUT, 0, 0)
                    Case 1
                         SendMessage_(GadgetID(0), #WM_COPY, 0, 0)
                    Case 2
                         SendMessage_(GadgetID(0), #WM_PASTE, 0, 0)
                    Case 3
                         SendMessage_(GadgetID(0), #EM_SETSEL, 0, -1)
                    Case 4
                         SendMessage_(GadgetID(0), #WM_CLEAR, 0, -1)                        
                    Case 5
                         SendMessage_(GadgetID(0), #EM_SETSEL, 0, -1)
                         SendMessage_(GadgetID(0), #WM_CLEAR, 0, -1)
               EndSelect
               PostEvent(#PB_Event_Repaint)
Première fois que j'utilise ça. J'ai appris un truc nouveau aujourd'hui, bonne journée :wink:

Re: ACME Software

Publié : ven. 10/mars/2017 17:37
par Marc56
Je me demande d'ailleurs si

Code : Tout sélectionner

PostEvent(#PB_Event_Repaint) 
n'est pas plus efficace que la classique bidouille

Code : Tout sélectionner

 While WindowEvent() : Wend
que je met parfois pour régénérer une ListeView (par exemple pour faire défiler un log).