The
library originates from
Konstantin Knizhnik's winbgi shareware.
I spent some time adding
a new initwindow
function (to allow the graphics window to be
initially opened at any size) and three new functions to allow simple
mouse-driven processing. Mark Richardson then added some new functions
to allow more than sixteen colors.
You are welcome to use and modify this library as you like. Let me know if you make interesting modifications.
graphics.h
.
-lbgi -lgdi32 -lcomdlg32
-luuid -loleaut32 -lole32
(in
that order) after any other file arguments to the compiler. For
example, to compile the bgidemo0.cpp
program you would give the compile command:
g++ bgidemo0.cpp -lbgi -lgdi32 -lcomdlg32 -luuid -loleaut32 -lole32 -o bgidemo0.exeNote that each of these library options begins with the letter l (not the number one).
If you are working with the CS1300 version of the g++ compiler (from www.cs.colorado.edu/~main/cs1300/README.html), then you can get all these libraries automatically by using the bgi++ command instead of g++. For example:
bgi++ bgidemo0.cpp -o bgidemo0.exeThis command creates an executable file called bgidemo0.exe. Note that when it runs, it creates a small graphics window where all the bgi operations are performed. Any text i/o with cin and cout will be done in the other (console) window.
Initialization: Normally, you initialize the BGI graphics by a call to
detectgraph
and a call to initgraph
.
You can still use those two function calls, or you may call a
new function named initwindow
. The function
has two arguments that are the size of the graphics window that you
want to create in pixels (width and height). For example, you can
create a window that is 450 pixels wide and 300 pixels high with
the statement:
initwindow(450, 450);
RGB Colors: The winbgim package supports two types of colors that may be used with any of the functions that expect colors as arguments:
BLACK BLUE GREEN CYAN RED MAGENTA BROWN LIGHTGRAY DARKGRAY LIGHTBLUE LIGHTGREEN LIGHTCYAN LIGHTRED LIGHTMAGENTA YELLOW WHITE
Three other macros (RED_VALUE, GREEN_VALUE, BLUE_VALUE, IS_BGI_COLOR and IS_RGB_COLOR) are explained in the examples below.
RGB Examples:
setcolor(BLUE); // Change drawing color to BLUE. setcolor(COLOR(255,100,0); // Change drawing color to reddish-green. setpalette(4, BLUE); // Change palette entry 4 to BLUE. setpalette(4, COLOR(9,9,9));// Change palette entry 4 to nearly black. int current = getcolor( ); // Set current to current drawing color. if (IS_BGI_COLOR(current)) // Check whether it is a BGI color. cout << "Current BGI drawing color is: " << current << end; if (IS_RGB_COLOR(current)) // Check whether it is an RGB color. cout << "Current RGB drawing color has these components:\n" << "Red: " << RED_VALUE(current) << '\n' << "Green: " << GREEN_VALUE(current) << '\n' << "Blue: " << BLUE_VALUE(current) << '\n'
int getdisplaycolor(int color)
int mousex( )
int mousey( )
bool ismouseclick(kind)
This function returns true if there is an unprocessed mouse event of
the specified kind.
The argument to ismouseclick
is
one of these constants from the winbgim.h
file:
WM_MOUSEMOVE
WM_LBUTTONDBLCLK
WM_LBUTTONDOWN
WM_LBUTTONUP
WM_MBUTTONDBLCLK
WM_MBUTTONDOWN
WM_MBUTTONUP
WM_RBUTTONDBLCLK
WM_RBUTTONDOWN
WM_RBUTTONUP
The middle mouse button handlers aren't working on my machine. I haven't yet tracked down the reason--it could be a broken mouse or it could be a bug in my programming.
getmouseclick
(which gets the coordinates of the event), or by calling
clearmouseclick
(which processes the event without providing its coordinates).
These two functions are described below.
void getmouseclick(kind, int& xint& y)
This function sets x and y to the pixel coordinates of an
unprocessed event of the specified kind. If there is no such
event, then the function sets both x and y to -1.
The value of the argument kind may be any of the constants
listed above. After calling getmouseclick
,
for a particular kind of event, the ismouseclick
will return false for that kind of event until another such event occurs.
void clearmouseclick(kind)
This is just like getmouseclick
, except it does not
provide the x and y coordinates of the event.
The value of the argument kind
may be any of the constants
listed above. After calling clearmouseclick
,
for a particular kind of event, the ismouseclick
will return false for that kind of event until another such event occurs.
void registermousehandler(kind, h)
Most mouse processing can be carried out with the
ismouseclick
and getmouseclick
.
But sometimes you need more control.
In general, you can obtain more control by
writing a different "handler function"
to handle each different
kind of mouse event, and you "register" each of your
handlers by calling registermousehandler
.
The first argument to registermousehandler
is
one of the constants listed above.
The second argument to registermousehandler
must be the name of the handler function that you wrote. This
function must be a void function with two int parameters.
Whenever the specified mouse event occurs, your handler will
be called and the two int parameters will be the x and y positions
where the event happened.
ismouseclick
and getmouseclick
void wait_for_left_click( ) { const int DELAY = 50; // Milliseconds of delay between checks int x, y; while (!ismouseclick(WM_LBUTTONDOWN)) delay(DELAY); getmouseclick(WM_LBUTTONDOWN, x, y); cout << "Latest left click at: " << x << " " << y << endl; }
void my_right_click_handler(int x, int y) { cout << "Right mouse click at " << x << " and " << y << endl; }Now, somewhere in your program (after you've initialized the graphics window), you must register this fine handler with the statement:
registermousehandler(WM_RBUTTONDOWN, my_right_click_handler);
In general, the work carried out in a handler must be small. If you need to do a lot of work, have the handler change a global variable that will later trigger the large work. Then the handler can return quickly.
void delay(int millisec)
int getch( )
int kbhit( )
c = (char) getch( );
If you press one of the keypad keys (arrows, Home, etc.), then
getch first returns the value 0. Then, at the next call, it will
KEY_HOME
KEY_UP
KEY_PGUP
KEY_LEFT
KEY_CENTER
KEY_RIGHT
KEY_END
KEY_DOWN
KEY_PGDN
KEY_INSERT
KEY_DELETE
-
The kbhit function returns 0 if there are no characters now waiting
to be read (with getch). It returns a non-zero if there are some
characters waiting to be read.
getactivepage()
and
getvisualpage()
to help support double-buffering.
They return the page number of the active page (where drawing is
currently taking place) and the visual page (the one on the screen).
The original winbgi was designed to support up to 16 pages, but I have
only used pages 1 and 2 myself. NOTE: Using page number 0 might
mess up the colors. I use pages 1-2 for double buffering.
bgiout
. It's
used is described in bgiout.html.
The graphics window now has a print option in the windows menu button, so the user can print the screen at any time. In additon, there are these new functions:
The initiwindow function can now be called multiple times to create more than one graphics window. The initwindow documentation describes how these multiple windows are used.
You may have noticed that any program that's compiled with g++ or bgi++ will always open a DOS command window when the program is run. If you want to stop this window from opening, then add the option -mwindows to the compile line (just after g++ or bgi++).