Archive for May, 2008

How to find the application associated with particular file extension.

0


Did you ever noticed that, While starting up some media player applications, they says that - “Some of its proprietary file formats are not associated with it and do you want to associate now?”. How these application are checking the associated application of particular filetype?


For a given file extension, you can find the executable associated with it by calling the api – AssocQueryString(). See the sample code snippet below.

#include "Shlwapi.h"
...
DWORD dwSize = MAX_PATH;
TCHAR tchApplicationPath[ MAX_PATH ] = { 0 };
HRESULT hr = AssocQueryString( 0,
                               ASSOCSTR_EXECUTABLE,
                               _T( ".mp3" ),
                               _T( "open" ),
                              tchApplicationPath,
                              &dwSize );

if( FAILED( hr ))
{
    // Failed to get the associated application.
}


So next time while starting, check whether your file formats are associated with your appliaction itself. ;) BTW, don’t forget to add Shlwapi.lib to your project settings.


Targeted Audience – Beginners.

Stringizing Operator, Charizing Operator and Token pasting operator.

0


What ever C++ best practices says, its a bit tough to eliminate macros. Especially in extensible frameworks. The best example is MFC. Indeed macros have drawbacks, but its the best wepon to inject code inside client classes which uses the framework.

For instance, the MFC message map itself. The message map support is provided by three macros – DECLARE_MESSAGE_MAP(), BEGIN_MESSAGE_MAP() and END_MESSAGE_MAP(). These macros declare static message map array and some utility functions to class. Indeed, the user is free from all those complications and everything are buried deep inside these macros .

There are some helpful operators which helps you to write powerful marcos. They are #, #@ and ##.


Stringizing Operator( # )
As name says – Stringizing Operator converts the macro parameter to a string. if # is prefixed before the parameter name, and used in the macro body, that parameter will get enclosed in double quotes. For instance see the following macro used for showing messagebox. The message – CDialogDlg::OnButton will get expanded to “CDialogDlg::OnButton”

MESSAGE_BOX( CDialogDlg::OnButton );
...
// The macro which shows Message.
#define MESSAGE_BOX( Message ) \
{\
    AfxMessageBox( _T( #Message )); \
}

if you want to see a real world example, check the following line from DAOCORE.CPP of MFC. A DAO trace macro.

DAO_TRACE(m_pDAODatabase->Close());
...
#define DAO_TRACE(f) AfxDaoTrace(f, #f, THIS_FILE, __LINE__)

Charizing Operator( #@ )
The Charizing operator is used to convert a macro parameter to a charector constant. If its prefixed in macro parameter, the parameter get enclosed in single quotes to form a char constant. For instance see the e.g. below. Its taken from MSDN.

// Same as a = 'b';
char a = MAKECHAR( b );
...
#define MAKECHAR( x )  #@x

Token-Pasting Operator (##)
Its also known as “Merging operator”. If its prefixed in macro parameter, that token just get pasted for each occurance. The best example is _T() macro. See its definition below.

// Assume unicode is defined.
// This will expand to csString = L"Hello";
CString csString = _T( "Hello" );
...
#define _T(x)       __T(x)
#define __T(x)      L ## x

Here the ##x pasts the token directly there. See one more example to see the power of token pasting operator. It can also be used to give unique names to the member variables in the injected code. See the definition of DECLARE_DYNAMIC() macro. Here the class name is pasted to generate unique name for the member variable injected.

#define DECLARE_DYNAMIC(class_name) \
protected: \
    static CRuntimeClass* PASCAL _GetBaseClass(); \
public: \
    static const AFX_DATA CRuntimeClass class##class_name; \
    virtual CRuntimeClass* GetRuntimeClass() const; \


But still keep in mind that macros are twin side sharp swords. If not properly used, … ;)


Targeted Audience – Intermediate.

How to convert local system time to UTC or GMT.

2


In Messengers did you notice that the time stamp will be expressed in UTC or GMT. UTC stands for Universal Coordinated Time and GMT stands for Greenwich Mean Time and both are same. Since the users engaged in chat can be from across world, this one is really helpful to understand the real time. If they are expressed in local time, it can result in confusion.

For instance, User1 says – “Login to chat by 13:00″. It can be his local time and 13:00 for user2 might be a different time according to his timezone. And think what will happen? :) UTC or GMT is very much useful if you communicate about time across world. But how can you convert your local system time to UTC or GMT?


First you’ve to get your timezone information by calling – GetTimeZoneInformation(). Then get the local time by calling – GetSystemTime() and translate it to UMT or GMT by calling – TzSpecificLocalTimeToSystemTime(). See the sample code snippet below.

// Get the local system time.
SYSTEMTIME LocalTime = { 0 };
GetSystemTime( &LocalTime );

// Get the timezone info.
TIME_ZONE_INFORMATION TimeZoneInfo;
GetTimeZoneInformation( &TimeZoneInfo );

// Convert local time to UTC.
SYSTEMTIME GmtTime = { 0 };
TzSpecificLocalTimeToSystemTime( &TimeZoneInfo,
                                 &LocalTime,
                                 &GmtTime );

// GMT = LocalTime + TimeZoneInfo.Bias
// TimeZoneInfo.Bias is the difference between local time
// and GMT in minutes.

// Local time expressed in terms of GMT bias.
float TimeZoneDifference = -( float(TimeZoneInfo.Bias) / 60 );
CString csLocalTimeInGmt;
csLocalTimeInGmt.Format( _T("%ld:%ld:%ld + %2.1f Hrs"),
                         GmtTime.wHour,
                         GmtTime.wMinute,
                         GmtTime.wSecond,
                         TimeZoneDifference );


Use SystemTimeToTzSpecificLocalTime() to convert UTC or GMT time back to your local timezone. You can also use UTC or GMT while logging messages. Anyway it all depends upto your needs. ;)


Targeted Audience – Beginners.

How to convert Image to Grayscale by using HLS colorspace?

0


Many image processing application provide functionality to convert images to gray scale. How they do it? There are many ways to convert an image to gray scale. The common method is to get the gray value of a pixel by the following equation

GrayValue = 0.3*Red + 0.59*Green + 0.11*Blue

There is another method to convert an image to grayscale – By using HLS colorspace. I’ve already explaned about HLS color space here -
http://weseetips.com/2008/05/22/convert-color-in-rgb-to-hls-and-vice-versa/

In the HLS color space, we can represent a pixel in Hue, luminosity and Saturation, where Saturation represents the colorfulness of the color or how colorful the color is. If the saturation goes to minimum, that color will become grayscale and if it goes to maximum the more fluorescent it will become.


1) Get each pixel in image in RGB.
2) Convert RGB to HLS and get the saturation.
3) Set saturation to 1 and convert back to RGB.
4) Set the new image pixel.

See the code snippet below. Please note that Its not an optimized one. Just to demonstrate the process.

// Create the image.
Bitmap ColorImage( csSourceImage );

// Get the size of image.
for( UINT x = 0; x < ColorImage.GetWidth(); ++x )
{
    for( UINT y = 0; y < ColorImage.GetHeight(); ++y )
    {
        // Get the pixel at x,y
        Color PixelColor;
        ColorImage.GetPixel( x, y, &PixelColor );

        // Convert it to COLORREF
        COLORREF RgbColor = PixelColor.ToCOLORREF();

        // Convert to HLS Color space
        WORD Hue = 0;
        WORD Luminance = 0;
        WORD Saturation = -100;
        ColorRGBToHLS( RgbColor, &Hue, &Luminance, &Saturation );

        // Set the saturation to 0 so that the
        // image will be greyscale.
        Saturation = 1;

        // Now re-generate HLS to RGB
        RgbColor = ColorHLSToRGB( Hue, Luminance, Saturation );

        // Convert back to Gdi+.
        PixelColor.SetFromCOLORREF( RgbColor );

        // Set it to image.
        ColorImage.SetPixel( x, y, PixelColor );
    }
}


Download sample project from here. The sample support only Jpeg images but can be easily extended.
http://jijoraj.110mb.com//samples/grayscaleconverter/GrayScaleConverter.zip
Please not that the GUI is not so much polished. ;)

As you think the first algorithm is more faster. But still HLS can be used and this is only one usage for HLS. The code snippet can be optimized further. But this is just for demo purpose. isn’t it? ;)


Targeted Audience – Intermediate.

copymessageboxcontents

Copy error string from MessageBox – More Easily.

1


While testing often we get error messages. While reporting bugs, what you’ll do? Read the MessageBox and type it in the bug description? There is a more easier method.


Just take the MessageBox and press Ctrl+C and the contents will be copied to the clipboard. For instance, if we press Ctrl+C for the following MessageBox,

Then then following message will be copied to the clipboard.

[Window Title]
Notepad

[Main Instruction]
Do you want to save changes to Untitled?

[Save] [Don't Save] [Cancel]

Now report the bugs fast and in detail. ;)


Targeted Audience – Beginners.

How to dump the call stack?

0


While debugging you can see the call stack at any time you wish by pressing Alt+7. But what to see the callstack when your executable is running without a debugger?


You can dump the call stack by calling – AfxDumpStack(). By default the output will be send by TRACE macro in debug build and if its release build, the output will be copied to the clipboard. You can specify the target destination to where the call stack information is to be copied. See the sample code snippet below.

// Dump the call stack.
AfxDumpStack( AFX_STACK_DUMP_TARGET_BOTH |
              AFX_STACK_DUMP_TARGET_ODS );

See the sample call stack dump[Taken from MSDN].

=== begin AfxDumpStack output ===

00427D55: DUMP2\DEBUG\DUMP2.EXE! void AfxDumpStack(unsigned long) + 181 bytes
0040160B: DUMP2\DEBUG\DUMP2.EXE! void CDump2Dlg::OnClipboard(void) + 14 bytes
BFF73663: WINDOWS\SYSTEM\KERNEL32.DLL! ThunkConnect32 + 2148 bytes
BFF928E0: WINDOWS\SYSTEM\KERNEL32.DLL! UTUnRegister + 2492 bytes

=== end AfxDumpStack() output ===

You might notice that Its not same as the Call stack that we see in Debugger. The syntax for each entry is as follows.

[Address]: [Module FileName ]           [FunctionName] + [Offset]
 BFF73663: WINDOWS\SYSTEM\KERNEL32.DLL! ThunkConnect32 + 2148 bytes


You can use the DebugView application to get the call stack when the executable is running standalone. Download it from http://technet.microsoft.com/en-us/sysinternals/bb896647.aspx.


Targeted Audience – Intermediate.

How to get the MAC address of your network adapter.

6


MAC address stands for Media Access Control address which is 6 bytes( 48 bits ) long. MAC address is the unique address which is used to identify network interface hardware. So how to get the MAC address of your network adapter?


You can use the function – GetAdaptersInfo(). The network adapter information will be populated and filled back in IP_ADAPTER_INFO structure. In that structure, you can get the network adapter name, MAC address and a couple of other information. See the sample code snippet.

#include "Iphlpapi.h"
...
// Get the buffer length required for IP_ADAPTER_INFO.
ULONG BufferLength = 0;
BYTE* pBuffer = 0;
if( ERROR_BUFFER_OVERFLOW == GetAdaptersInfo( 0, &BufferLength ))
{
    // Now the BufferLength contain the required buffer length.
    // Allocate necessary buffer.
    pBuffer = new BYTE[ BufferLength ];
}
else
{
    // Error occurred. handle it accordingly.
}

// Get the Adapter Information.
PIP_ADAPTER_INFO pAdapterInfo =
      reinterpret_cast<PIP_ADAPTER_INFO>(pBuffer);
GetAdaptersInfo( pAdapterInfo, &BufferLength );

// Iterate the network adapters and print their MAC address.
while( pAdapterInfo )
{
    // Assuming pAdapterInfo->AddressLength is 6.
    CString csMacAddress;
    csMacAddress.Format(_T("%02x:%02x:%02x:%02x:%02x:%02x"),
                        pAdapterInfo->Address[0],
                        pAdapterInfo->Address[1],
                        pAdapterInfo->Address[2],
                        pAdapterInfo->Address[3],
                        pAdapterInfo->Address[4],
                        pAdapterInfo->Address[5]);

    cout << "Adapter Name :" << pAdapterInfo->AdapterName << " "
         << "MAC :" << (LPCTSTR) csMacAddress << endl;

    // Get next adapter info.
    pAdapterInfo = pAdapterInfo->Next;
}

// deallocate the buffer.
delete[] pBuffer;


Don’t forget to add Iphlpapi.lib to project settings.


Targeted Audience – Beginners.

How to iterate child controls in your Dialog?

5


Assume you’ve a dialog with hundreds of child controls and you want to enable and disable them. Its not practical to get each control by control and disable them. Here iterating child controls comes to your help. Instead of getting control by control you can iterate all child controls of your dialog.


You can iterate the child windows by two methods -

1. Enumerate Child Windows
For enumeration you’ve to call the function – EnumChildWindows() by passing a callback function pointer. For each child window, the callback function will be called by passing child windows handle as parameter. See the sample code snippet.

// Enumerate Child Windows
EnumChildWindows( GetSafeHwnd(), EnumChildProc, 0 );
...

// For each child window, this callback will be called.
BOOL CALLBACK EnumChildProc( HWND hwnd, LPARAM lParam )
{
    // If you need hwnd, you can use it.
    // If you need the Control ID of child window then,
    UINT CtrlID = GetDlgCtrlID( hwnd );
    // Use the Control ID.

    return TRUE;
}

2. Get First and Next child window
If you don’t prefer a callback kind of child window iteration, then you can use – GetWindow() function. For getting the first window, you’ve to call the GetWindow() by passing GW_HWNDFIRST. For next window you should pass – GW_HWNDNEXT. You can also move backwards by using – GW_HWNDPREV. See the sample code snippet.

// Get the first child window. Use it.
HWND hwnd = ::GetWindow( GetSafeHwnd(),
                         GW_CHILD | GW_HWNDFIRST );

while( hwnd )
{
    // Get the next window. Use it.
    hwnd = ::GetWindow( hwnd, GW_HWNDNEXT );
}


While iterating in either methods you’ll get the child window handle. If you need the Ctrl ID, just call GetDlgCtrlID().


Targeted Audience – Beginners.

rgb_colorspace

Convert colors in RGB to HLS and vice versa.

2


RGB doesn’t need and introduction and If you are experienced in adobe photoshop, then you might be already familiar with HLS too.

RGB
All of us know about RGB. RGB is a color space in which, colors are represented by Red, Green and Blue components. Each component can vary from 0-255 in value. See the RGB color space below. (Thanks to MSDN for the pic)

HLS
HLS is also a Color space similar to RGB. But instead of red, green and blue components, HLS contain Hue, Luminance & Saturation components. Its a color space in which the Hue, saturation and luminance of a color can be separated and modified. See the HLS color space below.( Thanks to Wiki for the pic. )


Well, how can you convert RGB color to HLS and vice versa? You can use the api’s – ColorRGBToHLS() and ColorHLSToRGB(). See the sample code snippet below.

#include "Shlwapi.h"
...
// Red color in RGB
COLORREF RgbColor = RGB( 255, 0, 0 );

// Convert to HLS Color space
WORD Hue = 0;
WORD Luminance = 0;
WORD Saturation = 100;
ColorRGBToHLS( RgbColor, &Hue, &Luminance, &Saturation );

// Its converted to Hue, Luminance and Saturation.
// You can adjust the parameters according to your wish.

// Now convert back to RGB.
RgbColor = ColorHLSToRGB( Hue, Luminance, Saturation );


You can generate a wide variety of effects by adjusting HLS parameters which cannot be done by using RGB. Designers always use these HLS components for generating creative images. Take Photoshop and have a try!

BTW, don’t forget to add Shlwapi.lib to project settings.


Targeted Audience – Intermediate.

Format Size in bytes to more human readable size.

0


In several situation we’ve to convert bytes into more readable units such as KB’s or MB’s or in GB’s. For instance, you you want to display the file size of certain files, of course you can display in bytes. But it make more readable to user if its displayed in much higher units. So how can we convert bytes into more human readable size?


You can use the function – StrFormatByteSize(). See the following code snippet. In the code, the size of the executable file is read and converted to readable size.

#include "Shlwapi.h"
...
// Get the current filename.
TCHAR szFileName[MAX_PATH];
GetModuleFileName( AfxGetInstanceHandle(),
                   szFileName,
                   MAX_PATH );

// Open the file.
CFile CurrentFile;
CurrentFile.Open( szFileName, CFile::modeRead );

// Get the file size.
DWORD FileSize = 0;
FileSize = GetFileSize( HANDLE(CurrentFile.m_hFile),
                        0 );

// Now format the size in bytes to readable string.
const int MAX_FILE_SIZE_BUFFER = 255;
TCHAR szFileSize[MAX_FILE_SIZE_BUFFER];
StrFormatByteSize( FileSize,
                   szFileSize,
                   MAX_FILE_SIZE_BUFFER );

// The szFileSize contains converted size.


For converting byte size in DWORD, you just call StrFormatByteSize(). But for converting size in LONGLONG value, you’ve to call the Unicode version – StrFormatByteSizeW() explicitly.

BTW, don’t forget to specify Shlwapi.lib to your project settings.


Targeted Audience – Beginners.

Go to Top