Mauszeiger

Anfängerfragen zum Programmieren mit PureBasic.
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

Re: Mauszeiger

Beitrag von NicTheQuick »

Das hilft uns immer noch nicht sonderlich weiter, denn dein Code ist nach wie vor so nicht lauffähig. Im Übrigen habe ich einen Vorschlag für dich gebastelt, der besser zu handhaben ist also deine Makro-Lösung mit den 60 Ifs:

Code: Alles auswählen

DataSection
	GadgetsToCheck:
		Data.i 59 ;Anzahl der zu überprüfenden Gadgets
		;Und hier dann die 59 zu überprüfenden Gadget-Nummern
		Data.i 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20
		Data.i 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37
		Data.i 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54
		Data.i 55, 56, 57, 58, 59, 60
EndDataSection

Restore GadgetsToCheck
Define maxGadgets.i, AC.i, i.i
Read.i maxGadgets

GetCursorPos_(mouse.POINT) ;Es reicht aus das einmal abzufragen
For i = 1 To maxGadgets
	Read.i AC
	If GetWindowRect_(GadgetID(AC), GadgetRect.RECT)
		If mouse\x >= GadgetRect\Left And mouse\x <= GadgetRect\right And mouse\y >= GadgetRect\Top And mouse\y <= GadgetRect\bottom
			If AC > 0 And i < 121
				SetSystemCursor_(LoadCursor_(0, #IDC_HAND), #OCR_NORMAL)
			EndIf
			GTX = AC
			GT$ = GetGadgetText(GTX)     
			If AC > 500 And AC < 521 And GT$ <> ""
				SetSystemCursor_(LoadCursor_(0,#IDC_HAND), #OCR_NORMAL)
				HideGadget(AC + 40, 0)
				HideGadget(AC + 100, 0)
			EndIf
			Break ;Beende die For-Schleife, wenn die Maus über diesem Gadget steht
		EndIf
	EndIf
Next
If i > maxGadgets ;wenn kein Gadget gefunden wurde, ist i eins größer als maxGadgets, stellt also den Else-Fall dar.
	SetSystemCursor_(LoadCursor_(0, #IDC_ARROW), #OCR_NORMAL)
EndIf
ToolBoy
Beiträge: 42
Registriert: 01.01.2010 16:19
Computerausstattung: Win 98ME, XP Home und Pro, Win2000 und WinVista32 Home Pre.
Wohnort: Duisburg

Re: Mauszeiger

Beitrag von ToolBoy »

OH Dankr,

dass sieht nicht schlecht aus, besser als 60 mal verschachtelte IF Abfragen.

Das werde ich am WE testen und berichten.

Gruß ToolBoy
Windows 7 U. Windows 10 pro.
ToolBoy
Beiträge: 42
Registriert: 01.01.2010 16:19
Computerausstattung: Win 98ME, XP Home und Pro, Win2000 und WinVista32 Home Pre.
Wohnort: Duisburg

Re: Mauszeiger

Beitrag von ToolBoy »

Ich habe mal schnell einen kleinen Textaufbau gemacht und wenn hierbei, die Maus unter Win 7 nicht flackert, ist alles 0K. Auf jeden Fall viel einfacher und effizienter als meine 60 Schleifen Durchgänge.

Code: Alles auswählen

Current$ = GetCurrentDirectory()

DataSection
   GadgetsToCheck:
      Data.i 12 ;Anzahl der zu überprüfenden Gadgets
      ;Und hier dann die 59 zu überprüfenden Gadget-Nummern
      Data.i 1,2,3,4
      Data.i 5,6,7,8
      Data.i 9,10
      Data.i 11,12
    EndDataSection  
    
 
OpenWindow(0,0,0,400,400,"Gadget unter der Maus",#PB_Window_ScreenCentered|#PB_Window_MinimizeGadget)

ButtonGadget(1, 5, 10, 80, 20, "OK")
ButtonGadget(2, 5, 40, 80, 20, "OK")
ButtonGadget(3, 5, 70, 80, 20, "OK")
ButtonGadget(4, 5, 100, 80, 20, "OK")
ButtonGadget(5, 110, 10, 80, 20, "OK")
ButtonGadget(6, 110, 40, 80, 20, "OK")
ButtonGadget(7, 110, 70, 80, 20, "OK")
ButtonGadget(8, 110, 100, 80, 20, "OK")
ButtonGadget(9, 210, 10, 80, 20, "OK")
ButtonGadget(10,210, 40, 80, 20, "OK")
ButtonGadget(11,210, 70, 80, 20, "OK")
TextGadget(12,210, 100, 80, 20, "OK")

Repeat
  

  
Restore GadgetsToCheck
Define maxGadgets.i, AC.i, i.i
Read.i maxGadgets    
  
GetCursorPos_(mouse.POINT) ;Es reicht aus das einmal abzufragen
For i = 1 To maxGadgets
   Read.i AC
   If GetWindowRect_(GadgetID(AC), GadgetRect.RECT)
      If mouse\x >= GadgetRect\Left And mouse\x <= GadgetRect\right And mouse\y >= GadgetRect\Top And mouse\y <= GadgetRect\bottom
        SetSystemCursor_(LoadCursor_(0, #IDC_HAND), #OCR_NORMAL)
        HideGadget(1,1) ; Nur zum Test
         Break ;Beende die For-Schleife, wenn die Maus über diesem Gadget steht
       EndIf
     EndIf
   
Next 
If i > maxGadgets ;wenn kein Gadget gefunden wurde, ist i eins größer als maxGadgets, stellt also den Else-Fall dar.
  SetSystemCursor_(LoadCursor_(0, #IDC_ARROW), #OCR_NORMAL)
  HideGadget(1,0) ; Nur zum Test
EndIf


Event = WaitWindowEvent()


Until Event = #PB_Event_CloseWindow
Ich DANKE Dir
Windows 7 U. Windows 10 pro.
ToolBoy
Beiträge: 42
Registriert: 01.01.2010 16:19
Computerausstattung: Win 98ME, XP Home und Pro, Win2000 und WinVista32 Home Pre.
Wohnort: Duisburg

Re: Mauszeiger

Beitrag von ToolBoy »

SCHADE

Läuft nicht unter Win 7 unter ME und XP wird alles richtig ausgeführt.

Unter Win 7 flattert / flimmert die Maus gewaltig auf einem Gadget und das Endergebnis ist immer anders, mal ist die Mouse Hand auf ein Gadget oder der Maus Zeiger und ab und zu wird die Mouse Hand wird nach Programmende weiter von Win 7 als normaler Mouse Zeiger benutzt.

Jetzt muss ich aber arbeiten gehen.
ToolBoy

PS: Googel mal nach Maus flattern bei Windows 7.
In Office 7 mit Win 7 soll das noch schlimmer sein als bei mir.
Windows 7 U. Windows 10 pro.
Benutzeravatar
Kiffi
Beiträge: 10714
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: Mauszeiger

Beitrag von Kiffi »

ich weiß ja nicht genau, was Du da machen willst. Ich vermute mal,
dass Du anstelle des Pfeil-Cursors den Hand-Cursor setzen willst, wenn
Du über den entsprechenden Gadgets bist (beim nächsten Mal bitte
dazuschreiben).

SetSystemCursor_() ist in diesem Fall erst einmal falsch gewählt,
weil der Cursor (wie der Name schon vermuten lässt) systemweit gesetzt wird.
SetCursor_() ist hier die bessere Wahl.

LoadCursor_() brauchst Du auch nicht jedes Mal aufzurufen.

Hier mal ein verbesserter Code (wenn auch noch nicht optimal):

Code: Alles auswählen

 ; Inspiration: http://www.purebasic.fr/english/viewtopic.php?p=267198#p267198
EnableExplicit

Global HandCursor =LoadCursor_(0, #IDC_HAND)

Procedure WinCallback(hWnd, uMsg, wParam, lParam)
  
  Protected GadgetCounter
  Protected WinCallbackResult
  
  WinCallbackResult = #PB_ProcessPureBasicEvents
  
  Select uMsg
      
    Case #WM_SETCURSOR
      
      For GadgetCounter = 1 To 11
        If GadgetID(GadgetCounter) = wParam
          SetCursor_(HandCursor)
          WinCallbackResult = 1
          Break
        EndIf
      Next      
      
  EndSelect
  
  ProcedureReturn WinCallbackResult
  
EndProcedure

OpenWindow(0,0,0,400,400,"Gadget unter der Maus",#PB_Window_ScreenCentered|#PB_Window_MinimizeGadget)

ButtonGadget(1, 5, 10, 80, 20, "OK")
ButtonGadget(2, 5, 40, 80, 20, "OK")
ButtonGadget(3, 5, 70, 80, 20, "OK")
ButtonGadget(4, 5, 100, 80, 20, "OK")
ButtonGadget(5, 110, 10, 80, 20, "OK")
ButtonGadget(6, 110, 40, 80, 20, "OK")
ButtonGadget(7, 110, 70, 80, 20, "OK")
ButtonGadget(8, 110, 100, 80, 20, "OK")
ButtonGadget(9, 210, 10, 80, 20, "OK")
ButtonGadget(10,210, 40, 80, 20, "OK")
ButtonGadget(11,210, 70, 80, 20, "OK")
TextGadget(12,210, 100, 80, 20, "OK")

SetWindowCallback(@WinCallback())

Repeat
Until WaitWindowEvent()=#PB_Event_CloseWindow
Damit dürfte das Flackern schon mal ein wenig gemildert sein.

Grüße ... Kiffi
a²+b²=mc²
Benutzeravatar
Josh
Beiträge: 1028
Registriert: 04.08.2009 17:24

Re: Mauszeiger

Beitrag von Josh »

Ich habe auch grad rumgebastelt. Kiffi war wieder mal schneller. Aber trotzdem mein Ergebnis:

Den Systemcursor zu verändern ist auf jeden Fall nicht die feine Art. Selbst wenn du SetCursor_ verwendest, bekommst du ein leichtes Flackern, weil Windows bei jedem MouseMove versucht auf den Klassencursor zurückzusetzen. Du könntest jetzt den Klassencursor verändern, dann hast du aber den veränderten Cursor auf z.B. allen Buttons. Besser ist ein Hook auf die Gadgets.

Das war mein Ergebnis:

Code: Alles auswählen

EnableExplicit

Define Event
Define i

Procedure CbGadget (hWnd, uMsg, wParam, lParam)
  Define ClassName.s{20}

  If uMsg = #WM_SETCURSOR
    SetCursor_(LoadCursor_(0, #IDC_HAND))
    ProcedureReturn
  EndIf

  If uMsg = #WM_NCHITTEST
    GetClassName_(hWnd, @ClassName, 20)
    If ClassName = "Static"
      SetCursor_(LoadCursor_(0, #IDC_HAND))
      ProcedureReturn
    EndIf
  EndIf

  ProcedureReturn CallWindowProc_(GetProp_(hWnd, "OldProc"), hWnd, uMsg, wParam, lParam)

EndProcedure

OpenWindow (0,0,0,400,400,"Gadget unter der Maus",#PB_Window_ScreenCentered|#PB_Window_MinimizeGadget)

ButtonGadget (1,   5,  10, 80, 20, "OK")
ButtonGadget (2,   5,  40, 80, 20, "OK")
ButtonGadget (3,   5,  70, 80, 20, "OK")
ButtonGadget (4,   5, 100, 80, 20, "OK")
ButtonGadget (5, 110,  10, 80, 20, "OK")
ButtonGadget (6, 110,  40, 80, 20, "OK")
ButtonGadget (7, 110,  70, 80, 20, "OK")
ButtonGadget (8, 110, 100, 80, 20, "OK")
ButtonGadget (9, 210,  10, 80, 20, "OK")
ButtonGadget (10,210,  40, 80, 20, "OK")
ButtonGadget (11,210,  70, 80, 20, "OK")
TextGadget   (12,210, 100, 80, 20, "OK")

For i = 1 To 12
  SetProp_ (GadgetID(i), "OldProc", SetWindowLongPtr_(GadgetID(i), #GWL_WNDPROC, @CbGadget()))
Next

Repeat

  Event = WaitWindowEvent()

  If Event = #PB_Event_CloseWindow
    For i = 1 To 12
      RemoveProp_(GadgetID(i), "OldProc")
    Next
    End
  EndIf

ForEver
ToolBoy
Beiträge: 42
Registriert: 01.01.2010 16:19
Computerausstattung: Win 98ME, XP Home und Pro, Win2000 und WinVista32 Home Pre.
Wohnort: Duisburg

Re: Mauszeiger

Beitrag von ToolBoy »

Ich danke euch,

ich kannte nur die Änderung des Systemcursor, natürlich tauchen da Problehme auf, wenn ich scharf nachdenke.
Die Version vom Kiffi gefällt mir besser, bei ForEver bekomme ich immer Schwindsucht, wenn ich ForEver in ein fertiges Prog einbauen will.

Nach dem testen auf Win7 melde ich mich wieder.

Gruß ToolBoy
Windows 7 U. Windows 10 pro.
ToolBoy
Beiträge: 42
Registriert: 01.01.2010 16:19
Computerausstattung: Win 98ME, XP Home und Pro, Win2000 und WinVista32 Home Pre.
Wohnort: Duisburg

Re: Mauszeiger

Beitrag von ToolBoy »

Hurra,

beide Versionen flimmerfrei auf Win 7.

Version vom Kiffi erkennt keine TextGadget, mit ImageGadget noch nicht getestet.

Die Version von Josh funst auch mit TextGadget, unterstelle einfach dann auch mit ImageGadget.
ForEver habe ich einfach durch Until WaitWindowEvent()=#PB_Event_CloseWindow ersetzt und das klappte auf anhieb.

Ich danke euch beide. Jetzt bin ich zwei Wochen weg einige 1000 Zeilen neu Schreiben.

:allright: :bounce: :allright:
Windows 7 U. Windows 10 pro.
Benutzeravatar
Kiffi
Beiträge: 10714
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: Mauszeiger

Beitrag von Kiffi »

ToolBoy hat geschrieben:Version vom Kiffi erkennt keine TextGadget
... weil ein TextGadget normalerweise auch kein Event erzeugt. Um diese
Funktionalität zu erreichen, müsstest Du noch ein #SS_NOTIFY - Flag
vergeben:

Code: Alles auswählen

TextGadget(12,210, 100, 80, 20, "OK", #SS_NOTIFY)
Grüße ... Kiffi
a²+b²=mc²
Antworten