I tried writing this on my own, but it is beyond me.
My latest attempt has been the following:
I have been studying DrawText function from microsoft.com to write text to a bitmap.
Then I tried using similar to from stackoverflow.com but I did not get that to work. My compiler chokes on that. I tried studying that and fixing it, but my many attempts did not work.
Also, I tried adjusting this another from codeproject.com from whatever that is written in. I think it is MFC or cling-on or confused-us or something. My compiler pukes out almost every line of that.
Now I have this:
Expand|Select|Wrap|Line Numbers
- HBITMAP hbitmap = hMainWindowBitmapForRegion;
- // MAKEINTRESOURCE(IDB_BITMAP1));
- //BITMAP bm;
- GetObject( hbitmap, sizeof(BITMAP), &bm );
- long width=bm.bmWidth;
- long height=bm.bmHeight;
- //prepare the bitmap attributes
- BITMAPINFO bmInfo;
- memset(&bmInfo.bmiHeader,0,sizeof(BITMAPINFOHEADER));
- bmInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
- bmInfo.bmiHeader.biWidth=width;
- bmInfo.bmiHeader.biHeight=height;
- bmInfo.bmiHeader.biPlanes=1;
- bmInfo.bmiHeader.biBitCount=24;
- //create a temporary dc in memory.
- HDC pDC = ::GetDC(0);
- HDC TmpDC=CreateCompatibleDC(pDC);
- //create a new bitmap and select it in the memory dc
- BYTE *pbase;
- HBITMAP TmpBmp=CreateDIBSection(pDC,
- &bmInfo,DIB_RGB_COLORS,(void**)&pbase,0,0);
- HGDIOBJ TmpObj=SelectObject(TmpDC,TmpBmp);
- //draw the background
- HDC dcBmp=CreateCompatibleDC(TmpDC);
- HGDIOBJ TmpObj2 = SelectObject(dcBmp,hbitmap);
- BitBlt(TmpDC,0,0,width,height,dcBmp,0,0,SRCCOPY);
- SelectObject(TmpDC,TmpObj2);
- DeleteDC(dcBmp);
- //choose the font
- //CFont m_Font;
- HFONT m_Font; // = (HFONT)lParam;
- LOGFONT* m_pLF;
- m_pLF=(LOGFONT*)calloc(1,sizeof(LOGFONT));
- HFONT hFont = CreateFont (13, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET,
- OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
- DEFAULT_PITCH | FF_DONTCARE, TEXT("Tahoma"));
- //Set text position;
- RECT pos = {40,40,50,50};
- //draw the text
- HDC dcBmp2=CreateCompatibleDC(TmpDC);
- SetTextColor(dcBmp2,RGB(0,255,0));
- SetBkMode(dcBmp2, TRANSPARENT);
- SetBkColor(dcBmp2,RGB(0,0,255));
- //SetBkMode(TRANSPARENT);
- DrawTextW(dcBmp2,(LPCWSTR)"TestTestTestTestTestTestTestTestTestTestTest",4,&pos,DT_CALCRECT);
- DrawTextW(dcBmp2,(LPCWSTR)"TestTestTestTestTestTestTestTestTestTestTest",4,&pos,0);
- //cleanup
- free(m_pLF);
- DeleteDC(dcBmp2);
I tried various adjustments. I studied what the debugger said. I am getting overwhelmed by this. Would you please help me to get this to work?
Thank you.
In case you want more to see what I have: This is my entire program. It currently shows some red text on a bitmap that I have used to create a custom region. That works. But, I want to be able to use that and bitblt the blank bmp background out of it and just leave the text for my program to show. My intent is to have just the text showing with a transparent background. I want to make this dynamically. NOT in some image editor. I want to be able to show a changing text. That is where I am going with this. Help! Please!
Expand|Select|Wrap|Line Numbers
- // BitmapToCustomShapedRegion.cpp
- #define _UNICODE
- #define UNICODE
- #define STRICT // Require more care in declaring and using types.
- #include <windows.h>
- #include <string> // for std::char_traits
- //#include <iostream> // std::cout
- #include <algorithm> // std::min
- // Globals
- TCHAR szClassName[] = L"WIN32TEST";
- HWND Handle_of_MainWindow;
- HDC HDC_of_MainWindow;
- HINSTANCE MainWindow_hInstance;
- // Function prototypes with default arguments
- HBITMAP hMainWindowBitmapForRegion;
- BITMAPINFOHEADER RGB32BITSBITMAPINFO;
- #include "resource.h"
- #include "bitmap_to_region.h"
- #include "callback_winproc_main.h"
- //#include "ShObjIdl.h"
- int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
- {
- // Parameters being set but maybe not being used
- HINSTANCE hNotUsing001;
- hNotUsing001 = hPrevInstance;
- hPrevInstance = hNotUsing001;
- LPSTR lpNotUsing002;
- lpNotUsing002 = lpCmdLine;
- lpCmdLine = lpNotUsing002;
- // Parameters being set and being used
- WNDCLASS wc;
- HWND hWnd;
- MSG msg;
- // HBITMAP hMainWindowBitmapForRegion;
- hMainWindowBitmapForRegion = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_BITMAP1), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
- HWND HWND_of_TestBitmap_001= (HWND)hMainWindowBitmapForRegion;
- if (hMainWindowBitmapForRegion)
- {
- ZeroMemory(&wc, sizeof(wc));
- wc.style = CS_HREDRAW | CS_VREDRAW;
- wc.lpszClassName = szClassName;
- wc.lpfnWndProc = (WNDPROC)WndProc_for_main;
- wc.hInstance = hInstance;
- if (RegisterClass(&wc))
- {
- BITMAP bm;
- GetObject(hMainWindowBitmapForRegion, sizeof(bm), &bm);
- // For Agents
- //hWnd = CreateWindow(szClassName, NULL, WS_POPUP, 100, 10, bm.bmWidth, bm.bmHeight, NULL, NULL, hInstance, NULL);
- // For Anti-Agents
- hWnd = CreateWindow(szClassName, NULL, WS_POPUP, 650, 10, bm.bmWidth, bm.bmHeight, NULL, NULL, hInstance, NULL);
- /// test..........START
- HBITMAP hbitmap = hMainWindowBitmapForRegion;
- //BITMAP bm;
- GetObject( hbitmap, sizeof(BITMAP), &bm );
- long width=bm.bmWidth;
- long height=bm.bmHeight;
- //prepare the bitmap attributes
- BITMAPINFO bmInfo;
- memset(&bmInfo.bmiHeader,0,sizeof(BITMAPINFOHEADER));
- bmInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
- bmInfo.bmiHeader.biWidth=width;
- bmInfo.bmiHeader.biHeight=height;
- bmInfo.bmiHeader.biPlanes=1;
- bmInfo.bmiHeader.biBitCount=24;
- //create a temporary dc in memory.
- HDC pDC = ::GetDC(0);
- HDC TmpDC=CreateCompatibleDC(pDC);
- //create a new bitmap and select it in the memory dc
- BYTE *pbase;
- HBITMAP TmpBmp=CreateDIBSection(pDC,
- &bmInfo,DIB_RGB_COLORS,(void**)&pbase,0,0);
- HGDIOBJ TmpObj=SelectObject(TmpDC,TmpBmp);
- //draw the background
- HDC dcBmp=CreateCompatibleDC(TmpDC);
- HGDIOBJ TmpObj2 = SelectObject(dcBmp,hbitmap);
- BitBlt(TmpDC,0,0,width,height,dcBmp,0,0,SRCCOPY);
- SelectObject(TmpDC,TmpObj2);
- DeleteDC(dcBmp);
- //choose the font
- HFONT m_Font;
- LOGFONT* m_pLF;
- m_pLF=(LOGFONT*)calloc(1,sizeof(LOGFONT));
- HFONT hFont = CreateFont (13, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET,
- OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
- DEFAULT_PITCH | FF_DONTCARE, TEXT("Tahoma"));
- //Set text position;
- RECT pos = {40,40,50,50};
- //draw the text
- HDC dcBmp2=CreateCompatibleDC(TmpDC);
- SetTextColor(dcBmp2,RGB(0,255,0));
- SetBkMode(dcBmp2, TRANSPARENT);
- SetBkColor(dcBmp2,RGB(0,0,255));
- //SetBkMode(TRANSPARENT);
- DrawTextW(dcBmp2,(LPCWSTR)"TestTestTestTestTestTestTestTestTestTestTest",4,&pos,DT_CALCRECT);
- DrawTextW(dcBmp2,(LPCWSTR)"TestTestTestTestTestTestTestTestTestTestTest",4,&pos,0);
- //cleanup
- free(m_pLF);
- DeleteDC(dcBmp2);
- /// test..........END
- if (hWnd)
- {
- Handle_of_MainWindow = hWnd; // Using this for closing the program.
- HDC_of_MainWindow = GetDC( Handle_of_MainWindow );
- MainWindow_hInstance = hInstance;
- HRGN hBtRgn = BitmapToRegion(hMainWindowBitmapForRegion);
- if (hBtRgn)
- {
- SetWindowRgn(hWnd, hBtRgn, TRUE);
- }
- ShowWindow(hWnd, nCmdShow);
- UpdateWindow(hWnd);
- // Main message loop:
- while (GetMessage(&msg, nullptr, 0, 0))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- return (msg.wParam);
- }
- }
- }
- return 0; // successfully executed.
- // The return value is the exit code of your program, the shell
- // (or any other application that ran it) can read and use it.
- // nonzero indicates a failure of some kind.
- // return 1; // executed but some error may have occured.
- // return -1; // unexpected error may have occured.
- }
And then:
Expand|Select|Wrap|Line Numbers
- // bitmap_to_region.h
- //
- // BitmapToRegion : Create a region from the "non-transparent" pixels of a bitmap
- // Author : Jean-Edouard Lachand-Robert (http://www.geocities.com/Paris/LeftBank/1160/resume.htm), June 1998.
- //
- // hMainWindowBitmapForRegion : Handle of a source bitmap
- // cTransparentColor : Color base for the "transparent" pixels (default is black)
- // cTolerance : Color tolerance for the "transparent" pixels.
- //
- // A pixel is assumed to be transparent if the value of each of its 3 components (blue, green and red) is
- // greater or equal to the corresponding value in cTransparentColor and is lower or equal to the
- // corresponding value in cTransparentColor + cTolerance.
- //
- COLORREF cTransparentColor = RGB(254, 243, 222); // Used as Blue Green Red
- COLORREF cTolerance = 0x000000;
- // Previous declaration
- HRGN BitmapToRegion (HBITMAP hReceivedBitmap);
- HRGN BitmapToRegion (HBITMAP hReceivedBitmap)
- {
- HRGN hRgn = NULL;
- if (hReceivedBitmap)
- {
- // Create a memory DC inside which we will scan the bitmap content
- HDC hMemDC = CreateCompatibleDC(nullptr);
- if (hMemDC)
- {
- // Get bitmap size
- BITMAP bm;
- GetObject(hReceivedBitmap, sizeof(bm), &bm);
- // Create a 32 bits depth bitmap and select it into the memory DC
- //BITMAPINFOHEADER RGB32BITSBITMAPINFO;
- RGB32BITSBITMAPINFO = {
- sizeof(BITMAPINFOHEADER), // biSize
- bm.bmWidth, // biWidth;
- bm.bmHeight, // biHeight;
- 1, // biPlanes;
- 32, // biBitCount
- BI_RGB, // biCompression;
- 0, // biSizeImage;
- 0, // biXPelsPerMeter;
- 0, // biYPelsPerMeter;
- 0, // biClrUsed;
- 0 // biClrImportant;
- };
- // VOID * pbits32;
- // HBITMAP hbm32 = CreateDIBSection(hMemDC, (BITMAPINFO *)&RGB32BITSBITMAPINFO, DIB_RGB_COLORS, &pbits32, nullptr, 0);
- HBITMAP hbm32 = CreateDIBSection(hMemDC, (BITMAPINFO *)&RGB32BITSBITMAPINFO, DIB_RGB_COLORS, nullptr, nullptr, 0);
- if (hbm32)
- {
- HBITMAP holdBmp = (HBITMAP)SelectObject(hMemDC, hbm32);
- // Create a DC just to copy the bitmap into the memory DC
- HDC hDC = CreateCompatibleDC(hMemDC);
- if (hDC)
- {
- // Get how many bytes per row we have for the bitmap bits (rounded up to 32 bits)
- BITMAP bm32;
- GetObject(hbm32, sizeof(bm32), &bm32);
- while (bm32.bmWidthBytes % 4)
- bm32.bmWidthBytes++;
- // Copy the bitmap into the memory DC
- holdBmp = (HBITMAP)SelectObject(hDC, hReceivedBitmap);
- BitBlt(hMemDC, 0, 0, bm.bmWidth, bm.bmHeight, hDC, 0, 0, SRCCOPY);
- // For better performances, we will use the ExtCreateRegion() function to create the
- // region. This function take a RGNDATA structure on entry. We will add rectangles by
- // amount of ALLOC_UNIT number in this structure.
- #define ALLOC_UNIT 1000
- DWORD maxRects = ALLOC_UNIT;
- HANDLE hData = GlobalAlloc(GMEM_MOVEABLE, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects));
- RGNDATA *pData = (RGNDATA *)GlobalLock(hData);
- pData->rdh.dwSize = sizeof(RGNDATAHEADER);
- pData->rdh.iType = RDH_RECTANGLES;
- pData->rdh.nCount = pData->rdh.nRgnSize = 0;
- SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
- // Keep on hand highest and lowest values for the "transparent" pixels
- BYTE lr = GetRValue(cTransparentColor);
- BYTE lg = GetGValue(cTransparentColor);
- BYTE lb = GetBValue(cTransparentColor);
- BYTE hr = std::min(0xff, lr + GetRValue(cTolerance));
- BYTE hg = std::min(0xff, lg + GetGValue(cTolerance));
- BYTE hb = std::min(0xff, lb + GetBValue(cTolerance));
- // Scan each bitmap row from bottom to top (the bitmap is inverted vertically)
- BYTE *p32 = (BYTE *)bm32.bmBits + (bm32.bmHeight - 1) * bm32.bmWidthBytes;
- for (int y = 0; y < bm.bmHeight; y++)
- {
- // Scan each bitmap pixel from left to right
- for (int x = 0; x < bm.bmWidth; x++)
- {
- // Search for a continuous range of "non transparent pixels"
- int x0 = x;
- LONG *p = (LONG *)p32 + x;
- while (x < bm.bmWidth)
- {
- BYTE b = GetRValue(*p);
- if (b >= lr && b <= hr)
- {
- b = GetGValue(*p);
- if (b >= lg && b <= hg)
- {
- b = GetBValue(*p);
- if (b >= lb && b <= hb)
- {
- // This pixel is "transparent"
- break;
- }
- }
- }
- p++;
- x++;
- }
- if (x > x0)
- {
- // Add the pixels (x0, y) to (x, y+1) as a new rectangle in the region
- if (pData->rdh.nCount >= maxRects)
- {
- GlobalUnlock(hData);
- maxRects += ALLOC_UNIT;
- hData = GlobalReAlloc(hData, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), GMEM_MOVEABLE);
- pData = (RGNDATA *)GlobalLock(hData);
- }
- RECT *pr = (RECT *)&pData->Buffer;
- SetRect(&pr[pData->rdh.nCount], x0, y, x, y+1);
- if (x0 < pData->rdh.rcBound.left)
- {
- pData->rdh.rcBound.left = x0;
- }
- if (y < pData->rdh.rcBound.top)
- {
- pData->rdh.rcBound.top = y;
- }
- if (x > pData->rdh.rcBound.right)
- {
- pData->rdh.rcBound.right = x;
- }
- if (y+1 > pData->rdh.rcBound.bottom)
- {
- pData->rdh.rcBound.bottom = y+1;
- }
- pData->rdh.nCount++;
- // On Windows 98, ExtCreateRegion() may fail if the number of rectangles is too
- // large (ie: > 4000). Therefore, we have to create the region by multiple steps.
- if (pData->rdh.nCount == 2000)
- {
- HRGN h = ExtCreateRegion(nullptr, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), pData);
- if (hRgn)
- {
- CombineRgn(hRgn, hRgn, h, RGN_OR);
- DeleteObject(h);
- }
- else
- {
- hRgn = h;
- pData->rdh.nCount = 0;
- SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
- }
- }
- }
- }
- // Go to next row (remember, the bitmap is inverted vertically)
- p32 -= bm32.bmWidthBytes;
- }
- // Create or extend the region with the remaining rectangles
- HRGN h = ExtCreateRegion(nullptr, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), pData);
- if (hRgn)
- {
- CombineRgn(hRgn, hRgn, h, RGN_OR);
- DeleteObject(h);
- }
- else
- {
- hRgn = h;
- }
- // Clean up
- SelectObject(hDC, holdBmp);
- DeleteDC(hDC);
- }
- DeleteObject(SelectObject(hMemDC, holdBmp));
- }
- DeleteDC(hMemDC);
- }
- }
- return hRgn;
- }
And then more:
Expand|Select|Wrap|Line Numbers
- // callback_winproc_main.h
- ///
- // Previous declaration
- LRESULT CALLBACK WndProc_for_main(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
- LRESULT CALLBACK WndProc_for_main(
- HWND hWnd, // A handle to the window procedure to receive the message.
- UINT message, // The message.
- WPARAM wParam, // Additional message-specific information. The contents of this parameter depend on the value of the Msg parameter.
- LPARAM lParam // Additional message-specific information. The contents of this parameter depend on the value of the Msg parameter.
- )
- // The return value specifies the result of the message processing and depends on the message sent.
- // WNDPROC is either the address of a window or dialog box procedure,
- // or a special internal value meaningful only to CallWindowProc.
- {
- PAINTSTRUCT ps;
- HDC hdc;
- switch (message)
- {
- case WM_NCHITTEST:
- {
- return HTCAPTION;
- }
- case WM_LBUTTONDOWN:
- {
- break;
- }
- case WM_PAINT:
- {
- hdc = BeginPaint (hWnd, &ps);
- if (hMainWindowBitmapForRegion)
- {
- BITMAP bm;
- GetObject(hMainWindowBitmapForRegion, sizeof(bm), &bm);
- HDC memdc = CreateCompatibleDC(nullptr);
- HBITMAP h = (HBITMAP)SelectObject(memdc, hMainWindowBitmapForRegion);
- BitBlt(hdc, 0, 0, bm.bmWidth, bm.bmHeight, memdc, 0, 0, SRCCOPY);
- SelectObject(memdc, h);
- }
- /// THIS WORKS !
- /// Text to the bitmap START
- HDC hMemDC = CreateCompatibleDC(nullptr);
- HBITMAP hbm32 = CreateDIBSection(hMemDC, (BITMAPINFO *)&RGB32BITSBITMAPINFO, DIB_RGB_COLORS, nullptr, nullptr, 0);
- HBITMAP holdBmp = (HBITMAP)SelectObject(hMemDC, hbm32);
- SelectObject(hdc, (HGDIOBJ) holdBmp);
- HINSTANCE hInstance_of_TestBitmap_001 = GetModuleHandleW(L"Anti-Agent_Belinda.bmp");
- LPCWSTR SomeLText = L"1 2 3 4 5 6 7 8 9 0 a b c d e f g h i j k l m n o p q r s t u v w x y z";
- int LengthOfSomeLText = std::char_traits<wchar_t>::length (SomeLText);
- SetTextColor(hdc,RGB(255,0,0));
- SetBkMode(hdc, TRANSPARENT);
- SetBkColor(hdc,RGB(0,255,0));
- for (int i = 0; i < 10; i++)
- {
- TextOutW ( hdc, 10, (i * 15), SomeLText, LengthOfSomeLText );
- }
- /// Text to the bitmap END
- EndPaint (hWnd, &ps);
- break;
- }
- case WM_KEYDOWN:
- {
- if (wParam != VK_ESCAPE)
- {
- break;
- }
- }
- case WM_DESTROY:
- {
- PostQuitMessage(0);
- break;
- }
- default:
- {
- return (DefWindowProc(hWnd, message, wParam, lParam));
- }
- }
- return (0);
- }
Also:
Expand|Select|Wrap|Line Numbers
- // resource.h
- #define IDB_BITMAP1 101
And last:
Expand|Select|Wrap|Line Numbers
- // resource.rc
- #include "resource.h"
- // The DISCARDABLE keyword is ignored for 32-bit Windows, but remains for compatibility.
- IDB_BITMAP1 BITMAP "Blank_single_color.bmp" // To have a background that I can remove later.
- #define SUBLANG_NEUTRAL 0x00 // This was in winnt.h which seems to be called by afxres.h
- // I do not need all of that shit for just this one line.
- // I am getting tired of stripping vast amounts of Visual Studio
- // crap from examples just to get to the line or lines that I need.
- LANGUAGE 0, SUBLANG_NEUTRAL
Oh, the picture that I am working on: It is local and I did not get it to upload to here. Just pick a bmp and use it yourself.