Our website is made possible by displaying online advertisements to our visitors. Please consider supporting us by whitelisting our website.

large

Load a HBITMAP into SFML sf::Image container

I have been working on a SFML project for quite some time.
This project are hookup up with existing Win32 coded stuff, so I had to handle HBITMAP.

After hours of searching and trial&error, I got this solution.
The LoadFromMemory-part didn’t work so well, so I decided to get pixels.
It works for me, but should have more checks, use at own risk.


//////////////////////////////////////////////////////////////////////////
// Function created by: Lars Werner - http://lars.werner.no
//////////////////////////////////////////////////////////////////////////
// Inputs: [in] HBITMAP hBitmap = A HBITMAP handle
// [out] sf::Image *pPicture = A image in SFML as pointer
//
//////////////////////////////////////////////////////////////////////////
// Return: True if loaded, False if not!
// The pPicture is the variable set and to be used further on
//////////////////////////////////////////////////////////////////////////
// Version: 1.0 = Inital Release
//////////////////////////////////////////////////////////////////////////
bool SFMLLoadHBitmapAsImage(HBITMAP hBitmap, sf::Image *pPicture)
{
//Create a DC to get hBitmap information
HDC hDC = GetDC( ::GetDesktopWindow() );

//Create BITMAPINFO variable, set size
BITMAPINFO MyBMInfo = {0};
MyBMInfo.bmiHeader.biSize = sizeof( MyBMInfo.bmiHeader );

//Get the BITMAPINFO structure from the bitmap
if( 0 == GetDIBits(hDC, hBitmap, 0, 0, NULL, &MyBMInfo, DIB_RGB_COLORS))
{
// error handling
return false;
}

//Create the bitmap pixel array each element is [b,g,r]
BYTE* lpPixels = new BYTE[MyBMInfo.bmiHeader.biSizeImage];

//Setting up the structure of the buffer to be received
MyBMInfo.bmiHeader.biCompression = BI_RGB; // No-compression

//Now get the actual data from the picture
if (0 == GetDIBits(hDC, hBitmap, 0, MyBMInfo.bmiHeader.biHeight, (LPVOID)lpPixels, &MyBMInfo, DIB_RGB_COLORS))
{
// error handling
return false;
}

//Now create an array of SFML pixels we want to fill
sf::Uint8 *lpPixelWithAlpha = new sf::Uint8[ MyBMInfo.bmiHeader.biSizeImage + (MyBMInfo.bmiHeader.biSizeImage/3)/3 ]; //Add room for alpha

//Loop through each pixel, with steps of four RGBA!
for(int x=0;xLoadFromPixels(MyBMInfo.bmiHeader.biWidth, MyBMInfo.bmiHeader.biHeight, lpPixelWithAlpha))
{
// error handling
return false;
}

//Remove the pixels with alphachannel
delete[] lpPixelWithAlpha;

//Release the DC
ReleaseDC(::GetDesktopWindow(), hDC);

//Notify ok!
return true;
}

//Create a container for the picture
sf::Image m_mypicture;

//Get a HBITMAP (see function from before)
HBITMAP hBitmap = ScreenShot( http://lars.werner.no/?p=627 <--- function and parameters here ); //Run the function if( false == SFMLLoadHBitmapAsImage(hBitmap, &my_picture) ) { // error handling } //Load your image into the sprite sf::Sprite m_mysprite.SetImage(m_mypicture); //The DIB section begins with the last pixels at the beginning. //Since SFML have flip-functions I didn't care to fix it :) m_mysprite.FlipY(true);

Any comments, errors or bad design, please let me know in the comment section!

Take a screenshot of any given HWND!

Currently I’m working on a project that uses screenshots, and I just wanted to share this snippet.

//////////////////////////////////////////////////////////////////////////
// Function created by: Lars Werner - http://lars.werner.no
//////////////////////////////////////////////////////////////////////////
// Inputs: HWND hParent = the window we want to get DC from, eg
// ::GetDesktopWindow();
// int x = x-position of the screen
// int y = y-position of the screen
// int nWidth = Width of the screenshot
// int nHeight = Height of the screenshot
//
//////////////////////////////////////////////////////////////////////////
// Return: HBITMAP = Handle isn't deleted in function, please use
// DeleteObject() when finished with object!
//////////////////////////////////////////////////////////////////////////
// Version: 1.0 = Inital Release
//////////////////////////////////////////////////////////////////////////
HBITMAP ScreenShot(HWND hParent, int x, int y, int nWidth, int nHeight)
{
//Get a DC from the parent window
HDC hDC = GetDC(hParent);

//Create a memory DC to store the picture to
HDC hMemDC = CreateCompatibleDC(hDC);

//Create the actual picture
HBITMAP hBackground = CreateCompatibleBitmap(hDC, nWidth, nHeight );

//Select the object and store what we got back
HBITMAP hOld = (HBITMAP)SelectObject(hMemDC, hBackground);

//Now do the actually painting into the MemDC (result will be in the selected object)
//Note: We ask to return on 0,0,Width,Height and take a blit from x,y
BitBlt(hMemDC, 0, 0, nWidth, nHeight, hDC, x, y, SRCCOPY);

//Restore the old bitmap (if any)
SelectObject(hMemDC, hOld);

//Release the DCs we created
ReleaseDC(hParent, hMemDC);
ReleaseDC(hParent, hDC);

//Return the picture (not a clean method, but you get the drill)
return hBackground;
}

Any comments, error or bad design, please let me know in the comments!

Acrobat MDI – ish v0.5.0.1 released!

What is this?
Acrobat MDIish is a wrapper that snatch all of you Acrobat windows and present them into a single window.
A quick and dirty way to get MDI support back! 🙂

Download
Please download Acrobat MDI-ish from this page

Screenshot

Features
* Gets the MDI feature back to your Acrobat!
* Multimonitor support with MDI!
* Systray control so you can easily show/hide windows
* Multiple looks on the frame; Windows 2000/XP, Office 2003 / 2007