Page 1 of 1

How to make Bitmaps on Menu's Transparent In C++ Win32. Rate Topic: -----

#1 snoopy11  Icon User is online

  • Engineering ● Software
  • member icon

Reputation: 765
  • View blog
  • Posts: 2,225
  • Joined: 20-March 10

Posted 03 June 2012 - 12:23 PM

How to make Bitmaps on Menu's Transparent In C++ Win32.



This Tutorial Follows on from a previous Tutorial that I had.
I recently came across someone who wanted to make their bitmaps
Transparent for his Menu’s and no matter how much I helped him
He still wasn’t getting it. In fact he kept saying bitmaps are ‘ugly’
And icons were better.
Which surprised me as every format is eventually internally transformed to a bitmap by Windows.
But the truth is you can make bitmaps transparent if you want.
This is what we will do in this Tutorial so no matter the color of your menu
You will see transparency….
The Bitmaps I will be using this time.

Attached File  star.bmp (3.05K)
Number of downloads: 713
Attached File  pentagon.bmp (3.05K)
Number of downloads: 471
Attached File  diamond.bmp (3.05K)
Number of downloads: 452





They don’t look very transparent do they?
They look a bit well; Red is the word that springs to mind.
Don’t worry it’s all part of the plan.
There are about six ways to do this that I know of..
There are probably more that I don’t know of.
This is just one of them.

The Resource File.

First of all I would like to discuss the resource file
This is as follows

#include "resource.h"


BM1 BITMAP DISCARDABLE  "star.bmp"

BM2 BITMAP DISCARDABLE  "pentagon.bmp"

BM3 BITMAP DISCARDABLE  "diamond.bmp"


hMenu MENU DISCARDABLE

BEGIN

POPUP   "&File"

BEGIN

MENUITEM "Star", IDM_STAR

MENUITEM "Pentagon", IDM_PENTAGON

MENUITEM "Diamond", IDM_DIAMOND

END

END





Now the first thing we notice is that there are 3 bitmaps

Star
Pentagon
And Diamond.

Our Bitmaps are given labels BM1 to BM3.

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 Star, Pentagon and Diamond.

They are given labels too

IDM_STAR
IDM_PENTAGON
and
IDM_DIAMOND

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_STAR 101
#define IDM_PENTAGON 102
#define IDM_DIAMOND 103

#define BM1   1001
#define BM2   1002
#define BM3   1003



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.
You can build it with the icons provided.
Naming those icons as stated and putting them in your project directory.
This is not a Unicode build so please if you are using VS
change your character set to Multi-Byte.

#include "resource.h"
#include <Windows.h>


HBITMAP hBitmap = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(BM1));
HBITMAP hBitmap2 = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(BM2));
HBITMAP hBitmap3 = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(BM3));

int star = 0;
int pentagon = 0;
int diamond = 0;
int sClick = 0;
int dClick = 0;
int pClick = 0;
int memory = 0;
static HMENU Menu;

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
HBITMAP MakeBitMapTransparent(HBITMAP hbmSrc);

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)));//turn our window purple... sweet !
	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("Transparent 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(255, 0, 0));

		}

		break;


	case WM_CREATE:

		{
			
            
			Menu = GetMenu(hwnd);
			SetMenuItemBitmaps(Menu,IDM_STAR,MF_BITMAP|MF_BYCOMMAND,hBitmap,hBitmap);//set our menus to horrible rednesss
			SetMenuItemBitmaps(Menu,IDM_PENTAGON,MF_BITMAP|MF_BYCOMMAND,hBitmap2,hBitmap2);
			SetMenuItemBitmaps(Menu,IDM_DIAMOND,MF_BITMAP|MF_BYCOMMAND,hBitmap3,hBitmap3);
			
			hBitmap = MakeBitMapTransparent(hBitmap);// transform our bitmaps
			hBitmap2 = MakeBitMapTransparent(hBitmap2);
			hBitmap3 = MakeBitMapTransparent(hBitmap3);
			
			
			SetMenuItemBitmaps(Menu,IDM_STAR,MF_BITMAP|MF_BYCOMMAND,hBitmap,hBitmap);// set our menus to transparency wow !
			SetMenuItemBitmaps(Menu,IDM_PENTAGON,MF_BITMAP|MF_BYCOMMAND,hBitmap2,hBitmap2);
			SetMenuItemBitmaps(Menu,IDM_DIAMOND,MF_BITMAP|MF_BYCOMMAND,hBitmap3,hBitmap3);

			DrawMenuBar(hwnd);
			InvalidateRect(hwnd,NULL,true);
			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 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 star has been clicked evaluate

			if (sClick == 1)
			{
				sClick =0;
				memory =1;
				switch (star)
				{
				case 1:
					{

						DrawText(hdc,"You Selected star", -1,&rect, DT_CENTER | DT_WORDBREAK);

						break;
					}

				case 2:
					{
						DrawText(hdc,"You Deselected star", -1,&rect, DT_CENTER | DT_WORDBREAK);

						break;
					}

				}
			}

			// If pentagon has been clicked evaluate

			if (dClick == 1)
			{
				memory =2;
				dClick =0;
				switch (pentagon)
				{

				case 1:
					{
						DrawText(hdc,"You Selected pentagon", -1,&rect, DT_CENTER | DT_WORDBREAK);

						break;
					}

				case 2:
					{
						DrawText(hdc,"You Deselected pentagon", -1,&rect, DT_CENTER | DT_WORDBREAK);

						break;
					}

				}
			}

			if (pClick == 1)
			{
				memory =3;
				pClick =0;
				switch (diamond)
				{

				case 1:
					{
						DrawText(hdc,"You Selected diamond", -1,&rect, DT_CENTER | DT_WORDBREAK);

						break;
					}

				case 2:
					{
						DrawText(hdc,"You Deselected diamond", -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_STAR:
				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 (star == 0)
				{
					star = 1;
					sClick = 1;
					InvalidateRect(hwnd,NULL,true);
					break;
				}

				else if (star == 1)
				{
					star = 2;
					sClick = 1;
					InvalidateRect(hwnd,NULL,true);
					break;
				}

				else if (star == 2)
				{
					star = 1;
					sClick = 1;
					InvalidateRect(hwnd,NULL,true);
					break;
				}
				break;

			case IDM_PENTAGON:
				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 (pentagon == 0)
				{
					pentagon = 1;
					dClick = 1;
					InvalidateRect(hwnd,NULL,true);
					break;
				}

				else if (pentagon == 1)
				{
					pentagon = 2;
					dClick = 1;
					InvalidateRect(hwnd,NULL,true);
					break;
				}

				else if (pentagon == 2)
				{
					pentagon = 1;
					dClick = 1;
					InvalidateRect(hwnd,NULL,true);
					break;
				}
				break;

			case IDM_DIAMOND:
				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 (diamond == 0)
				{
					diamond = 1;
					pClick = 1;
					InvalidateRect(hwnd,NULL,true);
					break;
				}

				else if (diamond == 1)
				{
					diamond = 2;
					pClick = 1;
					InvalidateRect(hwnd,NULL,true);
					break;
				}

				else if (diamond == 2)
				{
					diamond = 1;
					pClick = 1;
					InvalidateRect(hwnd,NULL,true);
					break;
				}

				break;



			}//switch.
			break;
		}

	case WM_SIZE:
		if (memory==1)
		{
			sClick =1;
		}

		if (memory==2)
		{
			dClick =1;
		}

		if (memory==3)
		{
			pClick =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;
}



HBITMAP MakeBitMapTransparent(HBITMAP hbmSrc)
{
	HDC hdcSrc, hdcDst;
	HBITMAP hbmOld, hbmNew;
	BITMAP bm;
	COLORREF clrTP, clrBK;

	if ((hdcSrc = CreateCompatibleDC(NULL)) != NULL) {
		if ((hdcDst = CreateCompatibleDC(NULL)) != NULL) {
			int nRow, nCol;
			GetObject(hbmSrc, sizeof(bm), &bm);
			hbmOld = (HBITMAP)SelectObject(hdcSrc, hbmSrc);
			hbmNew = CreateBitmap(bm.bmWidth, bm.bmHeight, bm.bmPlanes, bm.bmBitsPixel, NULL);
			SelectObject(hdcDst, hbmNew);
			
			BitBlt(hdcDst,0,0,bm.bmWidth, bm.bmHeight,hdcSrc,0,0,SRCCOPY);

			clrTP = GetPixel(hdcDst, 0, 0);// Get color of first pixel at 0,0
			clrBK = GetSysColor(COLOR_MENU);// Get the current background color of the menu
			
			for (nRow = 0; nRow < bm.bmHeight; nRow++)// work our way through all the pixels changing their color
				for (nCol = 0; nCol < bm.bmWidth; nCol++)// when we hit our set transparency color.
					if (GetPixel(hdcDst, nCol, nRow) == clrTP)
						SetPixel(hdcDst, nCol, nRow, clrBK);
			
			DeleteDC(hdcDst);
		}
		DeleteDC(hdcSrc);
		
	}
	return hbmNew;// return our transformed bitmap.
}




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

#include "resource.h"
#include <Windows.h>


HBITMAP hBitmap = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(BM1));
HBITMAP hBitmap2 = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(BM2));
HBITMAP hBitmap3 = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(BM3));



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 star = 0;
int pentagon = 0;
int diamond = 0;
int sClick = 0;
int dClick = 0;
int pClick = 0;
int memory = 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);
HBITMAP MakeBitMapTransparent(HBITMAP hbmSrc);



This is our CallBack routine WndProc we define it inside WinMain

with the setter lpfnWndProc and our function to make bitmaps transparent.... exciting !



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)));//turn our window purple... sweet !
	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("Transparent 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)
	{



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 ;
	DWORD bMenuItemID;
	BYTE fbAttributes;
	HDC hdc;
	PAINTSTRUCT ps;
	long lfHeight = 100;
	RECT rect;
	HPEN   hPen1;
	HPEN   hPenThinBlack;
	HFONT       hf;
	switch(msg)
	{



Our Windows callback routine, sets up some local variables.

6th Block

case WM_CREATE:

		{
			
            
			Menu = GetMenu(hwnd);
			SetMenuItemBitmaps(Menu,IDM_STAR,MF_BITMAP|MF_BYCOMMAND,hBitmap,hBitmap);//set our menus to horrible rednesss
			SetMenuItemBitmaps(Menu,IDM_PENTAGON,MF_BITMAP|MF_BYCOMMAND,hBitmap2,hBitmap2);
			SetMenuItemBitmaps(Menu,IDM_DIAMOND,MF_BITMAP|MF_BYCOMMAND,hBitmap3,hBitmap3);
			
			hBitmap = MakeBitMapTransparent(hBitmap);// transform our bitmaps
			hBitmap2 = MakeBitMapTransparent(hBitmap2);
			hBitmap3 = MakeBitMapTransparent(hBitmap3);
			
			
			SetMenuItemBitmaps(Menu,IDM_STAR,MF_BITMAP|MF_BYCOMMAND,hBitmap,hBitmap);// set our menus to transparency wow !
			SetMenuItemBitmaps(Menu,IDM_PENTAGON,MF_BITMAP|MF_BYCOMMAND,hBitmap2,hBitmap2);
			SetMenuItemBitmaps(Menu,IDM_DIAMOND,MF_BITMAP|MF_BYCOMMAND,hBitmap3,hBitmap3);

			DrawMenuBar(hwnd);
			InvalidateRect(hwnd,NULL,true);
			break;
		}




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 then transformed into transparency.

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));

			HBRUSH 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 star has been clicked evaluate

			if (sClick == 1)
			{
				sClick =0;
				memory =1;
				switch (star)
				{
				case 1:
					{

						DrawText(hdc,"You Selected star", -1,&rect, DT_CENTER | DT_WORDBREAK);

						break;
					}

				case 2:
					{
						DrawText(hdc,"You Deselected star", -1,&rect, DT_CENTER | DT_WORDBREAK);

						break;
					}

				}
			}

			// If pentagon has been clicked evaluate

			if (dClick == 1)
			{
				memory =2;
				dClick =0;
				switch (pentagon)
				{

				case 1:
					{
						DrawText(hdc,"You Selected pentagon", -1,&rect, DT_CENTER | DT_WORDBREAK);

						break;
					}

				case 2:
					{
						DrawText(hdc,"You Deselected pentagon", -1,&rect, DT_CENTER | DT_WORDBREAK);

						break;
					}

				}
			}

			if (pClick == 1)
			{
				memory =3;
				pClick =0;
				switch (diamond)
				{

				case 1:
					{
						DrawText(hdc,"You Selected diamond", -1,&rect, DT_CENTER | DT_WORDBREAK);

						break;
					}

				case 2:
					{
						DrawText(hdc,"You Deselected diamond", -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_STAR:
				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 (star == 0)
				{
					star = 1;
					sClick = 1;
					InvalidateRect(hwnd,NULL,true);
					break;
				}

				else if (star == 1)
				{
					star = 2;
					sClick = 1;
					InvalidateRect(hwnd,NULL,true);
					break;
				}

				else if (star == 2)
				{
					star = 1;
					sClick = 1;
					InvalidateRect(hwnd,NULL,true);
					break;
				}
				break;

			case IDM_PENTAGON:
				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 (pentagon == 0)
				{
					pentagon = 1;
					dClick = 1;
					InvalidateRect(hwnd,NULL,true);
					break;
				}

				else if (pentagon == 1)
				{
					pentagon = 2;
					dClick = 1;
					InvalidateRect(hwnd,NULL,true);
					break;
				}

				else if (pentagon == 2)
				{
					pentagon = 1;
					dClick = 1;
					InvalidateRect(hwnd,NULL,true);
					break;
				}
				break;

			case IDM_DIAMOND:
				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 (diamond == 0)
				{
					diamond = 1;
					pClick = 1;
					InvalidateRect(hwnd,NULL,true);
					break;
				}

				else if (diamond == 1)
				{
					diamond = 2;
					pClick = 1;
					InvalidateRect(hwnd,NULL,true);
					break;
				}

				else if (diamond == 2)
				{
					diamond = 1;
					pClick = 1;
					InvalidateRect(hwnd,NULL,true);
					break;
				}

				break;



			}//switch.
			break;
		}

	case WM_SIZE:
		if (memory==1)
		{
			sClick =1;
		}

		if (memory==2)
		{
			dClick =1;
		}

		if (memory==3)
		{
			pClick =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;
}



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_STAR
IDM_PENTAGON
and
IDM_DIAMOND


We use bMenuItemID to store which MenuItem has been clicked.
We then use fdwMenu to evaluate whether the item is selected and unselected..


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

HBITMAP MakeBitMapTransparent(HBITMAP hbmSrc)
{
	HDC hdcSrc, hdcDst;
	HBITMAP hbmOld, hbmNew;
	BITMAP bm;
	COLORREF clrTP, clrBK;

	if ((hdcSrc = CreateCompatibleDC(NULL)) != NULL) {
		if ((hdcDst = CreateCompatibleDC(NULL)) != NULL) {
			int nRow, nCol;
			GetObject(hbmSrc, sizeof(bm), &bm);
			hbmOld = (HBITMAP)SelectObject(hdcSrc, hbmSrc);
			hbmNew = CreateBitmap(bm.bmWidth, bm.bmHeight, bm.bmPlanes, bm.bmBitsPixel, NULL);
			SelectObject(hdcDst, hbmNew);
			
			BitBlt(hdcDst,0,0,bm.bmWidth, bm.bmHeight,hdcSrc,0,0,SRCCOPY);

			clrTP = GetPixel(hdcDst, 0, 0);// Get color of first pixel at 0,0
			clrBK = GetSysColor(COLOR_MENU);// Get the current background color of the menu
			
			for (nRow = 0; nRow < bm.bmHeight; nRow++)// work our way through all the pixels changing their color
				for (nCol = 0; nCol < bm.bmWidth; nCol++)// when we hit our set transparency color.
					if (GetPixel(hdcDst, nCol, nRow) == clrTP)
						SetPixel(hdcDst, nCol, nRow, clrBK);
			
			DeleteDC(hdcDst);
		}
		DeleteDC(hdcSrc);
		
	}
	return hbmNew;// return our transformed bitmap.
}






10th Block of Code


HBITMAP MakeBitMapTransparent(HBITMAP hbmSrc)
{
	HDC hdcSrc, hdcDst;
	HBITMAP hbmOld, hbmNew;
	BITMAP bm;
	COLORREF clrTP, clrBK;

	if ((hdcSrc = CreateCompatibleDC(NULL)) != NULL) {
		if ((hdcDst = CreateCompatibleDC(NULL)) != NULL) {
			int nRow, nCol;
			GetObject(hbmSrc, sizeof(bm), &bm);
			hbmOld = (HBITMAP)SelectObject(hdcSrc, hbmSrc);
			hbmNew = CreateBitmap(bm.bmWidth, bm.bmHeight, bm.bmPlanes, bm.bmBitsPixel, NULL);
			SelectObject(hdcDst, hbmNew);
			
			BitBlt(hdcDst,0,0,bm.bmWidth, bm.bmHeight,hdcSrc,0,0,SRCCOPY);

			clrTP = GetPixel(hdcDst, 0, 0);// Get color of first pixel at 0,0
			clrBK = GetSysColor(COLOR_MENU);// Get the current background color of the menu
			
			for (nRow = 0; nRow < bm.bmHeight; nRow++)// work our way through all the pixels changing their color
				for (nCol = 0; nCol < bm.bmWidth; nCol++)// when we hit our set transparency color.
					if (GetPixel(hdcDst, nCol, nRow) == clrTP)
						SetPixel(hdcDst, nCol, nRow, clrBK);
			
			DeleteDC(hdcDst);
		}
		DeleteDC(hdcSrc);
		
	}
	return hbmNew;// return our transformed bitmap.
}



Our Bitmap transforming function.
set up some variables,create a hdc or two to the screen
create a new bitmap select this into a hdc
what ever happens to this hdc will now happen to our bitmap.

Blit our source dc onto our destination hdc


Whatever happens now to that hdc will happen to that bitmap hbmNew

Get color of first pixel at 0,0
Get the current background color of the menu

loop through each pixel when it matches the first color of what we see in 0,0
change it to the color background of the menu color.

So thats it !! Transparency issues solved !

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

Snoopy.

Is This A Good Question/Topic? 2
  • +

Page 1 of 1