Screen-Mouse doesn't work when Screen in Container?

Advanced game related topics
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Screen-Mouse doesn't work when Screen in Container?

Post by Kaeru Gaman »

If I put a WindowedScreen into a containergadget, the MouseLib doesn't seem to work properly.

Code: Select all

InitSprite()
InitKeyboard()
InitMouse()

ExamineDesktops()
DWidth  = DesktopWidth(0)
DHeight = DesktopHeight(0)

GSize = DHeight
GPos  = ( DWidth - DHeight ) / 2

OpenWindow( 0, 0,0, DWidth, DHeight, "test", #PB_Window_BorderLess | #PB_Window_ScreenCentered )
;CreateGadgetList( WindowID(0) )
  ContainerGadget( 0, GPos, 0, GSize, GSize )
 
OpenWindowedScreen(GadgetID(0),0,0,1024,1024,1,0,0)

MouseLocate(640,512)

Repeat
  EvID = WaitWindowEvent(10)
  ExamineKeyboard()
  ExamineMouse()

  If EvID = #PB_Event_CloseWindow Or KeyboardPushed(#PB_Key_Escape)
    EXIT = 1
  EndIf

  ClearScreen($100804)
  StartDrawing(ScreenOutput())
    DrawingMode( #PB_2DDrawing_Transparent )
    Circle(MouseX(), MouseY(), 16, $C040FF)
  StopDrawing()
  FlipBuffers()

Until EXIT
without the container, it works flawless.

Code: Select all

InitSprite()
InitKeyboard()
InitMouse()

ExamineDesktops()
DWidth  = DesktopWidth(0)
DHeight = DesktopHeight(0)


OpenWindow( 0, 0,0, DWidth, DHeight, "test", #PB_Window_BorderLess | #PB_Window_ScreenCentered )
 
OpenWindowedScreen(WindowID(0),0,0,1024,1024,1,0,0)

MouseLocate(640,512)

Repeat
  EvID = WaitWindowEvent(10)
  ExamineKeyboard()
  ExamineMouse()

  If EvID = #PB_Event_CloseWindow Or KeyboardPushed(#PB_Key_Escape)
    EXIT = 1
  EndIf

  ClearScreen($100804)
  StartDrawing(ScreenOutput())
    DrawingMode( #PB_2DDrawing_Transparent )
    Circle(MouseX(), MouseY(), 16, $C040FF)
  StopDrawing()
  FlipBuffers()

Until EXIT
is there a way to make the screenmouse work?

... else I have to go the Event-Way, I think...
or leave the container...
oh... and have a nice day.
pg
User
User
Posts: 75
Joined: Wed Jun 18, 2003 3:31 pm
Location: Swiss
Contact:

Post by pg »

Just a little modification:

Code: Select all

InitSprite() 
InitKeyboard() 
InitMouse() 

ExamineDesktops() 
DWidth  = DesktopWidth(0) 
DHeight = DesktopHeight(0) 

Global hwnd

GSize = DHeight 
GPos  = ( DWidth - DHeight ) / 2 

hwnd=OpenWindow( 0, 0,0, DWidth, DHeight, "test", #PB_Window_BorderLess | #PB_Window_ScreenCentered ) 
;CreateGadgetList( WindowID(0) ) 
  ContainerGadget( 0, GPos, 0, GSize, GSize ) 
  
hwnd=OpenWindowedScreen(GadgetID(0),0,0,1024,1024,1,0,0) 

MouseLocate(640,512) 

fx.f=GSize/1024
fy.f=DHeight/1024

Repeat 


  p.POINT  
  GetCursorPos_ (@p.POINT) 
  ScreenToClient_(GadgetID(0),@p)   
  p\x=(p\x/fx)
  p\y=p\y/fy
   
  
  
  EvID = WaitWindowEvent(10) 
  ExamineKeyboard() 
  ExamineMouse() 

  If EvID = #PB_Event_CloseWindow Or KeyboardPushed(#PB_Key_Escape) 
    EXIT = 1 
  EndIf 

  
  
  ClearScreen($100804) 
  StartDrawing(ScreenOutput())
    DrawingMode( #PB_2DDrawing_Transparent ) 
    Circle(p\x,p\y, 16, $C040FF) 
  StopDrawing() 
  FlipBuffers() 

Until EXIT
Maybe it's not working with MouseX() and MouseY() because the Mouse is over another active Window (Gadget))
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post by Kaeru Gaman »

I see what you did there...

I would just leave the API away, use WindowMouseX/Y and calculate the coords quite similar to your way.
got to see how to handle mouseclicks then...


my primary problem is that I
1. like to use the Screen-MouseLib
2. want a squared Windowedscreen in the middle of the window and keep the window resizable.
oh... and have a nice day.
xaby
User
User
Posts: 16
Joined: Tue May 15, 2007 12:41 pm
Location: Germany - Berlin

Post by xaby »

Kaeru wrote:1. like to use the Screen-MouseLib
Is that, what you realy mean?

Or do you want some special functions in your program and the
only way you know is to do it with the Screen-Mouse :?

I hate the difference between Screen-Mouse and No-Screen-Mouse
also. That's why I coded a "One-Only-Mouse"

It's easier to use for children :P

http://www.folker-linstedt.de/pureforum/FLDGS_X.zip

Mybe it is, what you are looking for. FLDGS.pbi
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post by Kaeru Gaman »

xaby wrote:Is that, what you realy mean?

Or do you want some special functions in your program and the
only way you know is to do it with the Screen-Mouse
if you have a look at this, Folker, you will see I know how to handle Mouse via API only...
http://www.purebasic.fr/english/viewtopic.php?t=25082

your include is an incredibly big overhead for what I plan.
if I had a detailed documentation, I maybe see what your include is all able to do...

but I don't like the Frame-Problem your Demo reveals...
I think my snippet does even better concerning this.
oh... and have a nice day.
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post by Kaeru Gaman »

PS

in fact, I hoped for an explanation from those who know,
WHY the screenmouse doesn't work and how to make it work.
oh... and have a nice day.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

I believe the problem lies in the messaging used as the windowed screen is assumed to be opened on a toplevel window, whereas the container is a static control. (but that's a guess) Here's a small include that preserves all original function names, so using it requires no extra effort:

Code: Select all

Structure MOUSESTATE
  mouseloc.POINT
  mbutton.i[4]
EndStructure

Procedure MouseInit()
  ProcedureReturn 1
EndProcedure

Procedure MouseExamine()
  Shared _mstate.MOUSESTATE
  Static screenw=0, screenh=0
  If Not screenw
    GetClientRect_(ScreenID(),@cr.RECT)
    screenw = cr\right-cr\left
    screenh = cr\bottom-cr\top
  EndIf
  RtlZeroMemory_(@_mstate, SizeOf(MOUSESTATE))
  GetCursorPos_(@_mstate\mouseloc)
  If WindowFromPoint_(_mstate\mouseloc\x | (_mstate\mouseloc\y<<32))=ScreenID() 
    SetCursor_(0)
  EndIf
  MapWindowPoints_(0,ScreenID(),@_mstate\mouseloc,1)
  If _mstate\mouseloc\x < 0 : _mstate\mouseloc\x = 0 : EndIf
  If _mstate\mouseloc\y < 0 : _mstate\mouseloc\y = 0 : EndIf
  If _mstate\mouseloc\x >= screenw : _mstate\mouseloc\x = screenw-1 : EndIf
  If _mstate\mouseloc\y >= screenh : _mstate\mouseloc\y = screenh-1 : EndIf
  With _mstate
    \mbutton[1]= GetAsyncKeyState_(#VK_LBUTTON) & 32768
    \mbutton[3]= GetAsyncKeyState_(#VK_MBUTTON) & 32768
    \mbutton[2]= GetAsyncKeyState_(#VK_RBUTTON) & 32768
  EndWith
EndProcedure

Procedure GetMouseX()
  Shared _mstate.MOUSESTATE
  ProcedureReturn _mstate\mouseloc\x
EndProcedure

Procedure GetMouseY()
  Shared _mstate.MOUSESTATE
  ProcedureReturn _mstate\mouseloc\y
EndProcedure

Procedure GetMouseKey(button)
  Shared _mstate.MOUSESTATE
  ProcedureReturn _mstate\mbutton[button]
EndProcedure

Macro InitMouse() : MouseInit() : EndMacro
Macro ExamineMouse() : MouseExamine() : EndMacro
Macro MouseX() : GetMouseX() : EndMacro
Macro MouseY() : GetMouseY() : EndMacro
Macro MouseButton(button) : GetMouseKey(button) : EndMacro
Small test: (note that the code is the same as if you weren't using the include)

Code: Select all

OpenWindow(0,0,0,640,240,"",#PB_Window_ScreenCentered)
InitSprite():InitMouse():InitKeyboard()
ContainerGadget(0,0,0,320,240)
OpenWindowedScreen(GadgetID(0),0,0,320,240,0,0,0)

Repeat
  While WindowEvent():Wend
  ClearScreen(0)
  ExamineMouse()
  StartDrawing(ScreenOutput())
    DrawText(100,100,Str(MouseX())+", "+Str(MouseY()), #White, #Black)
    If MouseButton(#PB_MouseButton_Left)
      DrawText(100,120,"Left")
    EndIf
    If MouseButton(#PB_MouseButton_Middle)
      DrawText(130,120,"Middle")
    EndIf
    If MouseButton(#PB_MouseButton_Right)
      DrawText(180,120,"Right")
    EndIf
  StopDrawing()
  FlipBuffers()
  ExamineKeyboard()
Until KeyboardPushed(#PB_Key_All)
I didn't do MouseDelta, mainly because I've never used it myself, but it would be simple enough to add.
BERESHEIT
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post by Kaeru Gaman »

thanx, netmaestro!

gives me a better insight in the API functions for the cursor than I had before.

- you have a SetCursor_(0) in there, but not the opposite?
(darn have no win32.hlp at hand...)

- I assume, (_mstate\mouseloc\x | (_mstate\mouseloc\y<<32)) is the synthesis of a POINT struct?
... couldn_t we pass _mstate\mouseloc directly?


btw.. it does not exactly work like the DX mouse,
if the cursor is outside the screen, the coordinates are still updated.
but I think this is even better.

... I see that the coords are limited manually by 4 ifs...
this enables us to limit them a bit further outside, so we could disply a crosswire that vanishes slowly beyond the border....

all in all, really nice snippet and very inspiring.
thnx again :D
oh... and have a nice day.
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Re: Screen-Mouse doesn't work when Screen in Container?

Post by Kaeru Gaman »

hu... it's over a year ago... time runs fast.

@netmaestro

I got a confirmation question left...

what about the SetCursor_(0) in there...?
I wonder why it is to be called every iteration to hide the cursor, but never to show it.
normally I would assume I hide the cursor when it enters the screen and show it again when it leaves the screen.

would you mind explaning this more detailed?
thanx a lot so far!
oh... and have a nice day.
User avatar
Olliv
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Sep 22, 2009 10:41 pm

Re: Screen-Mouse doesn't work when Screen in Container?

Post by Olliv »

@Kaeru

Each area of the screen (desktop screen) is assigned with a cursor pattern through the window class.

So, you can remove it...

Code: Select all

  If WindowFromPoint_(_mstate\mouseloc\x | (_mstate\mouseloc\y<<32))=ScreenID() 
    SetCursor_(0)
  EndIf
...add it just before the main loop...

Code: Select all

Define.I Zob
Global hCursor.I = CreateCursor_(Zob, 0, 0, 1, 1, @Zob, @Zob)
SetClassLong_(ScreenID(), #GCL_HCURSOR, hCursor)
...and add it after the main loop

Code: Select all

DestroyCursor_(hCursor)
Also you preserve the cursor in the window and out of the graphic screen, and you don't check what the OS already checks (if mouse cursor is in or out of the graphic screen)...
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Re: Screen-Mouse doesn't work when Screen in Container?

Post by Kaeru Gaman »

Each area of the screen (desktop screen) is assigned with a cursor pattern through the window class.
hm.. ok that makes it a bit clearer.
that could explain why I can deactivate it for the screencontainer and leave the outside untouched.

but why do I have to deactivate it each iteration?

sorry, cursor manipulation via API is just brandnew for me.
my goal is to fully understand what netmeastro showed there.

I'm away from wanting to use the dx mouselib, I will solve it via WindowMouseX/Y and API.

in the end, it would be sufficent to just hide the cursor when it is over any element of my window, container or not.
I don't need the rest of the window area for controls, it's just to provide a blind frame to cover the rest of the desktop when it has a different aspect ratio.
oh... and have a nice day.
Post Reply