This tutorial is concerned with getting with getting little icon pictures
onto your Menu's...
Now first of all I would like to talk a little about the icons themselves.
If you are just making a program for yourself I recommend in taking the
time to make your own 16 by 16 .bmp (bitmap) files.
If however you are making your program for commercial reasons,
that is you're going to sell it. I strongly recommend gettting them made professionally.
This can cost $50 a picture but if you negotiate with the free lance graphic designer
first you can usually get them down to half that or more depending on how many of
the little critters your going to need. They are after all very small graphics.
Smiley face full Colour

Smiley face grayed out

Tree full Colour

Tree grayed out

Car full Colour

Car grayed out

The Resource File.
First of all I would like to discuss the resource file
This is as follows
#include "resource.h"
BM1 BITMAP DISCARDABLE "smiley.bmp"
BM2 BITMAP DISCARDABLE "smiley2.bmp"
BM3 BITMAP DISCARDABLE "tree.bmp"
BM4 BITMAP DISCARDABLE "tree2.bmp"
BM5 BITMAP DISCARDABLE "car.bmp"
BM6 BITMAP DISCARDABLE "car2.bmp"
hMenu MENU DISCARDABLE
BEGIN
POPUP "&File"
BEGIN
MENUITEM "Smiley", IDM_SMILEY
MENUITEM "Tree", IDM_TREE
MENUITEM "Car", IDM_CAR
END
END
Now the first thing we notice is that there are 6 bitmaps
Smiley
Smiley2
etc.
Now Smiley is the full colour icon and Smiley2 is the grayed out icon.
Our Bitmaps are given labels BM1 to BM6.
Our Menu name is hMenu it draws a Menu Bar on your Window
designated by File and has 3 items on the File Menu
These are Smiley, Tree and Car.
They are given labels too
IDM_SMILEY
IDM_TREE
and
IDM_CAR
We will use these later on in our main .cpp.
The Resource Header.
Our Resource Header is called 'resource.h'
This is non-negotiable our program depends on it being called that.
#include <windows.h> #define hMenu 100 #define IDM_SMILEY 101 #define IDM_TREE 102 #define IDM_CAR 103 #define BM1 1001 #define BM2 1002 #define BM3 1003 #define BM4 1004 #define BM5 1005 #define BM6 1006
This is our list of defines we give each of them a unique
number this is important. Try to group things in
different hundreds and thousands groupings
obviously the same type of things go in the same type of groups.
We use these label identifiers later in MAKEINTRESOURCE.
The Main Program main.cpp
Well next up is the main.cpp.
I will include all of it at once then explain it piece by piece.
But for those who want to see what the program does, that is
those that can't wait. You can build it with the icons provided.
Naming those icons as stated and putting them in your project directory.
#include "resource.h"
HBITMAP hBitmap = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(BM1));
HBITMAP hBitmap2 = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(BM2));
HBITMAP sBitmap = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(BM3));
HBITMAP sBitmap2 = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(BM4));
HBITMAP lBitmap = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(BM5));
HBITMAP lBitmap2 = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(BM6));
int smiley = 0;
int tree = 0;
int car = 0;
int sClick = 0;
int tClick = 0;
int cClick = 0;
int memory = 0;
static HMENU Menu;
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
LPCTSTR className = TEXT("BitmapMenu");
WNDCLASSEX wc;
wc.cbSize = sizeof(wc);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.cbWndExtra = 0;
wc.cbClsExtra = 0;
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.lpszMenuName = MAKEINTRESOURCE(hMenu);
wc.lpszClassName = className;
wc.hbrBackground = (HBRUSH)(CreateSolidBrush(RGB(48, 38, 88)));
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
if(!RegisterClassEx(&wc))
{
MessageBox(NULL, TEXT("ERROR! FAILED TO REGISTER CLASS!"), TEXT("FATAL ERROR!"), MB_IConerror | MB_OK);
return true;
}
HWND hwnd = CreateWindowEx(0, className, TEXT("Bitmaps on Menu Demo"), WS_OVERLAPPEDWINDOW, 450, 100, 500 + 7, 500 + 33 , NULL, NULL, hInstance, NULL);
if(!hwnd)
{
MessageBox(NULL, TEXT("ERROR! FAILED TO CREATE WINDOW!"), TEXT("FATAL ERROR!"), MB_IConerror | MB_OK);
return true;
}
ShowWindow(hwnd, nShowCmd);
UpdateWindow(hwnd);
MSG msg;
while(GetMessage(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
DWORD fdwMenu ;
DWORD bMenuItemID;
BYTE fbAttributes;
HDC hdc;
PAINTSTRUCT ps;
long lfHeight = 100;
RECT rect;
HPEN hPen1;
HPEN hPenThinBlack;
HFONT hf;
switch(msg)
{
case WM_CTLCOLORSTATIC:
{
SetBkMode((HDC) wParam, TRANSPARENT);
return (LRESULT) CreateHatchBrush(HS_HORIZONTAL,RGB(48, 38, 88));
}
break;
case WM_CREATE:
{
Menu = GetMenu(hwnd);
SetMenuItemBitmaps(Menu, IDM_SMILEY, MF_BYCOMMAND, hBitmap , hBitmap2);
SetMenuItemBitmaps(Menu, IDM_TREE, MF_BYCOMMAND, sBitmap , sBitmap2);
SetMenuItemBitmaps(Menu, IDM_CAR, MF_BYCOMMAND, lBitmap , lBitmap2);
break;
}
case WM_PAINT:
{
hdc=BeginPaint(hwnd,&ps);
hPen1 = CreatePen(PS_SOLID, 5 , RGB(128, 128, 128));
hPenThinBlack = CreatePen(PS_SOLID, 1 , RGB(0,0,0));
//hBrush = CreateHatchBrush(HS_HORIZONTAL,RGB(48, 38, 88));
lfHeight=50;
hf = CreateFont(lfHeight, 0, 0, 0, 0, TRUE, 0, 0, 0, 0, 0, 0, 0, "Times New Roman");
SelectObject(hdc, hf);
rect.top=140;
rect.bottom=525;
rect.left=25;
rect.right=425;
SetBkColor(hdc, RGB(48, 38, 88));
SetTextColor(hdc, RGB(128, 128, 128));
// If Smiley has been clicked evaluate
if (sClick == 1)
{
sClick =0;
memory =1;
switch (smiley)
{
case 1:
{
DrawText(hdc,"You Selected Smiley", -1,&rect, DT_CENTER | DT_WORDBREAK);
break;
}
case 2:
{
DrawText(hdc,"You Deselected Smiley", -1,&rect, DT_CENTER | DT_WORDBREAK);
break;
}
}
}
// If Tree has been clicked evaluate
if (tClick == 1)
{
memory =2;
tClick =0;
switch (tree)
{
case 1:
{
DrawText(hdc,"You Selected Tree", -1,&rect, DT_CENTER | DT_WORDBREAK);
break;
}
case 2:
{
DrawText(hdc,"You Deselected Tree", -1,&rect, DT_CENTER | DT_WORDBREAK);
break;
}
}
}
if (cClick == 1)
{
memory =3;
cClick =0;
switch (car)
{
case 1:
{
DrawText(hdc,"You Selected Car", -1,&rect, DT_CENTER | DT_WORDBREAK);
break;
}
case 2:
{
DrawText(hdc,"You Deselected Car", -1,&rect, DT_CENTER | DT_WORDBREAK);
break;
}
}
}
break;
}
case WM_COMMAND: //Command from Child windows and menus are under this message
{
switch(LOWORD(wParam)) //the ID is wParam
{
case IDM_SMILEY:
bMenuItemID = LOWORD(wParam);
fdwMenu = GetMenuState(Menu, (UINT) bMenuItemID, MF_BYCOMMAND);
if (!(fdwMenu & MF_CHECKED))
{
CheckMenuItem(Menu, (UINT) bMenuItemID,
MF_BYCOMMAND | MF_CHECKED);
fbAttributes |= bMenuItemID;
}
else
{
CheckMenuItem(Menu, (UINT) bMenuItemID,
MF_BYCOMMAND | MF_UNCHECKED);
fbAttributes ^= bMenuItemID;
}
if (smiley == 0)
{
smiley = 1;
sClick = 1;
InvalidateRect(hwnd,NULL,true);
break;
}
else if (smiley == 1)
{
smiley = 2;
sClick = 1;
InvalidateRect(hwnd,NULL,true);
break;
}
else if (smiley == 2)
{
smiley = 1;
sClick = 1;
InvalidateRect(hwnd,NULL,true);
break;
}
break;
case IDM_TREE:
bMenuItemID = LOWORD(wParam);
fdwMenu = GetMenuState(Menu, (UINT) bMenuItemID, MF_BYCOMMAND);
if (!(fdwMenu & MF_CHECKED))
{
CheckMenuItem(Menu, (UINT) bMenuItemID,
MF_BYCOMMAND | MF_CHECKED);
fbAttributes |= bMenuItemID;
}
else
{
CheckMenuItem(Menu, (UINT) bMenuItemID,
MF_BYCOMMAND | MF_UNCHECKED);
fbAttributes ^= bMenuItemID;
}
if (tree == 0)
{
tree = 1;
tClick = 1;
InvalidateRect(hwnd,NULL,true);
break;
}
else if (tree == 1)
{
tree = 2;
tClick = 1;
InvalidateRect(hwnd,NULL,true);
break;
}
else if (tree == 2)
{
tree = 1;
tClick = 1;
InvalidateRect(hwnd,NULL,true);
break;
}
break;
case IDM_CAR:
bMenuItemID = LOWORD(wParam);
fdwMenu = GetMenuState(Menu, (UINT) bMenuItemID, MF_BYCOMMAND);
if (!(fdwMenu & MF_CHECKED))
{
CheckMenuItem(Menu, (UINT) bMenuItemID,
MF_BYCOMMAND | MF_CHECKED);
fbAttributes |= bMenuItemID;
}
else
{
CheckMenuItem(Menu, (UINT) bMenuItemID,
MF_BYCOMMAND | MF_UNCHECKED);
fbAttributes ^= bMenuItemID;
}
if (car == 0)
{
car = 1;
cClick = 1;
InvalidateRect(hwnd,NULL,true);
break;
}
else if (car == 1)
{
car = 2;
cClick = 1;
InvalidateRect(hwnd,NULL,true);
break;
}
else if (car == 2)
{
car = 1;
cClick = 1;
InvalidateRect(hwnd,NULL,true);
break;
}
break;
}//switch.
break;
}
case WM_SIZE:
if (memory==1)
{
sClick =1;
}
if (memory==2)
{
tClick =1;
}
if (memory==3)
{
cClick =1;
}
InvalidateRect(hwnd,NULL,true);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
break; // pass to DefWindowProc(...) as well
case WM_CLOSE:
DestroyWindow(hwnd);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
References.
Petzold Programming Windows Fifth Edition
MSDN
The Explanation Part
Well first of all this is not a unicode build so if your planning to run with this in MSVC you will need to do the following...
Go to the projects 'Properties'
Under Configuration Properties -> General
Click on the 'Character Set' drop down box and select
'Use Multi-Byte Character Set'
then click on 'OK'.
Now that is out of the way...
We can begin explaining the code...
1st Block
HBITMAP hBitmap = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(BM1)); HBITMAP hBitmap2 = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(BM2)); HBITMAP sBitmap = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(BM3)); HBITMAP sBitmap2 = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(BM4)); HBITMAP lBitmap = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(BM5)); HBITMAP lBitmap2 = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(BM6));
This loads all the bitmaps into their various identifier variables.
Its quite straight forward it loads it from our resource identifier such as
'BM1' using the command MAKEINTRESOURCE();
2nd Block
int smiley = 0; int tree = 0; int car = 0; int sClick = 0; int tClick = 0; int cClick = 0; static HMENU Menu;
This sets up some variables that we need in determining what part of the menu has been clicked so we can take appropriate action.
We also set up a HMENU called Menu.
3rd Block
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
This is our CallBack routine WndProc we define it inside WinMain
with the setter lpfnWndProc.
4th Block
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
LPCTSTR className = TEXT("BitmapMenu");
WNDCLASSEX wc;
wc.cbSize = sizeof(wc);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.cbWndExtra = 0;
wc.cbClsExtra = 0;
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.lpszMenuName = MAKEINTRESOURCE(hMenu);
wc.lpszClassName = className;
wc.hbrBackground = (HBRUSH)(CreateSolidBrush(RGB(48, 38, 88)));
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
if(!RegisterClassEx(&wc))
{
MessageBox(NULL, TEXT("ERROR! FAILED TO REGISTER CLASS!"), TEXT("FATAL ERROR!"), MB_IConerror | MB_OK);
return true;
}
HWND hwnd = CreateWindowEx(0, className, TEXT("Bitmaps on Menu Demo"), WS_OVERLAPPEDWINDOW, 450, 100, 500 + 7, 500 + 33 , NULL, NULL, hInstance, NULL);
if(!hwnd)
{
MessageBox(NULL, TEXT("ERROR! FAILED TO CREATE WINDOW!"), TEXT("FATAL ERROR!"), MB_IConerror | MB_OK);
return true;
}
ShowWindow(hwnd, nShowCmd);
UpdateWindow(hwnd);
MSG msg;
while(GetMessage(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
This is WinMain the programs entry point.
It sets up various things like the name of our CallBack routine.
Registers the Window class.
Sets up our Main Window 'hwnd'.
Shows the Window on screen and then goes through a message loop
Translating and Dispatching messages.
5th Block
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
DWORD fdwMenu ;
BYTE bMenuItemID;
BYTE fbAttributes;
HDC hdc;
PAINTSTRUCT ps;
long lfHeight = 100;
RECT rect;
HPEN hPen1;
HPEN hPenThinBlack;
HFONT hf;
switch(msg)
{
This is the beginning of our Windows CallBack Procedure
It sets up some bits and pieces that we will need for the
Program nothing too dificult so far.
6th Block
case WM_CREATE:
{
Menu = GetMenu(hwnd);
SetMenuItemBitmaps(Menu, IDM_SMILEY, MF_BYCOMMAND, hBitmap , hBitmap2);
SetMenuItemBitmaps(Menu, IDM_TREE, MF_BYCOMMAND, sBitmap , sBitmap2);
SetMenuItemBitmaps(Menu, IDM_CAR, MF_BYCOMMAND, lBitmap , lBitmap2);
break;
}
Sets The Menu variable to the Application Menu there are various ways to do this
Im using GetMenu this time.
The command SetMenuItemBitmaps sets the Menu items by their resource file names as told to by the MF_BYCOMMAND flag hBitmap and hBitmap2 are the loaded bitmaps of the full colour icon bitmap and the grayed out icon bitmap respectively.
This process carries on for each of the three Menu items we have, if you had more Menu Items then you would have more calls like these to place.
7th Block
case WM_PAINT:
{
hdc=BeginPaint(hwnd,&ps);
hPen1 = CreatePen(PS_SOLID, 5 , RGB(128, 128, 128));
hPenThinBlack = CreatePen(PS_SOLID, 1 , RGB(0,0,0));
lfHeight=50;
hf = CreateFont(lfHeight, 0, 0, 0, 0, TRUE, 0, 0, 0, 0, 0, 0, 0, "Times New Roman");
SelectObject(hdc, hf);
rect.top=140;
rect.bottom=525;
rect.left=25;
rect.right=425;
SetBkColor(hdc, RGB(48, 38, 88));
SetTextColor(hdc, RGB(128, 128, 128));
// If Smiley has been clicked evaluate
if (sClick == 1)
{
sClick =0;
switch (smiley)
{
case 1:
{
DrawText(hdc,"You Selected Smiley", -1,&rect, DT_CENTER | DT_WORDBREAK);
break;
}
case 2:
{
DrawText(hdc,"You Deselected Smiley", -1,&rect, DT_CENTER | DT_WORDBREAK);
break;
}
}
}
// If Tree has been clicked evaluate
if (tClick == 1)
{
tClick =0;
switch (tree)
{
case 1:
{
DrawText(hdc,"You Selected Tree", -1,&rect, DT_CENTER | DT_WORDBREAK);
break;
}
case 2:
{
DrawText(hdc,"You Deselected Tree", -1,&rect, DT_CENTER | DT_WORDBREAK);
break;
}
}
}
if (cClick == 1)
{
cClick =0;
switch (car)
{
case 1:
{
DrawText(hdc,"You Selected Car", -1,&rect, DT_CENTER | DT_WORDBREAK);
break;
}
case 2:
{
DrawText(hdc,"You Deselected Car", -1,&rect, DT_CENTER | DT_WORDBREAK);
break;
}
}
}
break;
}
We set up some Pens to draw with a rectangle RECT structure to cover the size of our Text we will draw on top of the window later in response to Menu changes.
We Set the Background colour of the Text and the Text colour itself.
Then we draw various messages depending on what we had selected in our Menu.
8th Block
case WM_COMMAND: //Command from Child windows and menus are under this message
{
switch(LOWORD(wParam)) //the ID is wParam
{
case IDM_SMILEY:
bMenuItemID = LOWORD(wParam);
fdwMenu = GetMenuState(Menu, (UINT) bMenuItemID, MF_BYCOMMAND);
if (!(fdwMenu & MF_CHECKED))
{
CheckMenuItem(Menu, (UINT) bMenuItemID,
MF_BYCOMMAND | MF_CHECKED);
fbAttributes |= bMenuItemID;
}
else
{
CheckMenuItem(Menu, (UINT) bMenuItemID,
MF_BYCOMMAND | MF_UNCHECKED);
fbAttributes ^= bMenuItemID;
}
if (smiley == 0)
{
smiley = 1;
sClick = 1;
InvalidateRect(hwnd,NULL,true);
break;
}
else if (smiley == 1)
{
smiley = 2;
sClick = 1;
InvalidateRect(hwnd,NULL,true);
break;
}
else if (smiley == 2)
{
smiley = 1;
sClick = 1;
InvalidateRect(hwnd,NULL,true);
break;
}
break;
case IDM_TREE:
bMenuItemID = LOWORD(wParam);
fdwMenu = GetMenuState(Menu, (UINT) bMenuItemID, MF_BYCOMMAND);
if (!(fdwMenu & MF_CHECKED))
{
CheckMenuItem(Menu, (UINT) bMenuItemID,
MF_BYCOMMAND | MF_CHECKED);
fbAttributes |= bMenuItemID;
}
else
{
CheckMenuItem(Menu, (UINT) bMenuItemID,
MF_BYCOMMAND | MF_UNCHECKED);
fbAttributes ^= bMenuItemID;
}
if (tree == 0)
{
tree = 1;
tClick = 1;
InvalidateRect(hwnd,NULL,true);
break;
}
else if (tree == 1)
{
tree = 2;
tClick = 1;
InvalidateRect(hwnd,NULL,true);
break;
}
else if (tree == 2)
{
tree = 1;
tClick = 1;
InvalidateRect(hwnd,NULL,true);
break;
}
break;
case IDM_CAR:
bMenuItemID = LOWORD(wParam);
fdwMenu = GetMenuState(Menu, (UINT) bMenuItemID, MF_BYCOMMAND);
if (!(fdwMenu & MF_CHECKED))
{
CheckMenuItem(Menu, (UINT) bMenuItemID,
MF_BYCOMMAND | MF_CHECKED);
fbAttributes |= bMenuItemID;
}
else
{
CheckMenuItem(Menu, (UINT) bMenuItemID,
MF_BYCOMMAND | MF_UNCHECKED);
fbAttributes ^= bMenuItemID;
}
if (car == 0)
{
car = 1;
cClick = 1;
InvalidateRect(hwnd,NULL,true);
break;
}
else if (car == 1)
{
car = 2;
cClick = 1;
InvalidateRect(hwnd,NULL,true);
break;
}
else if (car == 2)
{
car = 1;
cClick = 1;
InvalidateRect(hwnd,NULL,true);
break;
}
break;
}
This looks a lot of very confusing code but it's not
it's the same thing 3 times.
You can split it into 3 bits or cases...
IDM_SMILEY
IDM_TREE
and
IDM_CAR
We use bMenuItemID to store which MenuItem has been clicked.
We then use fdwMenu to evaluate whether the Menu image should be set
to checked or unchecked or selected and unselected..
In fact whether it should be the grayed out image that is displayed or full colour.
We then use the CheckMenuItem command to change the image from grayed out to colour
or colour to grayed out.
We then check to see if we should display a message on our Window informing of us of
a change in selection or deselection for that matter.
9th Block
case WM_SIZE:
if (memory==1)
{
sClick =1;
}
if (memory==2)
{
tClick =1;
}
if (memory==3)
{
cClick =1;
}
InvalidateRect(hwnd,NULL,true);
return 0;
This 9th Block of code basically deals
with resizing, moving and minimizing of the application
while still keeping information on screen about our selections.
Now Windows OS constantly makes calls to WM_ERASEBKGND
erasing the background of the window when it updates
the window. So we need a way of remembering what it was we selected
then repaint the window via WM_SIZE.
We do this with the 'memory' variable.
If 'memory' = 1 then we simulate a click on the Smiley
that is we set 'sClick' = 1 and force a repaint through InvalidateRect.
The program automatically still remembers if it was a 'selected' click
or a 'deselected' click and displays the correct message.
Final Block
case WM_DESTROY:
PostQuitMessage(0);
break; // pass to DefWindowProc(...) as well
case WM_CLOSE:
DestroyWindow(hwnd);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
This final block deals with closing the window properly and cleaning up.
Now if you want to download the .bmp bitmaps you can or make your own 16 by 16 icon bitmaps
You should have 3 files in your project
resource.h
resource.rc
and
main.cpp
I have tested this with MSVC and Code::Blocks and both run fine with this..
See your specific compiler info for where to put the .bmp files.
All the full code listings are at the top of this Tutorial.
Thanks for taking the time out to go into this journey.
Snoopy.
Attached File(s)
-
smiley.bmp (774bytes)
Number of downloads: 193 -
smiley2.bmp (774bytes)
Number of downloads: 149 -
tree.bmp (774bytes)
Number of downloads: 142 -
tree2.bmp (774bytes)
Number of downloads: 150 -
car.bmp (774bytes)
Number of downloads: 155 -
car2.bmp (774bytes)
Number of downloads: 148





MultiQuote


|