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.

Number of downloads: 1319

Number of downloads: 891

Number of downloads: 801
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.