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

Programming

Tips & trixs for the C++ fangroup, mainly Win32 and some MFC.

New article published: Load keyboard-dlls in a 64-bit enviroment

I have been working on a OnScreenkeyboard for a while, and I wanted to use the available resources for a easy multilingual system.

In windows there are kbd**.dll-files that contain arrays of scan codes, virtual keys and characters linked to VK/SC. To avoid inventing the wheel again, I tried to use these.

My developer computer is a Win7-x64, and I have a VM running WinXP (32-bit) on it.
I created a 32-bit application, with default MFC-configuration.
I noticed that the pVkToWcharTable is NULL on the 64-bit machine and not NULL on the 32-bit machine after running the init KbdLayerDescriptor(). This occurred even if they loaded the same 32-bit-dll.

I tried several solutions, but all of them required to compile one 32-bit and one 64-bit version of the program. That wasn’t a satisfying solution for me, so I created a wrapper to handle such special events.

Read the article Load and init keyboard-dlls in a 64-bit enviroment (KbdLayerDescriptor), to read and download my example from the picture above.

If there are other clever souls out there who have a better way of doing it, please let me know!

Hide, minimize or maximize your CFrameWndEx based window at start (MFC 10.0 tip)

After changing to Visual Studio 2010 many of my old ways of doing things didn’t work well anymore.

Recently I had a “SDI” (not really SDI since it doesn’t use the Doc/View way) that needed to be minimized @ startup.
My good old way used the ActivateFrame(int nCmdShow) and setting to SW_HIDE / SW_MINIMIZE / SW_MAXIMIZE didn’t work at all.
(The “SDI” uses the new visual styles, so I guess we don’t have full control over the ShowWindow() being called)

First in your MainFrm.h file, add this:

class CMainFrame : public CFrameWndEx
{
//(...)
public:
BOOL bIsHidden;
//(...)
};

Then in the MainFrm.cpp

// CMainFrame construction/destruction
CMainFrame::CMainFrame()
{
// TODO: add member initialization code here
bIsHidden = TRUE;
}

//This is where you block the window for showing
void CMainFrame::OnWindowPosChanging(WINDOWPOS* lpwndpos)
{
CFrameWndEx::OnWindowPosChanging(lpwndpos);

//When hidden we remove all the showwindow parameters (giving you the power back)
if(bIsHidden)
lpwndpos->flags &= ~SWP_SHOWWINDOW ;
}

Finally in your CWinAppEx derivated class

BOOL CAcrobatMDIishApp::InitInstance()
{
//(...)
pFrame->LoadFrame(IDR_MAINFRAME,
WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, NULL,
NULL);

// The one and only window has been initialized, minimize it (or maximize it).
pFrame->ShowWindow(SW_MINIMIZE); //Comment these two out to keep the windows hidden (like a hide to systray function for instance)
pFrame->UpdateWindow();
}

It is a simple way to control the visibilty of “SDI”/”MDI” application based on the CFrameWndEx and CWinAppEx classes.

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!