[Beginners] Mouse Handling in WindowedScreen

Share your advanced PureBasic knowledge/code with the community.
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

[Beginners] Mouse Handling in WindowedScreen

Post by Kaeru Gaman »

Code updated for 5.20+

here is an example how to handle the Mouse in a WindowedScreen,
which keeps movement soft while leaving the screen-area
and also keeps track of GotFocus/LostFocus...

of course it's possible to solve it in sole PB,
but its a bit more complicated to handle the leaving of the screen correctly.

code is meant as kind of a tutorial, so use any part you may need wherever you need it....

Code: Select all

;**************************************** 
;*** WinScreen_Mouse_API.pb
;***
;*** Skeleton for Mouse-Pointer Handling
;*** within a WindowedScreen.
;***
;*** by Kaeru Gaman, Dec.20th,2006
;*** PB Ver 4.02 Win
;*** using WinAPI
;**************************************** 

EnableExplicit

If Not InitSprite()
  MessageRequester("Error","No Sprite, Man!", #MB_ICONERROR)
  End
EndIf
If Not InitSound()
  MessageRequester("Error","No Sound, Man!", #MB_ICONERROR)
  End
EndIf
If Not InitKeyboard()
  MessageRequester("Error","No Keys, Man!", #MB_ICONERROR)
  End
EndIf
If Not OpenWindow(0, 0, 0, 800, 600, "WinScreen_Mouse" , #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget )
  MessageRequester("Error","No Window, Man!", #MB_ICONERROR)
  End
EndIf
If Not OpenWindowedScreen(WindowID(0), 0, 0, 800, 600, 0,0,0 )
  MessageRequester("Error","No Screen, Man!", #MB_ICONERROR)
  End
EndIf

;*************************************
;**** Prepare Main
;*************************************

Define WinEventID.l

Define EXIT.l       = 0     ;Exit-Flag
Define MCur.l       = 0     ;Show/Hide Status MousePointer
Define Focus.l      = 1     ;Focus-Flag of Game-Window

Define MPOS.COORD           ;MousePos
Define MLC.l     = 0        ;Mouse LeftClick
Define MRC.l     = 0        ;Mouse RightClick

Define Col.l     = 0        ;Color for Action
;**************************************************************************
;**** M A I N - L O O P
;**************************************************************************
Repeat
  ExamineKeyboard()
  WinEventID   = WindowEvent()
  
  ;{*** Focus-Test ***
  If Not IsScreenActive()
    ;If GetFocus_()<>WindowID(0) 
    Focus = 0 
  Else 
    Focus = 1 
  EndIf
  ;}
  
  ;*****************************************************
  ;**** Focus-Check and NoFocus Display
  ;*****************************************************
  If Not Focus
    ClearScreen($404040)
    StartDrawing(ScreenOutput())
      DrawingMode(#PB_2DDrawing_Transparent)
      DrawText(100,100,"NoFocus",$C0C0C0)
    StopDrawing()
    Delay(100)
    ;*****************************************************
    ;**** Focus-Only 
    ;*****************************************************
  Else
    ClearScreen($201008)
    
    ;{*** Mouse Status ***
    If WindowMouseX(0)>=0
      MPOS\X = WindowMouseX(0)
      MPOS\Y = WindowMouseY(0)
      MLC = GetAsyncKeyState_(#VK_LBUTTON)
      MRC = GetAsyncKeyState_(#VK_RBUTTON)
      If MCur = 0
        ShowCursor_(0)
        MCur = 1
      EndIf
    ElseIf MCur = 1
      ShowCursor_(1)
      MCur = 0
    EndIf
    ;}
    
    ;{*** Action ***
    If KeyboardPushed(#PB_Key_Space) Or MLC Or MRC
      If MLC
        Col = $2010C0
      ElseIf MRC
        Col = $10C020
      Else
        Col = $808080
      EndIf
      StartDrawing(ScreenOutput())
        FrontColor(Col)
        Circle(MPOS\X,MPOS\Y,32)
      StopDrawing()
    EndIf
    ;}
    
    ;{*** Mouse-Pointer Display ***
    If MCur = 1
      StartDrawing(ScreenOutput())
        FrontColor($20C0C0)
        Line(MPOS\X   ,MPOS\Y   , 24, 16)
        Line(MPOS\X   ,MPOS\Y   , 16, 24)
        Line(MPOS\X+24,MPOS\Y+16,-16, -8)
        Line(MPOS\X+16,MPOS\Y+24, -8,-16)
      StopDrawing()
    EndIf
    ;}
    
    ;{*** Escape - Test ***
    If KeyboardPushed(#PB_Key_Escape)
      EXIT = 1
    EndIf
    If WinEventID = #PB_Event_CloseWindow : EXIT=1 : EndIf
    ;}
    
    ;*****************************************************
    ;**** E N D  of Focus-Only 
    ;*****************************************************
  EndIf
  
  ;**************************************************************************
  ;**** M A I N - L O O P - E N D
  ;**************************************************************************
  FlipBuffers()
  Delay(0)
Until EXIT = 1
;*************************************
End
Last edited by Kaeru Gaman on Thu Dec 21, 2006 7:38 pm, edited 1 time in total.
oh... and have a nice day.
rsts
Addict
Addict
Posts: 2736
Joined: Wed Aug 24, 2005 8:39 am
Location: Southwest OH - USA

Post by rsts »

thanks for the 'lesson'.

Hope you find time for more.

cheers
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post by Kaeru Gaman »

applied a change on first post:
moved the Mouse-Status block into the Focus-Branch.
it's more consistent this way.


and here is also the solution for PB-only.

it's not that much lack in movement when leaving/entering the screen that i expected,
but now the outer 1-pixel-range to the edge of the screen is not acessable for the mouse,
since it's needed for the InScreen/OutScreen switch.

Code: Select all

;**************************************** 
;*** WinScreen_Mouse_noAPI.pb
;***
;*** Skeleton for Mouse-Pointer Handling
;*** within a WindowedScreen.
;***
;*** by Kaeru Gaman, Dec.20th,2006
;*** PB Ver 4.02 Win
;*** without WinAPI, maybe adoptable for Linux
;**************************************** 

#WSrnW = 800
#WSrnH = 600

EnableExplicit

If Not InitSprite()
  MessageRequester("Error","No Sprite, Man!", #MB_ICONERROR)
  End
EndIf
If Not InitSound()
  MessageRequester("Error","No Sound, Man!", #MB_ICONERROR)
  End
EndIf
If Not InitKeyboard()
  MessageRequester("Error","No Keys, Man!", #MB_ICONERROR)
  End
EndIf
If Not InitMouse()
  MessageRequester("Error","No Mouse, Man!", #MB_ICONERROR)
  End
EndIf
If Not OpenWindow(0, 0, 0, #WSrnW, #WSrnH, "WinScreen_Mouse" , #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget )
  MessageRequester("Error","No Window, Man!", #MB_ICONERROR)
  End
EndIf
If Not OpenWindowedScreen(WindowID(0), 0, 0, #WSrnW, #WSrnH, 0,0,0 )
  MessageRequester("Error","No Screen, Man!", #MB_ICONERROR)
  End
EndIf

;*************************************
;**** Prepare Main
;*************************************

Define WinEventID.l

Define EXIT.l       = 0     ;Exit-Flag
Define MCur.l       = 1     ;Show/Hide Status MousePointer
Define Focus.l      = 1     ;Focus-Flag of Game-Window

Define MPOS.COORD           ;MousePos
Define MLC.l     = 0        ;Mouse LeftClick
Define MRC.l     = 0        ;Mouse RightClick

Define Col.l     = 0        ;Color for Action

ReleaseMouse(0)             ;lock Mouse on screen
MouseLocate(1,1)            ;necessary to avoid check-conflicts on start
;**************************************************************************
;**** M A I N - L O O P
;**************************************************************************
Repeat
  ExamineKeyboard()
  WinEventID   = WindowEvent()

;{*** Focus-Test ***
  If Not IsScreenActive()
    Focus = 0 
  Else 
    Focus = 1 
  EndIf
;}

;*****************************************************
;**** Focus-Check and NoFocus Display
;*****************************************************
If Not Focus
  ClearScreen($404040)
  StartDrawing(ScreenOutput())
    DrawingMode(#PB_2DDrawing_Transparent)
    DrawText(100,100,"NoFocus",$C0C0C0)
  StopDrawing()
  Delay(100)
;*****************************************************
;**** Focus-Only 
;*****************************************************
Else
  ClearScreen($201008)

;{*** Mouse Status ***
  If MCur = 1
    ExamineMouse()        ; only check screen-mouse when active
    MPOS\X = MouseX()
    MPOS\Y = MouseY()
    MLC = MouseButton(1)
    MRC = MouseButton(2)
    If MPOS\X = 0 Or MPOS\Y = 0 Or MPOS\X = #WSrnW -1 Or MPOS\Y = #WSrnH -1
      MCur = 0
      ReleaseMouse(1)
    EndIf
  Else
    MPOS\X = WindowMouseX(0)
    MPOS\Y = WindowMouseY(0)
    If MPOS\X > 0 And  MPOS\Y > 0 And MPOS\X < #WSrnW -1 And MPOS\Y < #WSrnH -1
      MCur = 1
      ReleaseMouse(0)
      MouseLocate(MPOS\X,MPOS\Y)  ;necessary, since ReleaseMouse(0) sets screenmouse on 0,0
    EndIf
  EndIf
;}

;{*** Action ***
  If KeyboardPushed(#PB_Key_Space) Or MLC Or MRC
    If MLC
      Col = $2010C0
    ElseIf MRC
      Col = $10C020
    Else
      Col = $808080
    EndIf
    StartDrawing(ScreenOutput())
      FrontColor(Col)
      Circle(MPOS\X,MPOS\Y,32)
    StopDrawing()
  EndIf
;}

;{*** Mouse-Pointer Display ***
  If MCur = 1
    StartDrawing(ScreenOutput())
      FrontColor($20C0C0)
      Line(MPOS\X   ,MPOS\Y   , 24, 16)
      Line(MPOS\X   ,MPOS\Y   , 16, 24)
      Line(MPOS\X+24,MPOS\Y+16,-16, -8)
      Line(MPOS\X+16,MPOS\Y+24, -8,-16)
    StopDrawing()
  EndIf
;}

;{*** Escape - Test ***
  If KeyboardPushed(#PB_Key_Escape)
    EXIT = 1
  EndIf
  If WinEventID = #PB_Event_CloseWindow : EXIT=1 : EndIf
;}

;*****************************************************
;**** E N D  of Focus-Only 
;*****************************************************
EndIf

;**************************************************************************
;**** M A I N - L O O P - E N D
;**************************************************************************
  FlipBuffers()
  Delay(0)
Until EXIT = 1
;*************************************
End
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 »

new problem:

Mouse isn't released when leaving the screen by Alt-Tab.

have solved the leaving, but the backing in doesn't work properly so far.
will fix this later....
oh... and have a nice day.
Post Reply