After doing some searches, I quickly noticed that there simply wasn't an official tutorial or technique for manipulating the mouse 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 it's 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.
IMPORTANT: It is mandatory that you set yourself in a graphic mode in order to use the mouse. the mouse commands will always return -1 for a value if the graphic mode is not set.
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: GETMOUSE x,y(,wheel,(buttons))
- Argument: Description:
- Mouse position in screen coordinates is stored in these variables on function termination. If mouse is not present or out of the program window, x and y will hold -1.
- 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.
- 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.
Insights: Use this function to get mouse info while in gfx mode. Pay attention: GETMOUSE does NOT work if a gfx mode is not set. Pass x, y, wheel and buttons variables by reference, so this function will store result values in them. If mouse is not present or out of the program window, all returned values will be -1.
- Syntax: SETMOUSE (x)(,(y)(,cursor))
- Argument: Description:
- x,y Screen coordinates of the new mouse cursor position.
- cursor Pass 0 to hide the cursor, or 1 to show it.
Insights: This statement is useful to set the current system mouse cursor position, and to hide or show it. The cursor is shown by default when you call SCREEN.
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 = 2 CONST RIGHTBUTTON = 4 CONST SHOWMOUSE = 0 CONST HIDEMOUSE = 1
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.
DIM CurrentX AS INTEGER DIM CurrentY AS INTEGER DIM MouseButtons AS INTEGER DIM CanExitAS INTEGER
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 "CanExit" 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 PRINT USING "Mouse position: ###:### Buttons: "; CurrentX; CurrentY; IF MouseButtons AND LEFTBUTTON THEN PRINT "L"; IF MouseButtons AND MIDDLEBUTTON THEN PRINT "R"; IF MouseButtons AND RIGHTBUTTON THEN PRINT "M"; 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 truely 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 = 2 ' UNUSED IN THIS DEMO CONST RIGHTBUTTON = 4 ' UNUSED IN THIS DEMO CONST SHOWMOUSE = 0 CONST HIDEMOUSE = 1 DIM CurrentX AS INTEGER DIM CurrentY AS INTEGER DIM MouseButtons 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.
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.