Seite 1 von 1

Mausklick: an inaktive Fenster + Koordinaten ändern [Gelöst]

Verfasst: 19.07.2008 23:04
von K.Putt
Hallo,
Ich habe eine GUI mit einem Panel-Gadget.

Theorie:

Wenn auf dem Hauptpanel (Tab_0) ein einfacher Linksklick erfolgt, sollen automatisch alle anderen Panels diesen Klick erhalten -
allerdings sollen die Koordinaten etwas verändert sein.
D.h. z.B.:
in Tab_1 10 Pixel weiter rechts,
in Tab_2 10 Pixel links,
in Tab_3 10 Pixel höher,
in Tab_4 10 Pixel tiefer.

Der Mauszeiger im Tab_0 darf sich nicht dabei bewegen, so dass ein ungestörter Arbeitsfluss möglich ist.

Praxis:
Mit mouse_event_() kann man einen Linksklick simulieren.

Problem:
Wie sende ich den Klick an die anderen (inakiven) Tabs?

Jeder Trick oder Kniff wäre interessant, egal wie umständlich das Umzusetzen wäre.

Puh, ich hoffe das ist nicht zu viel auf einmal:-)
Ich bedanke mich schon einmal,
schönen abend!

ADDED:
OK, mir ist noch etwas eingefallen:
Wenn ich statt dem Panel Gadget mehrere Fenster benutze die ich exakt
hinter dem Hauptfenster verstecke, dann könnte ich theoretisch
SendMessage_() an das jeweilige Fenster benutzen.

Ich teste mal...

Verfasst: 20.07.2008 01:20
von K.Putt
So, ich habe jetzt mal 2 simple Beispielcodes, beide als Version mit jeweils 2 Fenstern, keiner von beiden funktioniert (leider):

Nummero Uno (für die Tonne :-)

ADDED:
Dieser Code funktioniert nicht, weil der Mauszeiger mit
SetCursorPos_(x, y)
positioniert werden muss.
Die Angaben bei mouse_event_() allein reichen nicht aus um eine Aktion
an der angegeben Koordinate auszuführen.

Code: Alles auswählen


#MOUSEEVENTF_LEFTDOWN = $2 
#MOUSEEVENTF_LEFTUP = $4 

Enumeration 
  #FirstWindow 
  #SecondWindow 
EndEnumeration 

Enumeration 
  #Button1 
  #Button2  
EndEnumeration 

Procedure SecondWindow() 
OpenWindow(#SecondWindow,0,0,300,200,"SecondWindow",#PB_Window_TitleBar|#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered) 
CreateGadgetList(WindowID(#SecondWindow))  
ButtonGadget(#Button2, 40, 40, 20, 20, "X")
EndProcedure 

Procedure FirstWindow() 
OpenWindow(#FirstWindow,0,0,300,200,"FirstWindow",#PB_Window_TitleBar|#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered) 
CreateGadgetList(WindowID(#FirstWindow))  
ButtonGadget(#Button1, 10, 10, 20, 20, "X")
EndProcedure 

Procedure SimulateClick()
hwnd = FindWindow_(#Null, "SecondWindow")
GetCursorPos_(pt.POINT)
mx= pt\x 
my= pt\y 
mx=mx+30
my=my+30
SetActiveWindow(#SecondWindow)
mouse_event_(#MOUSEEVENTF_LEFTDOWN, mx, my, 0, 0)
EndProcedure

Procedure EventHandling()
  Repeat 
   EventID=WaitWindowEvent() 
    Select EventID 
      Case #PB_Event_Gadget 
        Select EventGadget() 
          Case #Button1 
              Debug "Fenster1 - Button1"		
              SimulateClick()
          Case #Button2 
              Debug "Fenster2 - Button2"
        EndSelect 
    EndSelect 
  Until EventID=#PB_Event_CloseWindow
  CloseWindow(#SecondWindow) 
  CloseWindow(#FirstWindow) 
  End
EndProcedure

Procedure Main()
SecondWindow()
FirstWindow()
SetActiveWindow(#FirstWindow)
EventHandling()
EndProcedure

Main()

Deuxieme (ebenfalls :-)

Code: Alles auswählen

Enumeration 
  #FirstWindow 
  #SecondWindow 
EndEnumeration 

Enumeration 
  #Button1 
  #Button2  
EndEnumeration 

Procedure SecondWindow() 
OpenWindow(#SecondWindow,0,0,300,200,"SecondWindow",#PB_Window_TitleBar|#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered) 
CreateGadgetList(WindowID(#SecondWindow))  
ButtonGadget(#Button2, 40, 40, 20, 20, "X")
EndProcedure 

Procedure FirstWindow() 
OpenWindow(#FirstWindow,0,0,300,200,"FirstWindow",#PB_Window_TitleBar|#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered) 
CreateGadgetList(WindowID(#FirstWindow))  
ButtonGadget(#Button1, 10, 10, 20, 20, "X")
EndProcedure 

Procedure MakelParam(low.w, high.w)
  ProcedureReturn low + (high << 16)
EndProcedure

Procedure SimulateClick()
hwnd = FindWindow_(#Null, "SecondWindow")
GetCursorPos_(pt.POINT)
mx.w = pt\x 
my.w= pt\y 
mx= mx+30
my=my+30
lParam = MakelParam(mx.w, my.w)
SendMessage_(hwnd, WM_LBUTTONDOWN, 0, lParam);
SendMessage_(hwnd, WM_LBUTTONUP, 0, lParam);
EndProcedure

Procedure EventHandling()
  Repeat 
   EventID=WaitWindowEvent() 
    Select EventID 
      Case #PB_Event_Gadget 
        Select EventGadget() 
          Case #Button1 
              Debug "Fenster1 - Button1"		
              SimulateClick()
          Case #Button2 
 		          Debug "Fenster2 - Button2"
        EndSelect 
    EndSelect
  Until EventID=#PB_Event_CloseWindow
  CloseWindow(#SecondWindow) 
  CloseWindow(#FirstWindow) 
  End
EndProcedure

Procedure Main()
SecondWindow()
FirstWindow()
SetActiveWindow(#FirstWindow)
EventHandling()
EndProcedure

Main()

Ideen?

Verfasst: 21.07.2008 03:00
von K.Putt
Huhu!
Bin so allein :-)

Hab den Code jetzt mal für Tests abgeändert,
statt 2 Fenstern benutze ich nur noch eines und statt
Panel Gadget und Button kommt ein Webgadget mit
Javascript zum Einsatz, das auf einen Linksklick reagiert
(LBUTTONDOWN)

Tatsächlich reagiert es nicht, nicht einmal wenn der Cursor
vorher positioniert wird.

Ich habe mal "schweres Geschütz" aufgefahren
(bitte nicht lachen, ich teste etwa 12 Programmierstunden),
den Fehler kann ich immer noch nicht lokalisieren:

Code: Alles auswählen


Enumeration
  #FirstWindow
  #Web1
  #Button1
EndEnumeration

Macro MAKELPARAM(a,b)
  ((b&$FFFF)<<16|(a&$FFFF))
EndMacro 

Procedure WindowOpen()
  OpenWindow(#FirstWindow,0,0,800,600,"Window")
  CreateGadgetList(WindowID(#FirstWindow)) 
    ButtonGadget(#Button1, 10, 10, 40, 20, "Test")
    WebGadget(#Web1, 10, 40, 760, 520, "test.html")
EndProcedure

Procedure MakelParameter(low.w, high.w)
  ProcedureReturn low + (high << 16)
EndProcedure

Procedure SimulateClick()
  mx.w= 150
  my.w= 150
  lParam = MakelParameter(mx.w, my.w)
  mx2=150
  my2=150
  SetCursorPos_(mx2,my2)  ; da müsste der Klick eigentlich erfolgen...
  
  SendMessage_(WindowID(#FirstWindow), #WM_LBUTTONDOWN, #Null, lParam);
  SendMessage_(WindowID(#FirstWindow), #WM_LBUTTONDOWN, #Null, MAKELPARAM(mx,my));
  SendMessage_(WindowID(#FirstWindow), #WM_NCLBUTTONDOWN, #Null, lParam);
  SendMessage_(WindowID(#FirstWindow), #WM_NCLBUTTONDOWN, #Null, MAKELPARAM(mx,my));
  SendMessage_(WindowID(#FirstWindow), #WM_LBUTTONDOWN, #MK_LBUTTON, lParam);
  SendMessage_(WindowID(#FirstWindow), #WM_LBUTTONDOWN, #MK_LBUTTON, MAKELPARAM(mx,my));
  SendMessage_(WindowID(#FirstWindow), #WM_NCLBUTTONDOWN, #MK_LBUTTON, lParam);
  SendMessage_(WindowID(#FirstWindow), #WM_NCLBUTTONDOWN, #MK_LBUTTON, MAKELPARAM(mx,my));

  SendMessage_(GadgetID(#Web1), #WM_LBUTTONDOWN, #Null, lParam);  
  SendMessage_(GadgetID(#Web1), #WM_LBUTTONDOWN, #Null, MAKELPARAM(mx,my));
  SendMessage_(GadgetID(#Web1), #WM_NCLBUTTONDOWN, #Null, lParam);
  SendMessage_(GadgetID(#Web1), #WM_NCLBUTTONDOWN, #Null, MAKELPARAM(mx,my));
  SendMessage_(GadgetID(#Web1), #WM_LBUTTONDOWN, #MK_LBUTTON, lParam);
  SendMessage_(GadgetID(#Web1), #WM_LBUTTONDOWN, #MK_LBUTTON, MAKELPARAM(mx,my));
  SendMessage_(GadgetID(#Web1), #WM_NCLBUTTONDOWN, #MK_LBUTTON, lParam);
  SendMessage_(GadgetID(#Web1), #WM_NCLBUTTONDOWN, #MK_LBUTTON, MAKELPARAM(mx,my));

Debug "done..."
EndProcedure

Procedure EventHandling()
  Repeat
    GetCursorPos_(pt.POINT) 
    Debug "x:" + Str(pt\x) + "y:" + Str(pt\y)
    EventID=WaitWindowEvent()
    Select EventID
      Case #PB_Event_Gadget
        Select EventGadget()
          Case #Button1    
              SimulateClick()     
        EndSelect
    EndSelect
  Until EventID=#PB_Event_CloseWindow
  CloseWindow(#FirstWindow)
  End
EndProcedure

Procedure Main()
  WindowOpen()
  EventHandling()
EndProcedure

Main() 

Die test.html

Code: Alles auswählen

<html><head><title>Test</title>
<script type="text/javascript">
function Mausklick (Ereignis) {
  if (!Ereignis)
    Ereignis = window.event;
  if (document.getElementById) {
    document.getElementById("Springer").style.left  = Ereignis.clientX + "px";
    document.getElementById("Springer").style.top = Ereignis.clientY + "px";
  } else if (document.all) {
    document.all.Springer.style.left = Ereignis.clientX;
    document.all.Springer.style.top = Ereignis.clientY;
  }
}
document.onmousedown = Mausklick;
</script>
</head><body>
<div id="Springer" style="background-color:#FF0000; position:absolute;
top:50px; left:50px; width:50px; height:50px;"></div>
</body></html>
Es kommt also überhaupt kein Klick an, weder im Window noch im Gadget.

Kennt Jemand die Ursache?

Verfasst: 22.07.2008 08:41
von K.Putt
Lösung:
Im englischen Forum hat mir ein User erklärt wie man Buttons ansteuert.
Nachdem es mit dem Webgadget trotzdem nicht funktioniert hat einen Klick zu simulieren, wollte ich es mit dem Desktop probieren.
Dazu habe ich das Handle des Desktops mit WindowFromPoint() erhalten.
Beim Herumklicken und Debuggen (also Spielen :-)) ist mir dann folgendes aufgefallen:

Das Problem mit dem Webgadget ist, dass die GadgetID() des WebGaddets nicht das Handle des Browsers in dem WebGadget ist.
Mit WindowFromPoint() lässt sich diese ermitteln, dann kann man Klicks auf jede Koordinate des WebGadgets simulieren.

Buttons muss man direkt als Gadget ansteuern, per simulierten Klick auf eine Koordinate innerhalb des Buttons (also an das übergeordnete Window gesendet) werden diese nicht aktiviert.

Hier noch schnell der Code wen's interessiert:

Code: Alles auswählen

Macro MAKELPARAM(a,b)
  ((b&$FFFF)<<16|(a&$FFFF))
EndMacro 

OpenWindow(1,0,0,800,600,"hi")
CreateGadgetList(WindowID(1))
WebGadget(3, 10, 40, 460, 320, "test.html")

Repeat
  EventID=WaitWindowEvent()
   If GetAsyncKeyState_(#VK_LBUTTON)
    GetCursorPos_(pt.POINT)
    mx = pt\x 
    my= pt\y 
    curWindow = WindowFromPoint_(mx, my)
    Debug curWindow
    Debug GadgetID(3)
      SendMessage_(curWindow,#WM_LBUTTONDOWN,0,makelparam(10,10)) ;sendet einen Klick an 10,10
    Delay(50)
  EndIf
Until EventID=#PB_Event_CloseWindow
CloseWindow(1)
End
Code für test.html weiter oben.