Abfrage, Mausbutton, gedrückt/gehalten ?

Anfängerfragen zum Programmieren mit PureBasic.
JayCool
Beiträge: 54
Registriert: 02.08.2007 20:03

Abfrage, Mausbutton, gedrückt/gehalten ?

Beitrag 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
Zuletzt geändert von JayCool am 15.01.2008 15:12, insgesamt 1-mal geändert.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag 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.
Benutzeravatar
roherter
Beiträge: 1407
Registriert: 10.04.2005 18:58
Kontaktdaten:

Beitrag 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 
Purebasic 5.0 32bit und 64 bit

I'm back from hell
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag 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... ;)
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
roherter
Beiträge: 1407
Registriert: 10.04.2005 18:58
Kontaktdaten:

Beitrag von roherter »

OKOK.Sorry hatte wenig Zeit gerade. :)
Purebasic 5.0 32bit und 64 bit

I'm back from hell
JayCool
Beiträge: 54
Registriert: 02.08.2007 20:03

Beitrag 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?
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag 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.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
JayCool
Beiträge: 54
Registriert: 02.08.2007 20:03

Beitrag 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.
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Beitrag 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
Antworten