Link to home
Start Free TrialLog in
Avatar of rossryan
rossryan

asked on

Bitmaps, from handles (HBitmap, Hbmp)

Aright, I need sample code for this, as I am through beating my head against the wall, and not getting it.

Background: I'm injecting a Paint Hook dll into a process, to grab the window before it is scaled.

What I need:
Working, unmanaged, C++ code that can create a Bitmap. I do not care what kind, because it is going into C# land, I can manipulate it from there.

Here a portion of the code :

HBITMAP hBmp = NULL;

    {
        HDC hDC = GetDC(hWnd);
        hBmp = CreateCompatibleBitmap(hDC, rect.right - rect.left, rect.bottom - rect.top);
        ReleaseDC(hWnd, hDC);
    }
      hOld = SelectObject(hDCMem, hBmp);

I need a bitmap created from hBmp. And this code is going into a DLL.

I want headers, prototypes, whatever, give it all to me as long as it works.
Avatar of Daniel Junges
Daniel Junges
Flag of Brazil image



HDC hDC = GetDC(hWnd);

CBitmap hBmp;
BOOL result = hBmp.CreateCompatibleBitmap(hDC, rect.right - rect.left, rect.bottom - rect.top);

ASKER CERTIFIED SOLUTION
Avatar of AlexFM
AlexFM

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of rossryan
rossryan

ASKER

Hmm, DIB. Very nice. On a previous discussion, things were getting out of hand (first we start up GDI+, then make the image, then shut it down...pain).

I'm going to merge this code with what I have after work.
//CPP
HWND hWnd = NULL;
HBITMAP hBmp = NULL;
HGDIOBJ hOld = NULL;
HDC hDCMem = NULL;
HANDLE hMap = NULL;
SapphireData* SapphireData;
HANDLE hSapphireData = NULL;
void* SapphireDataMap = NULL;
CPaintHook hook;




void HookWindow2(HWND hWnd)
{
      
      hMap = CreateFileMapping(INVALID_HANDLE_VALUE,    // current file handle
    NULL,                              // default security
    PAGE_READWRITE,                    // read/write permission
    0,                                 // max. object size
    0,                                 // size of hFile
    "SapphireFSwap");            // name of mapping object


      if (hMap != NULL && GetLastError() == ERROR_ALREADY_EXISTS)
      {
    CloseHandle(hMap);
    hMap = NULL;
      }

      
      if (hMap != NULL)
      {
    CloseHandle(hMap);
    hMap = NULL;
      }
      SapphireDataMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, false, "SapphireFSwap");

      if (SapphireDataMap != NULL)
      {
      hSapphireData = MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
      }
   
      if (hSapphireData != NULL)
      {
            SapphireData = (struct SapphireData*)hSapphireData;
      }
      

      

      
   

    hook.SubClass(hWnd);


    hDCMem = CreateCompatibleDC(NULL);

    RECT rect;

    GetWindowRect(hWnd, & rect);

    hBmp = NULL;

    {
        HDC hDC = GetDC(hWnd);
        hBmp = CreateCompatibleBitmap(hDC, rect.right - rect.left, rect.bottom - rect.top);
        ReleaseDC(hWnd, hDC);
    }
      hOld = SelectObject(hDCMem, hBmp);

}

void UpdateWindow2()
{  
      GdiplusStartupInput gdiplusStartupInput;
      ULONG_PTR gdiplusToken;
      GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
      SendMessage(hWnd, WM_PRINT, (WPARAM) hDCMem, PRF_CHILDREN | PRF_CLIENT | PRF_ERASEBKGND | PRF_NONCLIENT | PRF_OWNED);
      SapphireData->SapphireSwap = Bitmap::FromHBITMAP(hBmp);
      //delete image;
    GdiplusShutdown(gdiplusToken);
    return 0;

}

void DestroyWindow2()
{

      
 

      SelectObject(hDCMem, hOld);
    DeleteObject(hDCMem);

      /*
    OpenClipboard(hWnd);
 
    EmptyClipboard();
    SetClipboardData(CF_BITMAP, hBmp);
    CloseClipboard();
      */

      if (hSapphireData)
      {
    UnmapViewOfFile(hSapphireData);
    SapphireData = NULL;
      }
      CloseHandle(SapphireDataMap);

}

//H
struct SapphireData
{
CBitmap SapphireSwap;
};





void CaptureWindow(HWND hWnd);
void HookWindow2(HWND hWnd);
void UpdateWindow2();
void DestroyWindow2();



Hmm. Aright, how do I redefine the above struct to carry the bits (or a full bitmap) into shared memory?


CreateBMP(BYTE* pBits, int nWidth, int nHeight)

Hmm. I have a handle to a bitmap (hBmp), not the bits, so, I'll probably have to lock memory to get them. Width and Height I can grab from getClientRect.
I've got one other question for you Alex (not code related). I've told you about Sapphire, do you think it's pointless?

I mean, I've studied MS Task Gallery, Sun's Project Looking Glass, 3DOsX, 3DTop, 3DWM, LiteStep...the list goes on. I've looked at their interfaces, compared what I think are the best parts, considered whether they are relevant or a dead end.

What do you think?
I don't know nothing about Sapphire, so I cannot help here.

About your code:

hBmp = CreateCompatibleBitmap(hDC, rect.right - rect.left, rect.bottom - rect.top);

Replace this with lines:

    LPBITMAPINFO lpbi;

    ...

    delete[] lpbi;

By this way you have DIB instead of DDB. Lines from my code:

    HDC hDC = CreateCompatibleDC(NULL);

    ...

    TextOut(hDC, 20, 20, "Hello", (int)strlen("Hello"));

are used to fill bitmap, you have your own code for this. Line:

   GetBitmapBits(hBitmap, ImageSize, pBits);

write bitmap bits to buffer supplied by called. Instead of this write bitmap bits to memory mapped file.