Anderer Maus-Cursor, wenn Maus über ImageGadget ... [gelöst]

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
Thomas
Beiträge: 893
Registriert: 06.07.2006 19:24
Wohnort: Regensburg
Kontaktdaten:

Anderer Maus-Cursor, wenn Maus über ImageGadget ... [gelöst]

Beitrag von Thomas »

Code: Alles auswählen

OpenWindow(0,10,10,400,200,"CursorTest",#PB_Window_SystemMenu)

CreateGadgetList(WindowID(0))
   ImageGadget(0, 30, 30, 80, 80, 0, #PB_Image_Border)

SetClassLong_(GadgetID(0),#GCL_HCURSOR,0)   ;<<- für was ist das genau?

Cursor = LoadCursor_(0, #IDC_CROSS)

Repeat
  Event = WaitWindowEvent()

  GetCursorPos_(cursorpos.POINT)                                                ;diese
  MapWindowPoints_(0, WindowID(0), cursorpos, 1)                                ;3 Zeilen
  If ChildWindowFromPoint_(WindowID(0), cursorpos\x, cursorpos\y) = GadgetID(0) ;ermitteln doch nur, ob sich der Cursor über dem Imagegadget befindet, oder?
    SetCursor_(Cursor)
  EndIf

Until Event = #PB_Event_CloseWindow

End
Meine Frage steht oben im Code ...
Zuletzt geändert von Thomas am 16.12.2007 21:59, insgesamt 1-mal geändert.
v6.00
Benutzeravatar
Falko
Admin
Beiträge: 3535
Registriert: 29.08.2004 11:27
Computerausstattung: PC: MSI-Z590-GC; 32GB-DDR4, ICore9; 2TB M2 + 2x3TB-SATA2 HDD; Intel ICore9 @ 3600MHZ (Win11 Pro. 64-Bit),
Acer Aspire E15 (Win11 Home X64). Purebasic LTS 6.11b1
HP255G8 Notebook @AMD Ryzen 5 5500U with Radeon Graphics 2.10 GHz 3.4GHz, 32GB_RAM, 3TB_SSD (Win11 Pro 64-Bit)
Kontaktdaten:

Beitrag von Falko »

Das hattest du schon mal :cry:

http://www.purebasic.fr/german/viewtopi ... ght=cursor

Gruß Falko
Bild
Win11 Pro 64-Bit, PB_6.11b1
Benutzeravatar
Thomas
Beiträge: 893
Registriert: 06.07.2006 19:24
Wohnort: Regensburg
Kontaktdaten:

Beitrag von Thomas »

Ja, das weis ich ...
ich möchte nur wissen für was dieses

Code: Alles auswählen

SetClassLong_(GadgetID(0),#GCL_HCURSOR,0)
macht, und

Code: Alles auswählen

 GetCursorPos_(cursorpos.POINT)
  MapWindowPoints_(0, WindowID(0), cursorpos, 1)
  If ChildWindowFromPoint_(WindowID(0), cursorpos\x, cursorpos\y) = GadgetID(0)
was diese 3 Zeilen genau machen; ich vermute mal, das die nur gut sind, um zu überprüfen, ob sich die Maus über dem ImageGadget befindet ... bin mir aber nicht sicher :oops:
v6.00
Benutzeravatar
Falko
Admin
Beiträge: 3535
Registriert: 29.08.2004 11:27
Computerausstattung: PC: MSI-Z590-GC; 32GB-DDR4, ICore9; 2TB M2 + 2x3TB-SATA2 HDD; Intel ICore9 @ 3600MHZ (Win11 Pro. 64-Bit),
Acer Aspire E15 (Win11 Home X64). Purebasic LTS 6.11b1
HP255G8 Notebook @AMD Ryzen 5 5500U with Radeon Graphics 2.10 GHz 3.4GHz, 32GB_RAM, 3TB_SSD (Win11 Pro 64-Bit)
Kontaktdaten:

Beitrag von Falko »

Das mit dem Drei zeiler stimmt nicht ganz. Am besten wäre es, wenn du die Win32.hlp in dein Hilfeverzeichnis kopiert hättest. Dort ist es beschrieben.
GetCursorPos_(cursorpos.POINT)
MapWindowPoints_(0, WindowID(0), cursorpos, 1)
If ChildWindowFromPoint_(WindowID(0), cursorpos\x, cursorpos\y) = GadgetID(0)
The GetCursorPos function retrieves the cursor's position, in screen
coordinates.


The MapWindowPoints function converts (maps) a set of points from a
coordinate space relative to one window to a coordinate space relative to
another window.
(Wandelt die maps in Points um)

The ChildWindowFromPoint function determines which, if any, of the child windows belonging to a parent window contains the specified point.


Zum
SetClassLong_(GadgetID(0),#GCL_HCURSOR,0)

The SetClassLong function replaces the specified 32-bit (long) value at the specified offset into the extra class memory or the WNDCLASS structure for the class to which the specified window belongs.


Naja, zum Übersetzen gibt es ja Google.
So wie ich das sehe, sind die 3 Funktionen frei übersetzt :
Ermitteln des Cursors in eine Structure
wandeln von maps in points
und übertragen der Cursorposition auf das Gadget.

Was SetClassLong .. macht, kann ich auch nicht genau sagen.
Vermutlich muß das Windows-spezifisch angewendet werden.
Man könnte es auch auskommentieren und der Source läuft auch dann noch.

Gruß Falko
Bild
Win11 Pro 64-Bit, PB_6.11b1
Benutzeravatar
Ligatur
Beiträge: 196
Registriert: 09.07.2006 00:41

Beitrag von Ligatur »

Das SetClassLong ist so wie es da steht völlig nutzlos.

Kommentierst du aber die drei Zeilen aus, nach denen du gefragt hast + das SetCursor_() + das EndIf und änderst das SetClassLong() etwas ab erhälst du eine bessere Lösung:

Code: Alles auswählen

OpenWindow(0,10,10,400,200,"CursorTest",#PB_Window_SystemMenu) 

CreateGadgetList(WindowID(0)) 
   ImageGadget(0, 30, 30, 80, 80, 0, #PB_Image_Border) 

Cursor = LoadCursor_(0, #IDC_CROSS) 

SetClassLong_(GadgetID(0),#GCL_HCURSOR,Cursor)   ;<<- für was ist das genau? 

Repeat 
  Event = WaitWindowEvent() 

;   GetCursorPos_(cursorpos.POINT)                                                ;diese 
;   MapWindowPoints_(0, WindowID(0), cursorpos, 1)                                ;3 Zeilen 
;   If ChildWindowFromPoint_(WindowID(0), cursorpos\x, cursorpos\y) = GadgetID(0) ;ermitteln doch nur, ob sich der Cursor über dem Imagegadget befindet, oder? 
;     SetCursor_(Cursor) 
;   EndIf 

Until Event = #PB_Event_CloseWindow 

End
Die 3 Funktionen frei übersetzt währen:

GetCursorPos: Hole die Cursorposition in eine POINT - Struktur
MapWindowPoint: Wandele die übergebenen Punkte (hier nur ein Punkt, die Cursorposition) welche sich auf die linke obere Ecke eines Fensters (hier das Desktopfenster bzw. Screen) beziehen so um, das sie sich auf die linke obere Ecke des zweiten Fensters beziehen, in diesem Fall ist diese Funktion aber eigendlich nicht gut gewählt, da für die Umwandelung nur eines Wertes von Screenkoordinaten als Ursprung ScreenToClient_() besser ist.
ChildWindowFromPoint: Hole das Fenster unter der angegebenen Position bezogen auf die linke obere Ecke des übergeordneten Fensters.

um zu wissen was SetClassLong_() macht sollte man aber zumindest wissen wie ein Fenster per API geöffnet wird. Da das hier aber das Anfängerforum ist wird das hier zu weit führen (das tat wohl eigendlich das bisherige auch schon, letztendlich die ganze Frage).
Benutzeravatar
Thomas
Beiträge: 893
Registriert: 06.07.2006 19:24
Wohnort: Regensburg
Kontaktdaten:

Beitrag von Thomas »

Ich brauchs halt so:
Wenn ne Variable Eins ist und die Maus über dem ImageGadget, soll sich der Cursor zum Fadenkreuz ändern ...
v6.00
Benutzeravatar
Ligatur
Beiträge: 196
Registriert: 09.07.2006 00:41

Beitrag von Ligatur »

Dann lädst du dir halt einmal mit #IDC_ARROW den normalen Cuzrsor und mit #IDC_CROSS den Kreuzcursor und setzt mit SetClassLong den Cursor auf das Kreuz wenn die Variable gesetzt wird und änderst ihn wieder auf Pfeil wenn die Variable wieder auf 0 gesetzt wird
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Beitrag von edel »

Ich habe vor Monaten? mal eine Userlib fuer mich geschrieben,
unteranderem mit folgender Funktion :

Code: Alles auswählen

Prototype wndproc(hWnd, uMsg, wParam, lParam)
 
Structure PB_CURSOR
  newcursor.l
	oldcursor.l
	OldWndProc.wndproc;   
EndStructure

Macro LOWORD(Value)
  (value & $FFFF)
EndMacro

Macro HIWORD(Value)
  (value >> 16 & $FFFF)
EndMacro 	

Procedure mouse_cursor_callback(hWnd, uMsg, wParam, lParam)
  Protected *Cursor.PB_CURSOR = GetWindowLong_(hWnd, #GWL_USERDATA)
  Protected rc.rect
    
  If uMsg = #WM_MOUSEMOVE
    
    GetClientRect_(hWnd, @rc)
		
		If (PtInRect_(@rc, LOWORD(lParam), HIWORD(lParam)))
		  SetCapture_(hWnd)
			*Cursor\oldcursor = SetCursor_(*Cursor\newcursor)
		Else
		  ReleaseCapture_()
			SetCursor_(*Cursor\oldcursor)
	  EndIf
	  	
  EndIf   

  If (uMsg = #WM_NCDESTROY)  	
		SetWindowLong_(hWnd, #GWL_WNDPROC, *Cursor\OldWndProc)
		SetWindowLong_(hWnd, #GWL_USERDATA, 0)
		FreeMemory(*Cursor)
		ProcedureReturn 0;DefWindowProc_(hWnd, uMsg, wParam, lParam)				
	EndIf
	
  ProcedureReturn *Cursor\OldWndProc(hWnd, uMsg, wParam, lParam)
EndProcedure

Procedure SetGadgetCursor(id,newCursor)
  Protected *Gadget.LONG = IsGadget(id)
	Protected *Cursor.PB_CURSOR 
	
	If Not *Gadget
		ProcedureReturn  0
	EndIf
	
	*Cursor = GetWindowLong_(*Gadget\l, #GWL_USERDATA)
			
	If Not *Cursor	
		*Cursor = AllocateMemory(SizeOf(PB_CURSOR))
	EndIf
		
	If Not *Cursor	
		ProcedureReturn 0
	EndIf
	
	If Not newCursor

	  If *Cursor\OldWndProc
		  SetWindowLong_(*Gadget\l, #GWL_WNDPROC, *Cursor\OldWndProc)
	  EndIf
		
		SetWindowLong_(*Gadget\l, #GWL_USERDATA, 0)
		
		FreeMemory(*Cursor)
		
		ProcedureReturn 0
	EndIf
	
	*Cursor\OldWndProc = SetWindowLong_(*Gadget\l, #GWL_WNDPROC, @mouse_cursor_callback())
	SetWindowLong_(*Gadget\l, #GWL_USERDATA, *Cursor)
	
	*Cursor\newcursor  = newCursor
	
	ProcedureReturn 1
EndProcedure
Test :

Code: Alles auswählen

hwnd = OpenWindow(0,0,0,200,200,"")

CreateGadgetList(hwnd)
ButtonGadget(0,0,0,100,100,"hand aus")
CheckBoxGadget(1,120,10,100,20,"")

hand = LoadCursor_(0,#IDC_HAND)



Repeat
  e = WaitWindowEvent() 
  
  If e = #PB_Event_Gadget 
    If EventGadget() = 1
      an ! 1
      
      If an = 1
        SetGadgetCursor(0,hand)
        SetGadgetText(0,"hand an")
      Else  
        SetGadgetText(0,"hand aus")
        SetGadgetCursor(0,0)
      EndIf
    EndIf 
  EndIf
  
Until e = #PB_Event_CloseWindow
Benutzeravatar
Thomas
Beiträge: 893
Registriert: 06.07.2006 19:24
Wohnort: Regensburg
Kontaktdaten:

Beitrag von Thomas »

ok, Danke! :D
problem gelöst ...
v6.00
Benutzeravatar
Shardik
Beiträge: 746
Registriert: 25.01.2005 12:19

Beitrag von Shardik »

Im englischen Forum hatte auch netmaestro schon ein Beispiel vorgestellt, das sogar ohne Callback auskommt:
http://www.purebasic.fr/english/viewtop ... 84&start=1
Antworten