Seite 1 von 1

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

Verfasst: 15.12.2007 21:23
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 ...

Verfasst: 15.12.2007 22:26
von Falko
Das hattest du schon mal :cry:

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

Gruß Falko

Verfasst: 15.12.2007 22:31
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:

Verfasst: 15.12.2007 23:44
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

Verfasst: 16.12.2007 02:04
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).

Verfasst: 16.12.2007 07:31
von Thomas
Ich brauchs halt so:
Wenn ne Variable Eins ist und die Maus über dem ImageGadget, soll sich der Cursor zum Fadenkreuz ändern ...

Verfasst: 16.12.2007 15:21
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

Verfasst: 16.12.2007 16:49
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

Verfasst: 16.12.2007 21:58
von Thomas
ok, Danke! :D
problem gelöst ...

Verfasst: 17.12.2007 13:06
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