Page 1 of 1

Posted: Sun Jan 11, 2009 12:41 am
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.

Posted: Sun Jan 11, 2009 10:20 am
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

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

Posted: Wed Feb 17, 2010 11:54 pm
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!

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

Posted: Thu Feb 18, 2010 2:57 am
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)...

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

Posted: Thu Feb 18, 2010 9:01 am
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.