Aug 132012
 

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!

 Posted by at 11:31:10
Aug 132011
 

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.

 Posted by at 22:27:14
Jul 062011
 

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!

 Posted by at 23:01:59
%d bloggers like this: