Seite 1 von 1

WindowMouseX - ein Pixel zu viel

Verfasst: 22.11.2007 02:03
von Sebastian
Folgendes Problem macht mir gerade sehr zu schaffen:
Ich habe mal das Beispiel aus der Hilfe gewählt - hier wird ein Fenster mit der inneren Breite von 300px definiert. Wenn man nun an die äußerste Koordinate des Fensters fährt (nicht darüber hinweg), dann erhält man den Wert 0. Ist ja auch klar, PureBasic rechnet ja die 0 als eine Stelle. Wenn man aber an den äußersten Rand rechts fährt, so erhält man einen Wert von 300!!! Demnach müsste der Fensterinhalt 301 Pixel breit sein. Ist er aber nicht. Warum wird die 300 noch ausgegeben? Warum ist nicht bei 299 Schluss? Das bereitet mir in einem Programm echte Schwierigkeiten. Ist doch ein Bug von PureBasic oder?
Also nach meinem Verständnis müsste die Ausgabe von 1-300 XOr 0-299 gehen.

Code: Alles auswählen

If OpenWindow(0, 0, 0, 300, 30, "Fenster Maus-Monitor", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    CreateGadgetList(WindowID(0))
      TextGadget(0, 10, 6, 200, 20, "")
    
    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)))
    Until Event = #PB_Event_CloseWindow
  EndIf

Verfasst: 22.11.2007 02:16
von #NULL
du kannst (zumindest mit pb-2ddrawing / windowoutput() ) aber nicht auf die kante unten und rechts zeichnen.
siehe hier:

Code: Alles auswählen

If OpenWindow(0, 0, 0, 300, 30, "Fenster Maus-Monitor", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    CreateGadgetList(WindowID(0))
      TextGadget(0, 10, 6, 200, 20, "")
   
    Repeat
      Event = WaitWindowEvent(20) ; kehre mindestens alle 20 ms für ein Update zurück
      wmx=WindowMouseX(0)
      wmy=WindowMouseY(0)
      SetGadgetText(0, "Fenster Maus-Position: " + Str(wmx) + "," + Str(wmy))
      StartDrawing(WindowOutput(0))
        Box(wmx,wmy,1,1,255)
      StopDrawing()
    Until Event = #PB_Event_CloseWindow
  EndIf 
wo ist denn für dich das problem bei der ganzen sache?

Verfasst: 22.11.2007 02:19
von Sebastian
Das kann gut sein, jedoch ist die Ausgabe von WindowMouseX/Y dennoch unlogisch, oder? Ich verwende die Mauskoordinaten in einem Algorithmus. Sobald ich versehentlich die rechte Kante erreiche, stimmt die Rechnung nicht mehr und mein Programm hängt sich auf. Sicher, ich kann das abfangen, dennoch ist das doch ein Bug oder?

Verfasst: 22.11.2007 08:23
von DrShrek
Ich habe es mal als BUG gemeldet.

Verfasst: 22.11.2007 11:46
von Ligatur
Hallo,
Ich habe mal ein 300x300 großes Fenster mit Hilfe der API geöffnet und auch die Mauskoordinaten mit Funktionen der API abgefragt. Sowohl die von #WM_MOUSEMOVE gelieferten Werte als auch die über GetCursorPos_() und mit ScreenToClient_() umgerechneten Werte weisen dieses Problem nicht auf, die zurückgegebenen Werte liegen im Breicch von 0 - 299 wie zu Erwarten. Aber dafür kann man seltsamerweise im Fenster ein Rechteck von 0,0 - 300, 300 zeichnen :? .
Grüße,
Ligatur

Code: Alles auswählen

EnableExplicit

Declare WndProc(hwnd.l, msg.l, wParam.l, lParam.l)

Define.l hwnd, rc.RECT
Define.s szAppName
Define msg.MSG

szAppName.s = "Fenster"
Define wndclass.WNDCLASS

wndclass\style = #CS_HREDRAW | #CS_VREDRAW
wndclass\lpfnWndProc = @WndProc()
wndclass\cbClsExtra = 0
wndclass\cbWndExtra = 0
wndclass\hInstance = 0
wndclass\hIcon = LoadIcon_(0, #IDI_APPLICATION)
wndclass\hCursor = LoadCursor_(0, #IDC_ARROW)
wndclass\hbrBackground = GetStockObject_(#WHITE_BRUSH)
wndclass\lpszMenuName = 0
wndclass\lpszClassName = @szAppName

If Not RegisterClass_(@wndclass)
	MessageRequester("Fehler", "Fensterklasse nicht registriert")
	End
EndIf

rc\left = 30
rc\top = 50
rc\right = 330
rc\bottom = 350
AdjustWindowRectEx_(@rc, #WS_CAPTION | #WS_SYSMENU, 0, #WS_EX_ACCEPTFILES)
hwnd = CreateWindowEx_(#WS_EX_ACCEPTFILES, szAppName, "Fenstername", #WS_CAPTION | #WS_SYSMENU, rc\left, rc\top, rc\right - rc\left, rc\bottom - rc\top, 0, 0, 0, 0)

If hwnd = 0
	MessageRequester("Fehler", "Fenster konnte nicht geöffnet werden")
	End
EndIf	

ShowWindow_(hwnd, #SW_SHOWNORMAL)
UpdateWindow_(hwnd)

While GetMessage_(msg, 0, 0, 0)
	TranslateMessage_(msg)
	DispatchMessage_(msg)
Wend
End

Procedure.l WndProc(hwnd.l, msg.l, wParam, lParam)
	Protected hdc, ps.PAINTSTRUCT, RPn, APn, OutTxt.s, tm.TEXTMETRIC, ay, rc.RECT
	Static mx, my, mp.POINT
	
	Select msg
		Case #WM_MOUSEMOVE
			GetCursorPos_(@mp)
			ScreenToClient_(hwnd, @mp)
			mx = lParam & $FFFF
			my = lParam >> 16
			InvalidateRect_(hwnd, 0, #True)
			ProcedureReturn 0
			
		Case #WM_PAINT
			If GetUpdateRect_(hwnd, #NULL, #False)
				hdc = BeginPaint_(hwnd, @ps)
				RPn = CreatePen_(#PS_SOLID, 1, RGB(255, 0, 0))
				APn = SelectObject_(hdc, RPn)
				Rectangle_(hdc, 0, 0, 300, 300)
				GetTextMetrics_(hdc, @tm)
				ay = tm\tmHeight + tm\tmExternalLeading + tm\tmInternalLeading
				OutTxt.s = "X: " + Str(mx)
				TextOut_(hdc, 5, 5, @OutTxt, Len(OutTxt))
				OutTxt.s = "Y: " + Str(my)
				TextOut_(hdc, 5, 5 + ay, @OutTxt, Len(OutTxt))
				OutTxt.s = "MX: " + Str(mp\x)
				TextOut_(hdc, 5, 5 + 2 * ay, @OutTxt, Len(OutTxt))
				OutTxt.s = "MY: " + Str(mp\y)
				TextOut_(hdc, 5, 5 + 3 * ay, @OutTxt, Len(OutTxt))
				DeleteObject_(SelectObject_(hdc, APn))
				EndPaint_(hwnd, @ps)
			EndIf
			ProcedureReturn 0
			
		Case #WM_DESTROY
			PostQuitMessage_(0)
			ProcedureReturn 0
	EndSelect
	
	ProcedureReturn DefWindowProc_(hwnd, msg, wParam, lParam)
EndProcedure


Verfasst: 22.11.2007 13:49
von Sebastian
Du hast Recht! Mich verwirrt das auch gerade ein Wenig. Also muss es sich wohl tatsächlich um einen waschechten Bug handeln.

Verfasst: 22.11.2007 17:16
von NicTheQuick
'Rectangle_(hdc, 0, 0, 300, 300)' zeigt tatsächlich nur ein Rechteck von (0, 0)
bis (299, 299) an, sonst würde die Maus nicht auf der linken Linie (0, 0)
anzeigen und auf der rechten (299, 299). Wenn ihr mal 'Rectangle_(hdc, 0, 0, 20, 20)'
macht, dann könnt ihr die Pixel ja mal von Hand zählen.

Verfasst: 22.11.2007 17:40
von Ligatur
NicTheQuick hat geschrieben:'Rectangle_(hdc, 0, 0, 300, 300)' zeigt tatsächlich nur ein Rechteck von (0, 0)
bis (299, 299) an, sonst würde die Maus nicht auf der linken Linie (0, 0)
anzeigen und auf der rechten (299, 299). Wenn ihr mal 'Rectangle_(hdc, 0, 0, 20, 20)'
macht, dann könnt ihr die Pixel ja mal von Hand zählen.
Das mag sein, aber seltsam ist das trotzdem da Rectangle_() keine Breite und Höhe erwartet sondern Koordinaten für die linke obere und Koordinaten für die rechte untere Ecke wie im MSDN nachzulesen oder auch auszuprobieren mit Rectangle_(hdc, 50, 50, 300, 300), die rechte und untere Linie bleiben dann an der gleichen Position.
Die rechte und untere Linie wird also ein Pixel zu weit links bzw. oben angezeigt.

Verfasst: 24.11.2007 16:51
von Sebastian
Alles klar. Da scheint es mehr Probleme zu geben, als ich annahm. Wie ist jetzt vorzugehen? Reicht dieses Posting oder sollte ich nochmal direkt an die PureBasic-Entwickler eine E-Mail schreiben? Steht jemand mit denen im ständigen Kontakt, so dass ich mir das sparen kann?

Verfasst: 24.11.2007 17:31
von Kiffi
Sebastian hat geschrieben:Wie ist jetzt vorzugehen?
Dr. Shrek hat es ja bereits im englischen Forum als Bug gepostet:

http://www.purebasic.fr/english/viewtop ... 838#219838

Du könntest dort bestätigen, dass es auch bei Dir auftritt. Vielleicht melden
sich dann auch noch andere. Dann abwarten und Tee trinken.

Grüße ... Kiffi