Kontextmenü bei Stringgadget/Combogadget abfangen

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
FGK
Beiträge: 249
Registriert: 09.01.2005 14:02
Computerausstattung: i5-4430 CPU / 8GB RAM
GeForce GT630
Windows 10 Home / 64-bit
Wohnort: Augsburg

Kontextmenü bei Stringgadget/Combogadget abfangen

Beitrag von FGK »

Hallo Leute,

ich hab mir mit hilfe des Forums/Archivs ne Eventabfrage zusammen gezimmert mit der ich die Rechte Maustaste auf Gadgets abfangen kann.
Das klappt im Testprog ganz gut solange ich nach ermitteln des Gadgets ne Testmessagebox aufrufe. In meinem eigentlichen Prog will ich das einfach nichts passiert - also daß das Standardkontextmenü für Stringgadgets nicht erscheint. Lasse ich Messagebox einfach weg kommt es dennoch zur Anzeige. Wer hat ne Idee dazu?

Einige Kopfzerbrechen machte mir auch das verdammte Frame3DGadget. Wird es vor den eigentlichen Gadgets die man abfragen will erzeugt dann "schluckt" es anscheinend die Events. Seltsam ist auch daß ich eigentlich dachte FrameGadgets wären wie in VB auch Container. Damit man mit einem Hide auf ein Frame mit Gadgets drin alle auf einmal "hiden" könnte.

Na ja PB is halt net VB *ggg

in diesem Sinne

Euer

FGK

Code: Alles auswählen

Procedure WindowUnderCursor(hwnd) 
  GetCursorPos_(cursor.POINT) 
  MapWindowPoints_(0,hwnd,cursor,1) 
  ProcedureReturn ChildWindowFromPoint_(hwnd,cursor\x,cursor\y) 
EndProcedure 

Procedure GetPanelDisplayWindowID(Gadget,item); Return the Display-WindowID of a Panel-Item
  tc_item.TC_ITEM
  tc_item\Mask=#TCIF_PARAM 
  SendMessage_(GadgetID(Gadget),#TCM_GETITEM,item,tc_item)
  ProcedureReturn tc_item\lParam
EndProcedure

OpenWindow(0,100,100,500,200, #PB_Window_MinimizeGadget, "Check right click") 
CreateGadgetList(WindowID()) 
PanelGadget(99,0,0,500,200)
AddGadgetItem(99,1,"N0")
StringGadget(1, 10, 20, 60, 24, "String") 
Frame3DGadget(98,0,0,200,100,"Test")
AddGadgetItem(99,1,"N1")
TextGadget(2, 100, 10, 60, 24, "Text") 
AddGadgetItem(99,1,"N2")
ButtonGadget(3, 10, 40, 60, 24, "Button") 
CloseGadgetList()
;HideGadget(98,1)

Repeat 
  Select WaitWindowEvent() 
    Case #WM_RBUTTONDOWN ; any click anywhere in the window 
      Select WindowUnderCursor(GetPanelDisplayWindowID(99,GetGadgetState(99))) 
        Case GadgetID(1) : MessageRequester("INFO","StringGadget",0) 
        Case GadgetID(2) : MessageRequester("INFO","TextGadget",0) 
        Case GadgetID(3) : MessageRequester("INFO","ButtonGadget",0) 
        Case WindowID(0) : MessageRequester("INFO","Main Window",0) 
      EndSelect 
    Case #PB_EventCloseWindow 
      End 
  EndSelect 
ForEver
Benutzeravatar
FGK
Beiträge: 249
Registriert: 09.01.2005 14:02
Computerausstattung: i5-4430 CPU / 8GB RAM
GeForce GT630
Windows 10 Home / 64-bit
Wohnort: Augsburg

Beitrag von FGK »

Hallo Leute,

was ist los? Hat keiner ne Idee wie man dieses Verhalten abstellen kann?
Sonst wird gemosert daß die meisten Probleme vom Niveau her alle mit der Online-Hilfe gelöst werden könnten und nun wo es def. nicht mit "Anleitung lesen" getan ist hat keiner ne Idee?

Kommt enttäuscht mich nicht.

Euer

FGK
Benutzeravatar
Hroudtwolf
Beiträge: 1416
Registriert: 30.10.2004 23:33
Kontaktdaten:

Beitrag von Hroudtwolf »

Mach halt ein Popupmenu. Das klappt.....
Meiner Erfahrung nach öffnet sich dann nur dein Popup und nicht das Systeminterne.
Benutzeravatar
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

Beitrag von Danilo »

Sorry, ich dachte dazu müssten Beispiele von mir im CodeArchiv
sein (WinAPI).

Habe es jetzt aber selbst nicht finden können, deshalb hier nochmal
2 Beispiele wo das mit enthalten ist:

Code: Alles auswählen

;
; by Danilo, 20.01.2004 - german forum
;
Global oldStringProc

Procedure NewStringProc(hWnd,Msg,wParam,lParam)
  If Msg = #WM_CHAR
    If wParam <> 8 And (wParam < '0' Or wParam > '9') ; allow 0 - 9 and Backspace (Ascii 8)
      ProcedureReturn 0
    Else
      Beep_(800,50)
    EndIf
  ElseIf Msg = #WM_KEYDOWN Or Msg = #WM_KEYUP
    If wParam = #VK_LEFT Or wParam = #VK_RIGHT ; block cursor keys
      ProcedureReturn 0
    EndIf
  ElseIf Msg = #WM_RBUTTONDOWN ; block popup-menu on right mouse click
    ProcedureReturn 0
  EndIf
  ProcedureReturn CallWindowProc_(oldStringProc,hWnd,Msg,wParam,lParam)
EndProcedure

OpenWindow(1,200,200,400,200,#PB_WINDOW_SystemMenu,"")
   CreateGadgetList(WindowID())
   StringGadget(1,10,10,300,20,"")
   oldStringProc = SetWindowLong_(GadgetID(1),#GWL_WNDPROC,@NewStringProc())
Repeat:Until WaitWindowEvent()=#PB_EventCloseWindow
Anderes Beispiel:

Code: Alles auswählen

;
; by Danilo, 10.07.2004 - german forum
;
Structure _LimitStringGadget
   oldCallback.l
   limit_size.l
   limit_asc.l
   mouse_block_rc.l
EndStructure

Procedure NewStringProc(hWnd,Msg,wParam,lParam)
  *mem._LimitStringGadget = GetWindowLong_(hWnd,#GWL_USERDATA)
  If *mem
    If Msg = #WM_CHAR
      If *mem\limit_size And *mem\limit_asc
        *ascii.BYTE = *mem\limit_asc
        For a = 1 To *mem\limit_size
          If *ascii\b & $FF = wParam
            found = 1
          EndIf
          *ascii + 1
        Next a
      EndIf
      If found = 0
        ProcedureReturn 0
      EndIf
      Beep_(800,20)
    ElseIf Msg = #WM_RBUTTONDOWN ; block popup-menu on right mouse click
      If *mem\mouse_block_rc = 1
        ProcedureReturn 0
      EndIf
    EndIf
    ProcedureReturn CallWindowProc_(*mem\oldCallback,hWnd,Msg,wParam,lParam)
  EndIf
  ProcedureReturn 0
EndProcedure

Procedure LimitStringGadgetInput(gadget,String$,BlockRightClick)
  len = Len(String$)
  If IsGadget(gadget)
    hString = GadgetID(gadget)
    *mem._LimitStringGadget = GetWindowLong_(hString,#GWL_USERDATA)
    If *mem=0
      *mem._LimitStringGadget = AllocateMemory(SizeOf(_LimitStringGadget))
    EndIf
    If *mem
      SetWindowLong_(hString,#GWL_USERDATA,*mem)
      *mem\limit_size  = len
      If len
        If *mem\limit_asc
          FreeMemory(*mem\limit_asc)
        EndIf
        *mem\limit_asc = AllocateMemory(len)
        If *mem\limit_asc
          CopyMemory(@String$,*mem\limit_asc,len)
        EndIf
      EndIf
      If *mem\oldCallback=0
        *mem\oldCallback = SetWindowLong_(hString,#GWL_WNDPROC,@NewStringProc())
      EndIf
      *mem\mouse_block_rc = BlockRightClick
    EndIf
  EndIf
EndProcedure

OpenWindow(1,200,200,400,200,#PB_WINDOW_SystemMenu,"")
   CreateGadgetList(WindowID())
   StringGadget(1,10,10,300,20,"")
   StringGadget(2,10,35,300,20,"")
   
   LimitStringGadgetInput(1,"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+Chr(#BS),1)
   LimitStringGadgetInput(2,"0123456789"+Chr(#BS),1)
   
Repeat:Until WaitWindowEvent()=#PB_EventCloseWindow

Ganz vereinfacht ist das was Du haben willst dann:

Code: Alles auswählen

Global oldStringProc

Procedure NewStringProc(hWnd,Msg,wParam,lParam)
  If Msg = #WM_RBUTTONDOWN ; block popup-menu on right mouse click
    ProcedureReturn 0
  EndIf
  ProcedureReturn CallWindowProc_(oldStringProc,hWnd,Msg,wParam,lParam)
EndProcedure

OpenWindow(1,200,200,400,200,#PB_WINDOW_SystemMenu,"")
   CreateGadgetList(WindowID())
   StringGadget(1,10,10,300,20,"")
   oldStringProc = SetWindowLong_(GadgetID(1),#GWL_WNDPROC,@NewStringProc())
Repeat:Until WaitWindowEvent()=#PB_EventCloseWindow
Für Dein anderes Problem könntest Du vielleicht ein ContainerGadget
nehmen (ohne Border) und darin dann das Frame3DGadget plazieren.
Dann brauchst Du nur den Container verstecken.
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
Benutzeravatar
FGK
Beiträge: 249
Registriert: 09.01.2005 14:02
Computerausstattung: i5-4430 CPU / 8GB RAM
GeForce GT630
Windows 10 Home / 64-bit
Wohnort: Augsburg

Beitrag von FGK »

Danke Danilo,

jetzt wo ichs per Code vor den Augen hab - leuchtet es mir ein.
Da Gadgets in der Regel so ne Art "Window" sind (werden glaub ich mit CreateWindowEx erzeugt) können die alle ne eigene WindowProc haben?
Da drauf wäre ich trotzdem nie (oder net so schnell) gekommen.

Danke schön nochmals

Gruß

FGK
CNESM
Beiträge: 311
Registriert: 29.08.2004 15:16
Kontaktdaten:

Beitrag von CNESM »

Hi,

erstmal: Schöne Beispiele :)

Mir ist aufgefallen, das das Abfangen aber beim Fenster aber völlig versagt, ansonsten läuft alles reibungslos. Wollte mal fragen, ob das bei euch auch so ist oder nur bei mir? /WinME. Hab den Code mal ein bissle umgebaut aber hilft nix :)
Benutzeravatar
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

Beitrag von Danilo »

FGK hat geschrieben:Da Gadgets in der Regel so ne Art "Window" sind (werden glaub ich mit CreateWindowEx erzeugt) können die alle ne eigene WindowProc haben?
Korrekt. Eigene Fensterklassen haben einen eigenen Callback,
und die Standardklassen (Button, Listview etc.) haben einen
internen Callback vom System.
CNESM hat geschrieben:Mir ist aufgefallen, das das Abfangen aber beim Fenster aber völlig versagt, ansonsten läuft alles reibungslos. Wollte mal fragen, ob das bei euch auch so ist oder nur bei mir? /WinME.
Kannst Du nochmal etwas ausführlicher erklären was Du meinst?

Ich kann da leider nicht richtig rauslesen was Du genau willst.
Sollte es darum gehen Nachrichten von einem Fenster abzufangen,
kannst Du das im WindowCallback machen.
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
CNESM
Beiträge: 311
Registriert: 29.08.2004 15:16
Kontaktdaten:

Beitrag von CNESM »

Hi,

entschudlige, das ganze war auf den ersten Codesatz bezogen. Hab den Code nur mal kurz überflogen und dabei entdeckt, das auch das Kontektmenue des Fenster abgefangen werden sollte (Case WindowID(0)). Bei mir klappt das aber nicht.

Oder sehe ich das mal wieder was falsch?
Benutzeravatar
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

Beitrag von Danilo »

CNESM hat geschrieben:Hab den Code nur mal kurz überflogen und dabei entdeckt, das auch das Kontektmenue des Fenster abgefangen werden sollte (Case WindowID(0)). Bei mir klappt das aber nicht.
Schau mal da:
Per Befehl Kontext Menü öffnen (wie bei Rechte Maus) ?!
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
CNESM
Beiträge: 311
Registriert: 29.08.2004 15:16
Kontaktdaten:

Beitrag von CNESM »

Hi,

naja wollte nur wissen, ob das in diesem Beispiel funktionieren sollte, nicht wie es generell geht, aber dennoch danke fürs Beispiel :)
Antworten