Using the Mouse in FreeBASIC

After doing some searches, I quickly noticed that there simply wasn't an 
official tutorial or technique for manipulating the mouse in a windows 
console application in FreeBASIC. Therefore, I decided to write this 
technique in order to give such an example to the FreeBASIC Community. As 
you know A Windows Console is already mouse aware by ways of the fact that 
it is a windows console, which means it's created with the use of the 
Windows API, which means that the mouse can be accessed from the Console 
Window. So There's no need to turn the mouse on or off in your code. All 
you need to do is Get or Set the X and Y coordinates and get the states of 
the mouse buttons. We will be covering the following subjects in this 
tutorial.

   *Getting Mouse Coordinates:
     The mouse cursor, when the mouse is moved, continuously updates its 
   position. You can get these values to determine where the pointer 
   currently is on the screen.

   *Setting Mouse Coordinates:
     For some reason there may be a need to position the mouse pointer at a 
   different location than where the pointer currently is.

   *Getting The Mouse Button Statuses:
     Quite simply, when the user presses a button on the mouse, it returns 
   a value that says that a button is pressed, and which buttons are 
   pressed, too. From these values you can decide what part of your code 
   gets executed.

As with most tutorials, this one too can be better explained with the use 
of an example program. We will be creating a very simple program that acts 
upon the user's interaction with the mouse and certain areas of the screen. 
It should provide the bases of code needed to efficiently operate and 
control the mouse in your own programming projects.

Editors Note:
   - The mouse functions will work with a graphics window as demonstrated 
   in this tutorial.
   - They will work with console window however in Windows, Quick Edit mode 
   must be turned off (this conflict between Quick Edit and FreeBASIC mouse 
   is fixed from fbc version 1.08).

THE SAMPLE PROGRAM DESCRIPTION

For the sake of a demonstration program, things will be quite simple and as 
straightforward as it possibly can. The program will show 3 items at the 
top of the screen and depending on which one you click a different message 
will be displayed on the screen. This should give you enough information to 
know how to work with the mouse in FreeBASIC.

In FreeBASIC, there's basically 2 commands that you need to worry about 
when trying to handle the mouse in your projects. Here they are with their 
syntax explained as per the documentation.

----------------------------------------------------------------------------
----

Syntax
result = GetMouse (x, y [, [ wheel ] [, [ buttons ] [, [ clip ]]]])

Description
GETMOUSE retrieves the mouse position and button status. 

Mouse position is stored in X and Y when the function is called. If the 
mouse is not in the program window, X and Y will be -1.

'wheel' is the mouse wheel counter. Rotating the wheel away from you makes 
the count to increase, rotating towards you makes it to decrease. If mouse 
is not present or out of the program window, wheel will hold -1.

'buttons' stores the button status. On function termination, this will 
return a bitmask holding buttons status. Bit 0 is set if left mouse button 
is down; bit 1 is set if right mouse button is down; bit 2 is set if middle 
mouse button is down.

'clip' stores the mouse clipping status; if 1, the mouse is currently 
clipped to the graphics window; if 0, the mouse is not clipped.

*GETMOUSE is for use in graphics modes, set using the SCREEEN command 
ONLY.*

----------------------------------------------------------------------------
-----

Syntax
result = SetMouse([ x ] [, [ y ] [, [ visibility ] [, [ clip ]]]])

Description
SETMOUSE will set the X,Y coordinates of the mouse pointer, as well as 
setting it's visibility. 

Mouse position is set using the X and Y parameters. 

The mouse will be visible if visibility is set to 1, and invisible if 
visibility is set to 0.

clip - 1 indicates mouse is clipped to graphics window, 0 indicates no 
clipping

*SETMOUSE is intended for graphics modes initiated using the SCREEN 
statement only.*

----------------------------------------------------------------------------
---- 

THE CODING BEGINS

Here are a set of constants that I declare at the beginning of the module. 
This is simply to gain a bit of clarity of code in the rest of the 
programming example.
      Const LEFTBUTTON = 1 
      Const MIDDLEBUTTON = 4 
      Const RIGHTBUTTON = 2 
      Const SHOWMOUSE = 1
      Const HIDEMOUSE = 0 

As a first step in this example, we will be declaring variables that we 
will be using throughout the example program. Of course you don't have to 
declare your variables, but me I like to do so because when you do so you 
know exactly why you're declaring your variables. To me that's good 
practice. Editors Note: In #lang FB you must declare variables before using 
them. 
      Dim CurrentX As Integer 
      Dim CurrentY As Integer
      Dim MouseButtons As Integer
      Dim CanExit As Integer
      Dim As String A,B,C

The idea here is to do everything within a loop so that we can also control 
how the program exits. So we'll create a loop that will exit when the "CanEx
it" variable is equal to 0. In the loop we'll interrogate the mouse and 
print some basic values. (This part is extracted from the example provided 
in the GETMOUSE syntax explanation in the gfxlib.txt file). Don't forget to 
set your graphics mode as it is a must to get valid return values from the 
mouse commands. We'll use Screen 12 for our example.
   Screen 12 
   CanExit = 1
    
   Do While CanExit <> 0 
      GetMouse CurrentX, CurrentY, , MouseButtons 
      If CurrentX < 0 Then
       Print "Mouse is out of context." 
      Else
      If MouseButtons And LEFTBUTTON Then A="L"
      If MouseButtons And MIDDLEBUTTON Then B="M"
      If MouseButtons And RIGHTBUTTON Then C="R"
       Print Using "Mouse position: ###:### Buttons: &&&"; CurrentX; CurrentY;A;B;C 
       A="":B="":C=""    
      End If 
   Loop

This sample will basically continuously display information about Where the 
mouse is, if it's on the program window and which mouse button is pressed 
if any. The GETMOUSE statement basically puts the current X and Y 
coordinates in our CurrentX and CurrentY variables and the status of the 
mouse buttons in our MouseButtons variable. The Three If Statements will 
print L if the left button was pressed, M if the middle button (or the 
wheel) was pressed and R if the Right button was pressed.

For the next step, since we want to control a bit what's happening with the 
mouse, will display a few extra things at the beginning of the program and 
control what happens with them afterwards, in the loop. This is regular 
text being displayed, this could be replaced by a series of line commands 
or something to draw a button for the different options. But that is 
outside the scope of this tutorial. So far, by getting rid of the unwanted 
print statements from the code above, the loop should now look like this:
      Screen 12 
      SetMouse 1, 1, 1
      CanExit = 1
      Locate 1,1
      Print " | FIRST | SECOND | THIRD | EXIT | "
      Do While CanExit <> 0
       Locate 1,1
       GetMouse CurrentX, CurrentY, , MouseButtons
      Loop 

Basically we print the line that has " | FIRST | SECOND | THIRD | EXIT | " 
at the top of the screen. And we go into the loop that interrogates the 
mouse. Of course, right now nothing will happen if you press a button 
because there is no code for it. In our example, we'll add code that simple 
prints which option was selected. If the user selects the EXIT option, 
we'll print the Option and we'll exit the loop. We'll also add a print 
statement outside the loop with a sleep to tell the use that we are truly 
outside the loop and therefore the program is ended. With all this, the 
code should now look like this. I am putting the whole source file here so 
you can cut and paste it easily.
   Const LEFTBUTTON   = 1
   Const MIDDLEBUTTON = 4   ' UNUSED IN THIS DEMO
   Const RIGHTBUTTON  = 2   ' UNUSED IN THIS DEMO
   Const SHOWMOUSE    = 1
   Const HIDEMOUSE    = 0

   Dim CurrentX     As Integer
   Dim CurrentY     As Integer
   Dim MouseButtons As Integer
   Dim CanExit      As Integer

   Screen 12
   SetMouse 1, 1, SHOWMOUSE
   CanExit = 1
   Locate 1,1
   Print " | FIRST | SECOND | THIRD | EXIT | "

   Do
      GetMouse CurrentX, CurrentY, , MouseButtons
      If MouseButtons And LEFTBUTTON Then
        If CurrentY <= 12 Then
          If CurrentX >= 0 And CurrentX <=75 Then
            Locate 12, 1
            Print "First Option Selected ";
          ElseIf CurrentX >= 76 And CurrentX <= 147 Then
            Locate 12, 1
            Print "Second Option Selected";
          ElseIf CurrentX >= 148 And CurrentX <=212 Then
            Locate 12, 1
            Print "Third Option Selected ";
          ElseIf CurrentX >= 213 And CurrentX <=268 Then
            Locate 12, 1
            Print "Last Option Selected  ";
            Exit Do
          End If
        End If
      End If
   Loop While Inkey$ = ""

   SetMouse 1, 1, HIDEMOUSE
   Print
   Print "AND NOW WE'RE OUT OF THE LOOP"
   Sleep

You can see the many IF statements in this last piece of code. The numbers 
that are there have been measured as per SCREEN 12 returned coordinates. 
They should work in all graphics mode however because a pixel is a pixel in 
a Console Graphics Window. Each if represents where the different options 
are written on the screen. If you would have used a graphics button routine 
you could simply use the same width and height as you did to draw the 
button in these if statements to know which button was clicked.

IN CONCLUSION

As you can see, using the mouse has been made very simple in FreeBASIC. You 
can use simple statement like the print command to draw your screens or you 
can use graphics command like LINE to draw your screens graphically. No 
matter which way you choose to draw your screens with, the SETMOUSE and 
GETMOUSE statement will work the same way and return the very same values. 
All you have to do is get that information and make your programs do what 
you want them to do if they press a button, select an option, or even in 
the case of a game, you could easily make the main character move towards 
the location where you clicked on the screen as well. The choice is up to 
you.

As always, if you have any questions regarding this tutorial or any other 
I've written, feel free to email me and we'll see what we can do about 
solving your particular problem.

MystikShadows
Stéphane Richard
srichard@adaworld.com 

Last Reviewed by Sancho3 on February 06, 2018