Seite 1 von 1

Abfrage, Mausbutton, gedrückt/gehalten ?

Verfasst: 15.01.2008 14:24
von JayCool
Hi,

in meinem Programm will ich erreichen, dass überall dort, wo ich mit der Maus ins schwarze Image-Gadget klicke, ein weißes Quadrat gezeichnet wird.

Allerdings wird ein Quadrat nur beim allerersten Klick gezeichnet, dann nicht mehr. Kann mir jemand den Grund erklären?

Code: Alles auswählen

If OpenWindow(0, 0, 0, 800, 600, "MouseDraw", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  CreateImage(1,760,560)
  CreateGadgetList(WindowID(0))
  ImageGadget(0,20,20,760,560,ImageID(1))
  OutputID = ImageOutput(1)
  
  Repeat
    Event = WaitWindowEvent() 
    If Event = #PB_Event_Gadget
      If EventGadget() = 0 
        If EventType() = #PB_EventType_LeftClick
          x = WindowMouseX(0)
          y = WindowMouseY(0)
          StartDrawing(OutputID)
            Box(x,y,20,20,RGB(255,255,255))
          StopDrawing()    
          SetGadgetState(0,ImageID(1))
        EndIf
      EndIf
    EndIf
  Until Event = #PB_Event_CloseWindow
EndIf

Verfasst: 15.01.2008 14:34
von NicTheQuick
Unter Linux funktioniert der Code. Allerdings hast du wahrscheinlich das
Offset vergessen.

Code: Alles auswählen

          x = WindowMouseX(0) - 20
          y = WindowMouseY(0) - 20
Unter Windows könnte es sein, dass du das 'ImageGadget()' zuerst mit
'DisableGadget()' deaktivieren musst. Ich glaube, dann funktioniert es.

Verfasst: 15.01.2008 14:35
von roherter

Code: Alles auswählen

If OpenWindow(0, 0, 0, 800, 600, "MouseDraw", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  CreateImage(1,760,560)
  CreateGadgetList(WindowID(0))
  ImageGadget(2,20,20,760,560,ImageID(1))
  OutputID = ImageOutput(1)
  
  Repeat
    Event = WaitWindowEvent()
    If Event = #PB_Event_Gadget
      If EventGadget() = 2
        If EventType() = #PB_EventType_LeftClick
          Debug "jj"
          x = WindowMouseX(0)
          y = WindowMouseY(0)
          StartDrawing(ImageOutput( 1))
          Box(x,y,20,20,RGB(255,255,255))
          StopDrawing()   
          SetGadgetState(2,ImageID(1))
        EndIf
      EndIf
    EndIf
  Until Event = #PB_Event_CloseWindow
EndIf 

Verfasst: 15.01.2008 15:04
von Kaeru Gaman
unter windows kann die OutputID für den Drawing-Vorgang nicht gepuffert werden, du musst sie für jeden Zugriff ermitteln. Anscheinend bleibt sie nicht konstant.

@roherter
mehr text, weniger code... ;)

Verfasst: 15.01.2008 15:08
von roherter
OKOK.Sorry hatte wenig Zeit gerade. :)

Verfasst: 15.01.2008 15:09
von JayCool
Hi,

ich hab' nochmal nen Code gebaut. Jetzt klappts.

Code: Alles auswählen

  If OpenWindow(0, 0, 0, 300, 300, "Fenster Maus-Monitor", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    CreateImage(1,100,100)
    CreateGadgetList(WindowID(0))
      TextGadget(0, 10, 6, 200, 20, "")
      ImageGadget(1,100,100,100,100,ImageID(1))
    
    Repeat
      Event = WaitWindowEvent(20) ; kehre mindestens alle 20 ms für ein Update zurück
      
      SetGadgetText(0, "Fenster Maus-Position: " + Str(WindowMouseX(0)) + "," + Str(WindowMouseY(0)))
      et = EventType()
;       If et <> -1
;         Debug Str(et)
;       EndIf
      If EventGadget()=1 And et = #PB_EventType_LeftClick ;EventType() 
        x = WindowMouseX(0)
        y = WindowMouseY(0)
        
        StartDrawing(ImageOutput(1))
          Box(x-100,y-100,10,10,RGB(255,255,255))
        StopDrawing()
        
        SetGadgetState(1,ImageID(1))
        
        ;Debug Str(x)+"     "+Str(y)
      EndIf
    Until Event = #PB_Event_CloseWindow
  EndIf
Jetzt hab' ich aber zufällig nochmal 'ne etwas schwierigere Frage:
Ist es möglich, zu ermitteln, ob der Mausbutton aktuell noch gedrückt ist, und wenn ja, wie?

Verfasst: 15.01.2008 15:19
von Kaeru Gaman
PB-only:
mit nem Flag arbeiten, eine Variable, die "mitschreibt", ob der Button im letzten Durchlauf schon gedrückt war.

Win-API:
von GetAsyncKeystate_(#VK_LBUTTON) bekommst du unterschiedliche rückgabewerte,
je nachdem, ob der button geclickt oder gehalten wurde.

Verfasst: 15.01.2008 16:18
von JayCool
Kaeru Gaman hat geschrieben:PB-only:
mit nem Flag arbeiten, eine Variable, die "mitschreibt", ob der Button im letzten Durchlauf schon gedrückt war.
Das geht nicht, da es hier kein Event gibt von nem Typ, was ich mal so oberflächlich 'ReleaseButton' nennen würde.



Win-API:
von GetAsyncKeystate_(#VK_LBUTTON) bekommst du unterschiedliche rückgabewerte,
je nachdem, ob der button geclickt oder gehalten wurde.
Werd' mal probieren, ob ich das hinkrieg.

Verfasst: 15.01.2008 16:30
von edel
Wenn du auf andere Betriebssysteme verzichten kannst
gibt es mit der Winapi eine sehr einfache Lösung

Code: Alles auswählen

Global oldCallback

Macro LOWORD(value) : (value & $FFFF)       : EndMacro
Macro HIWORD(value) : (value >> 16 & $FFFF) : EndMacro 

Procedure ImageCallback(hwnd,msg,wparam,lparam)

	If msg = #WM_LBUTTONDOWN 	
		SendMessage_(hwnd,#WM_MOUSEMOVE,#MK_LBUTTON,lparam)
	EndIf 
		
	If msg = #WM_MOUSEMOVE And #MK_LBUTTON & wparam		
		StartDrawing(ImageOutput(1))
			x = LOWORD(lparam) 
			y = HIWORD(lparam) 
			Box(x,y,6,6,$FFFFFF)
		StopDrawing()  						
		SetGadgetState(0,ImageID(1))
	EndIf 
	
	ProcedureReturn CallWindowProc_(oldCallback,hwnd,msg,wparam,lparam)
EndProcedure

If OpenWindow(0, 0, 0, 800, 600, "MouseDraw", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  CreateImage(1,760,560)
  CreateGadgetList(WindowID(0))
  ImageGadget(0,20,20,760,560,ImageID(1))
   
 	oldCallback = SetWindowLong_(GadgetID(0),#GWL_WNDPROC,@ImageCallback())
 
  Repeat
    Event = WaitWindowEvent()    
  Until Event = #PB_Event_CloseWindow
  
EndIf