C++ Function Pointers Simplified!

18 10 2009

Background information
Pointer is a variable which holds the address of another variable. Where, function pointer is again a variable which holds the address of a function.

If you think pointers are evil, then function pointers must be Satan for you. :) Well, is there any easy way to create function pointers from function prototype? Indeed, there is. Its the “BAT” technique. Never heard about it before? No problem. Its invented by me just now. After watching BatMan series from cartoon network.

FunctionPointers


The “BAT” technique is this -

  1. Put Bracket or parenthesis around the function name.
  2. Add Asterisk or star in-front of function name.
  3. Now Typedef it to create a new datatype. Means change the function name to new datatype name and add typedef infront of it.
  4. Now you can use the new function pointer datatype like ordinary variables.

For instance, Assume we want to make a function pointer for function – DWORD MyFunction( int a, int b).

1) Bracket
DWORD (MyFunction)( int a, int b);

2) Asterisk
DWORD (*MyFunction)( int a, int b);

3) Typedef
typedef DWORD (*MyFunctionPtr)( int a, int b);

Ah! you have created a function pointer – MyFunctionPtr for function type – ‘DWORD MyFunction( int a, int b)’
Now you can use it like any other variable in your code. For instance, just see the following code snippet with real world usage of function pointers.

// Callback function for progress notification.
bool NotifyProgress( int Percentage )
{
 // Display progress and return true to continue.
 return true;
}

// typedef function pointer.
typedef bool (*NotifyProgressPtr)( int Percentage );

// DVD Burning function with pointer to NotifyProgress
// to update progress.
void BurnDVD( NotifyProgressPtr FnPtr )
{
 for( int Progress = 0; Progress <= 100; ++Progress )
 {
 // Call the function.
 (*FnPtr)(Progress);
 }
}

// Main function.
int _tmain(int argc, _TCHAR* argv[])
{
 // Ummm... Burn one DVD.
 BurnDVD( NotifyProgress );
 return 0;
}


Function pointers are not that much evil. Isn’t it? ;)


Targeted Audience – Beginners.





How to Set Dialog as TopMost Window?

11 10 2009


I always wondered about popularity of Winamp. It has rich custom drawn UI, which made it stand out of the crowd. Did you noticed its “Always on top” feature and wondered about how its implemented? Its time to reveal the secret – How winamp implemented that feature – Staying at the top?

SetTopMostWindow


You can use – SetWindowPos() with HWND_TOPMOST flag. Have a look at the code snippet.

void CRabbitDlg::OnSetTopmost()
{
    // Set window position to topmost window.
    ::SetWindowPos( GetSafeHwnd(),
                    HWND_TOPMOST,
                    0, 0, 0, 0,
                    SWP_NOMOVE | SWP_NOREDRAW | SWP_NOSIZE );
}


Single line of code. But wowing feature. isn’t it?


Targeted Audience – Beginners.





Microsoft MVP for Visual C++ for 2009-2010

5 10 2009

Dear All,

With great pleasure, I would like to inform you that – with god’s grace, I’ve been awarded as Microsoft MVP (Most Valuable Professional) for Visual C++. At this moment I would like to thank all my readers for supporting me and making this happen! Please go through my MVP profile.

MicrosoftMvp

I really thank Microsoft for this wonderful MVP award and I really love their products. I really feel great about being a part of it. Well, I owe all this achievements to my fellow readers who motivated me to post more and more and atlast ended in being an MVP. So hearty thanks to you all, once again!

Best Regards,
Jijo. [Humble VC++ enthusiasit from Next Door]





How to Watch this Pointer – The Wizards Way!

30 07 2009


How to watch the this pointer? Just add ‘this’ to watch window. Everyone does like that. Isn’t it? But how Visual C++ wizards watch ‘this’ pointer? ;)

thiswizardway


The secret is, visual C++ compiler passes this pointer via ECX register. So add (ClassName*)(@ECX) to watch window will give you this pointer. Have a look at the screenshot.

thiswizardway2


Interesting, the internals of Visual C++. Isn’t it?


Targeted Audiance – Intermediate.





How to get the CPU Name String?

21 06 2009


While taking the System properties, you have noticed the processor name string. For instance, in my laptop it is – “Intel(R) Core(TM)2 Duo CPU     T5250  @ 1.50GHz“. Ever though about how to get this processor name string?

cpuid
Image Courtesy – Wallpaper Mania.


You can use the function – __cpuid(), which generates the instruction – cpuid. Have a look at the code snippet. Code taken and modified from MSDN.

#include <iostream>
#include <intrin.h>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    // Get extended ids.
    int CPUInfo[4] = {-1};
    __cpuid(CPUInfo, 0x80000000);
    unsigned int nExIds = CPUInfo[0];

    // Get the information associated with each extended ID.
    char CPUBrandString[0x40] = { 0 };
    for( unsigned int i=0x80000000; i<=nExIds; ++i)
    {
        __cpuid(CPUInfo, i);

        // Interpret CPU brand string and cache information.
        if  (i == 0x80000002)
        {
            memcpy( CPUBrandString,
            CPUInfo,
            sizeof(CPUInfo));
        }
        else if( i == 0x80000003 )
        {
            memcpy( CPUBrandString + 16,
            CPUInfo,
            sizeof(CPUInfo));
        }
        else if( i == 0x80000004 )
        {
            memcpy(CPUBrandString + 32, CPUInfo, sizeof(CPUInfo));
        }
}

    cout << "Cpu String: " << CPUBrandString;
}


You can get a lot of information about cpu by using __cpuid. Have a look at the MSDN Documentation.


Targeted Audiance – Intermeidate.





How to Change the Display Orientation?

10 05 2009


Are you using Windows XP? Press Ctrl+Atl+DownArrow, and then Ctrl+Atl+UpArrow. The screen changes its orientation upside down. isn’t it? But how to turn the screen, upside down programmatically?

ChangeDisplayOrientation
Image Courtesy – marieforleo.com


Get the current DEVMODE by calling -EnumDisplaySettings(). Then change orientation by setting DEVMODE.dmDisplayOrientation and calling ChangeDisplaySettings(). Have a look at the code snippet. Code taken from MSDN.

// Get current Device Mode.
DEVMODE DeviceMode = { 0 };
EnumDisplaySettings( NULL,
 ENUM_CURRENT_SETTINGS,
 &DeviceMode );

// Change display mode upside down.
DeviceMode.dmDisplayOrientation = DMDO_180;
ChangeDisplaySettings( &DeviceMode, 0 );

// Sleep for 10 seconds.
Sleep( 10000 );

// Change display mode back.
DeviceMode.dmDisplayOrientation = DMDO_DEFAULT;
ChangeDisplaySettings( &DeviceMode, 0 );


Be careful to restore the display orientation back. Or else ;)


Targeted Audiance – Intermeidate.





How to Parse Virtual Table?

7 05 2009

Virtual Table is one of the most fascinating stuff for C++ programmer. Well, did you ever  peek into virtual table, which is the real engine of virtual functions?

virtualfunction


The first 4 bytes of an objects points to another pointer which points to virtual table. Casting it to DWORD*, we can parse all virtual functions. Once you get function address, you can get the function name by calling – SymFromAddr(). Have a look at code snippet.

virtualfunction2

#include <ImageHlp.h>
...
// Get list of virtual functions.
void CRabbitDlg::ParseVtable()
{
    // Initialize symbols.
    InitializeSymbols();

    // We are going to parse vtable of CWinApp object.
    DWORD* pBase = (DWORD*)(AfxGetApp());
    DWORD* pVptr = (DWORD*)*pBase;

    // Iterate through VirtualTable.
    DWORD Index = 0;
    DWORD FnAddr = pVptr[Index];
    while( FnAddr )
    {
        // Translate FunctionAddress to FunctionName.
        CString FunctionName;
        GetSymbolNameFromAddr( FnAddr, FunctionName );

        // Format and add to list.
        CString Final;
        Final.Format( _T("%0x - %s"), FnAddr, FunctionName.operator LPCTSTR());
        m_List.AddString( Final );

        // Next function pointer.
        FnAddr = pVptr[++Index];
    }
}

// Initialize Symbol engine.
void CRabbitDlg::InitializeSymbols()
{
    DWORD Options = SymGetOptions();
    Options |= SYMOPT_DEBUG;
    Options |= SYMOPT_UNDNAME; 

    ::SymSetOptions( Options ); 

    // Initialize symbols.
    ::SymInitialize ( GetCurrentProcess(),
                      NULL,
                      TRUE );
}

// Get symbol name from address.
void CRabbitDlg::GetSymbolNameFromAddr( DWORD SymbolAddress, CString& csSymbolName )
{
    DWORD64 Displacement = 0;
    SYMBOL_INFO_PACKAGE SymbolInfo = {0};
    SymbolInfo.si.SizeOfStruct  = sizeof( SYMBOL_INFO );
    SymbolInfo.si.MaxNameLen = sizeof(SymbolInfo.name);

    // Get symbol from address.
    ::SymFromAddr( GetCurrentProcess(),
                   SymbolAddress,
                   &Displacement,
                   &SymbolInfo.si );

    csSymbolName = SymbolInfo.si.Name;
}


Don’t forget to include ImageHlp.lib to project settings.


Targeted Audiance – Intermediate.





How to Delete Duplicate entries from STL containers?

16 04 2009


If you want to remove duplicate items, you can go for stl::set. But what to do if you want to delete duplicate data from other containers?

removeduplicate
Picture Courtesy – Squidoo


You can use std::unique() algorithm to remove adjacent duplicate items. So at first, sort your data, then call std::unique(). Now all the duplicate data will be rearranged to end of container. Now delete the unwanted range of duplicate data. Have a look at code snippet below.

#include <vector>
#include <string>
#include <algorithm>

using namespace std;

int main(int argc, char* argv[])
{
    // Election list.
    vector<string> ElectionList;
    ElectionList.push_back( "Sam" );
    ElectionList.push_back( "John" );
    ElectionList.push_back( "Ron" );
    ElectionList.push_back( "Sam" );
    ElectionList.push_back( "John" );

    // Sort the list to make same items be together.
    sort( ElectionList.begin(), ElectionList.end());

    // Rearrange unique items to front.
    vector<string>::iterator Itr = unique(
        ElectionList.begin(),
        ElectionList.end());

    // Delete the duplicate range.
    ElectionList.erase( Itr, ElectionList.end());
}


Take care that std::unique() just removes the adjacent duplicate entries. It wont remove the entire duplicate entries present in the container. That’s why we need to sort the container at first, which will arrange all duplicate entries to adjacent  locations. ;)


Targeted Audience – Beginners.





How to Change the Icon of MFC application?

5 04 2009


When you create an MFC application, did you notice the icon of executable? Yes! its that same old icon. But I’ve seen other application with different icon. Well, how to set the icon of executable to give a new face for it? ;)

setappicon
Image Courtesy – Flickr


The secret is, windows will choose the first icon present in executable as exe icon. By default for an MFC application, IDR_MAINFRAME will be the icon resource name and it have the lowest resource value – 128. Follow the steps to add an icon and make set it the first one in executable.

1. Import a new icon by using resource editor.

setappicon1

2. Let the icon be IDR_ICON1.
3. Now open resource.h and you can see, IDR_MAINFRAME which is the mfc icon, have lowest resource id.

setappicon2
4. Now edit the resource.h to make IDI_ICON1 as lowest resource id.

setappicon3
5. Now clean and build your application and check the application icon. Wow! its changed!!!


The point is, the icon should be the first icon in executable. You can set icon value even to zero. It will work!


Targeted Audiance – Intermediate.





How to measure Performance by using High Resolution Timer in Visual C++?

31 03 2009


Ever had a performance tweaking project? The first thing you need is a high resolution stop watch to measure performance of different code blocks. But is there a high resolution stop watch?

highperformancetimer


You can use QueryPerformanceCounter(). You can get the performance counter frequency – i.e. ticks per second by calling QueryPerformanceFrequency(). Have a look at the sample CStopWatch class.

// Stop watch class.
class CStopWatch
{
public:
    // Constructor.
    CStopWatch()
    {
        // Ticks per second.
        QueryPerformanceFrequency( &liPerfFreq );
    }

    // Start counter.
    void Start()
    {
        liStart.QuadPart = 0;
        QueryPerformanceCounter( &liStart );
    }

    // Stop counter.
    void Stop()
    {
        liEnd.QuadPart = 0;
        QueryPerformanceCounter( &liEnd );
    }

    // Get duration.
    long double GetDuration()
    {
        return ( liEnd.QuadPart - liStart.QuadPart) /
                long double( liPerfFreq.QuadPart );
    }

private:
    LARGE_INTEGER liStart;
    LARGE_INTEGER liEnd;
    LARGE_INTEGER liPerfFreq;
};

int main()
{
    // Stop watch object.
    CStopWatch timer;

    // Start timer.
    timer.Start();

    // ZZzzzzz... for few seconds.
    Sleep( 3000 );
    timer.Stop();

    // Get the duration. Duration is in seconds.
    long double duration = timer.GetDuration();

    return 0;
}


Even if the sample app slept for 3 seconds, in high resolution timer, the duration is 2.9xxx seconds. ;) Can you guess why?


Targeted Audiance – Intermediate.