How to find the application associated with particular file extension.

30 05 2008


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.

29 05 2008


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.

28 05 2008


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?

27 05 2008


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.





Copy error string from MessageBox – More Easily.

26 05 2008


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?

25 05 2008


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.

24 05 2008


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.