{{fbdoc item="title" value="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.//

==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.

--------------------------------------------------------------------------------
{{fbdoc item="title" value="GETMOUSE"}}
----
{{fbdoc item="syntax"}}
result = ""GetMouse"" (x, y [, [ wheel ] [, [ buttons ] [, [ clip ]]]])

{{fbdoc item="desc"}}
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.*


---------------------------------------------------------------------------------
{{fbdoc item="title" value="SETMOUSE"}}
----
{{fbdoc item="syntax"}}
result = ""SetMouse""([ x ] [, [ y ] [, [ visibility ] [, [ clip ]]]])

{{fbdoc item="desc"}}
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.
%%(freebasic)
	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. 
%%(freebasic)
	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 "Can********Exit" 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.
%%(freebasic)
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 Current********X and Current********Y variables and the status of the mouse buttons in our Mouse********Buttons 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:
%%(freebasic)
	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.
%%(freebasic)
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//