bits and bytes

Jesus Loves You. C, C++, VC++, .net code snippets and articles, based on Nibu’s day to day programming experiences.

Daily bytes

Posted by Nibu Thomas on April 7, 2009

Word of the Day

Quote of the Day

Article of the Day

This Day in History

Today’s Birthday

In the News

Posted in General | Tagged: , , , , | Leave a Comment »

Verify completeness of copy constructor

Posted by Nibu Thomas on November 18, 2009

So after sometime I’m back with a new tip. You know I sometimes forget to adapt copy constructors when I add new members to a class. So at times I end up with strange bugs. So I’ve devised a small utility to remind me to update copy constructors after adding new members to class. Here is the utility…

#ifdef _DEBUG
   #define VERIFY_COPY_CONSTRUCTOR(Class, OldSize)\
   if( sizeof( Class ) != OldSize )\
   {\
      TCHAR szBuf[512] = { 0 };\
      _stprintf_s(szBuf, \
                  sizeof(szBuf)/sizeof(TCHAR), \
                  _T( "Copy constructor not adapted for new members\nOld class size is: %d\nNew class size is: %d\n" ), \
                  OldSize, \
                  sizeof( Employee ));\
      ::MessageBox( ::GetForegroundWindow(), szBuf, _T( "Error!" ), MB_OK|MB_ICONERROR );\
      __asm int 3\
   }
#else
   #define VERIFY_COPY_CONSTRUCTOR(Class, Size)
#endif

class Employee
{
public:
   Employee()
   {
   }

   Employee( const Employee& Emp )
         : m_Name( Emp.m_Name )
   {
      // Actual size as of now is 36.
      VERIFY_COPY_CONSTRUCTOR( Employee, 32 );
   }

private:
   int m_Age;
   std::string m_Name;
};

Note: 32 is given on purpose to trigger an assert.

Now when you run this code an error pops up which says that copy constructor is not updated. Last time when I updated Employee class copy constructor I only added copying code for m_Name but now I’ve got a new member and I forgot to update the copy constructor. So my utility jumps in and gives me this error dialog…


Error Dialog

Error Dialog

 

Note that new size of the class is given in the message box to help you update the hard coded size in the macro. The only thing that you should remember here is to update the hard coded size in the macro (well you’ll that’s for sure ;) ).

PS: There is also something cooler which I didn’t try out yet. VC10 has something called static_assert which will be useful for such purposes. You can try out and let me know ;) .

#ifdef _DEBUG
#define VERIFY_COPY_CONSTRUCTOR(Class, OldSize)\
if( sizeof( Class ) != OldSize )\
{\
TCHAR szBuf[512] = { 0 };\
_stprintf_s(szBuf, sizeof(szBuf)/sizeof(TCHAR), _T( “Copy constructor not adapted for new members\nOld class size is: %d\nNew class size is: %d\n” ), OldSize, sizeof( Employee ));\
::MessageBox( ::GetForegroundWindow(), szBuf, _T( “Error!” ), MB_OK|MB_ICONERROR );\
__asm int 3\
}
#else
#define VERIFY_COPY_CLASS(Class, Size)
#endif

class Employee
{
public:
Employee()
{
}

Employee( const Employee& Emp )
{
VERIFY_COPY_CONSTRUCTOR( Employee, 35 );
}

private:
int m_Age;
std::string m_Name;
};

Posted in C++, VC++ | Tagged: | Leave a Comment »

Some issues when working with ComboBox

Posted by Nibu Thomas on August 11, 2009

The main reason for posting this issue is to help MFC/Win32 beginners. But anyway it’s a good read ;) , so once upon a time…

If you’re a beginner with window’s ComboBox controls then you might end up with a bald head thinking and thinking about a weird behavior of combo’s after it’s creation. The combo as such is a great control but there are certain important things to keep in mind while creating a combo.

So what are the problems? Well make it singular, “Problem”. One and the only problem with this control is shown in this screenshot…

Drop down not visible

Drop down not visible

I’ve clicked the drop down arrow but cannot see the dropdown. This one is created via resource editor. The problem here is, just adding a combo is not enough but we’ve also got to set the size of the drop down via resource editor. So follow these steps, as shown in the screen shot to fix this issue…

Resizing a combo drop down

Resizing a combo drop down

So that’s it. The white drag rectangle denotes combo drop down size. Press Ctrl + T to test this. Please note that this is not a bug but a feature of resource editor since there isn’t an another way to set drop down size for a combo via resource editor. But I agree that they should’ve set a better default drop down size instead of a zero height drop down.

Now this was via resource editor. It’s bit different when creating dynamically via code using CComboBox::Create function. Note that you have to give a valid height value. This height value will be the dropdown size for this combo.

See this e.g.

m_Combo.Create( WS_VISIBLE | WS_TABSTOP | WS_BORDER | CBS_DROPDOWNLIST | CBS_SORT,
                CRect( 10, 10, 200, 300 ),
                this,
                IDC_COMBO1 + 1 );
m_Combo.SetFont( GetFont(), TRUE );

Hope you’ve noticed the last big value given to Combo via CRect, 300. That’s the drop down height. Normally beginners set it to 30 or 40 which results in this issue.

See the resultant screenshot…

Result of properly creating a combo

Result of properly creating a combo

Not a big deal for experts but for beginners, well I’ve been a beginner too, it’s one painful issue. :)

Posted in MFC, Windows API | Tagged: , | Leave a Comment »

How to use SendInput?

Posted by Nibu Thomas on August 4, 2009

So what does SendInput API do?

SendInput API is a helper function to simulate keyboard and mouse inputs. It’s an ideal function to insert characters into a password which otherwise is not possible. Here is what MSDN says about this function…

“The SendInput function inserts the events in the INPUT structures serially into the keyboard or mouse input stream. These events are not interspersed with other keyboard or mouse input events inserted either by the user (with the keyboard or mouse) or by calls to keybd_event, mouse_event, or other calls to SendInput.”

Here is a simple and basic function which sends a given text to a foreground window (my earlier function was crap so I replaced it with this new one that works for all texts, haven’t tried out with foreign keyboards though)…

BOOL SendText( LPCSTR lpctszText )
{
   vector< INPUT > EventQueue;

   char Buff[120] = {0};
   GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_ILANGUAGE, Buff, sizeof(Buff));
   HKL hKeyboardLayout = ::LoadKeyboardLayout( Buff, KLF_ACTIVATE );

   const int Len = strlen( lpctszText );
   for( int Index = 0; Index &amp;amp;amp;lt; Len; ++Index )
   {
      INPUT Event = { 0 };

      const SHORT Vk = VkKeyScanEx(lpctszText[Index], hKeyboardLayout);
      const UINT VKey = ::MapVirtualKey( LOBYTE( Vk ), 0 );

      if( HIBYTE( Vk ) == 1 ) // Check if shift key needs to be pressed for this key
      {
          // Press shift key
          ::ZeroMemory( &amp;amp;amp;amp;Event, sizeof( Event ));
          Event.type = INPUT_KEYBOARD;
          Event.ki.dwFlags = KEYEVENTF_SCANCODE;
          Event.ki.wScan = ::MapVirtualKey( VK_LSHIFT, 0 );
          EventQueue.push_back( Event );
      }

      // Keydown
      ::ZeroMemory( &amp;amp;amp;amp;Event, sizeof( Event ));
      Event.type = INPUT_KEYBOARD;
      Event.ki.dwFlags = KEYEVENTF_SCANCODE;
      Event.ki.wScan = VKey;
      EventQueue.push_back( Event );

      // Keyup
      ::ZeroMemory( &amp;amp;amp;amp;Event, sizeof( Event ));
      Event.type = INPUT_KEYBOARD;
      Event.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP;
      Event.ki.wScan = VKey;
      EventQueue.push_back( Event );

      if( HIBYTE( Vk ) == 1 )// Release if previouly pressed
      {
           // Release shift key
          ::ZeroMemory( &amp;amp;amp;amp;Event, sizeof( Event ));
          Event.type = INPUT_KEYBOARD;
          Event.ki.dwFlags = KEYEVENTF_SCANCODE| KEYEVENTF_KEYUP;
          Event.ki.wScan = ::MapVirtualKey( VK_LSHIFT, 0 );
          EventQueue.push_back( Event );
      }
   }// End for

   if( hKeyboardLayout )
   {
       UnloadKeyboardLayout( hKeyboardLayout );
   }

   return ::SendInput( EventQueue.size(), &amp;amp;amp;amp;EventQueue[0], sizeof( INPUT ));
}

Posted in Windows API | Tagged: , , , | 19 Comments »

How to clear visual studio search history?

Posted by Nibu Thomas on July 15, 2009

Previous search terms of visual studio is stored in windows registry. The registry key for Visual Studio 9.0 is …

HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\9.0\Find

The search terms are arranged as …

Find 0
Find 1
Find 2

Delete them to clear search history.

Posted in Visual studio | Tagged: | 1 Comment »

auto keyword redefined in VC10

Posted by Nibu Thomas on July 14, 2009

auto keyword is one of those keywords that’s never used. So what the c++ committee has done is, they’ve started using it for a better purpose. For better understanding see this simple demo…

First without using auto keyword…

void AutoTest()
{
  typedef std::vector<int> IntVector;
  IntVector Ints;
  std::generate_n(std::back_inserter( Ints ), 100, rand);

  // After filling some elements into the vector, we iterate through them
  for( IntVector::iterator Itr = Ints.begin(); Itr != Ints.end(); ++Itr )
  {
    // Some code
  }
}

Now let’s try with the auto keyword…

void AutoTest()
{
  typedef std::vector</int><int> IntVector;
  IntVector Ints;
  std::generate_n(std::back_inserter( Ints ), 100, rand);

  // After filling some elements into the vector, we iterator through them
  for( auto Itr = Ints.begin(); Itr != Ints.end(); ++Itr )
  {
    // Some code
  }
}

Hope you noticed the difference, the type for the variable Itr is automagically inferred by the compiler based on the return type from Ints.begin().  Another huge benefit is when using auto keyword to wrap a lamda  expression (an anonymous/inline functor). See this example…

void LamdaTest()
{
   int x = 0;
   auto LamdaFunc = [&x](int y)
   {
     while( y-- > 0 )
     {
       ++x;
     }
   };

   LamdaFunc( 10 );
   LamdaFunc( 100 );

   std::cout < < "Value of x after calling LamdaFunc is: " << x;
}

For us it’s hard to infer or to know how to declare the type of this lamda expression but for the compiler it’s easy (well hope so). When we give auto keyword the type is auto inferred. We then use LamdaFunc object to invoke this lamda expression. In the end x will have the value 110. Note that the expression [&x] means, pass x by reference. I’ll brag about lamda’s in my next post probably.

Cool isn’t it, I liked this feature. 8)

Posted in C++, VC++, Visual studio | Tagged: , , , | Leave a Comment »

CComPtr vs _com_ptr_t

Posted by Nibu Thomas on July 14, 2009

Recently a user asked this question in forums, I was quite able to answer his query. So thought this might be useful to you guys too. :)

So the basic difference is that CComPtr is an ATL class is used with using ATL COM implementations while _com_ptr_t is one of the few COM support classes to support non ATL COM development. The definitions of these COM support classes go along with the tlb files and probably that’s why they are called as COM support classes. Also their definition can be found in comdef.h too. The other classes similar to _com_ptr_t are …

  1. _bstr_t
  2. _com_error
  3. _com_ptr_t
  4. _variant_t

So what are COM support classes? These are special lightweight classes that wraps basic useful COM functionality so that ideas like COM smart pointer typedefs over raw COM inteface classes works just by using tlb file. An example on how _com_ptr_t is used…

_COM_SMARTPTR_TYPEDEF(IMyInterface, __uuidof(IMyInterface));

This above line declares _com_ptr_t specialization IMyInterfacePtr.

The library to link to for using COM support classes is comsuppw.lib.

Posted in C++, VC++, COM | Tagged: , | Leave a Comment »

Ordering output of out of order builds in Visual Studio

Posted by Nibu Thomas on June 2, 2009

So what is an out of order build?

If you’ve got a multi-core processor then your compilation process will be distributed between these processors. One project will be built on one core while another one on a different core. Then all of these obj file will be gathered together during linking.

But one problem is that the output will look mangled, see this output…

Out of order builds

Out of order builds

The numbers on the left 3>, 4> uniquely identify a particular project being compiled. I’ve got two cores so effectively two projects can be compiled in parallel. But this is a mess particularly if you’ve got too many project’s you’ll have a hard time find out related projects, you’ll get tired of scrolling up and down. :)

But there is a way to overcome this, at the top of the output window (see above shot) there is a combo “Show output from:”. Change this to “Build Order” from “Build”, now this is how the output will look…

Build output ordered

Build output ordered

Just to be complete; you can enable out of order builds via…

Tools->Options->Projects and Solutions->Build and Run->Maximum number of parallel project builds.

Here is a screenshot of this dialog.

Enable Out Of Order Builds

Enable Out Of Order Builds

So enjoy working in this great IDE (well) ;) .

Posted in Visual studio | Tagged: , | 1 Comment »

Add horizontal scrollbar to a combo box

Posted by Nibu Thomas on May 28, 2009

CComboBox has a function called SetHorizontalExtent which doesn’t work. SDK equivalent is CB_SETHORIZONTALEXTENT which also doesn’t work. The reason for this bug is pretty lame, because WS_HSCROLL style for combo box is not set, which in turn the VS dialog editor does not provide :( . So a workaround is to open .rc file in a text editor and add WS_HSCROLL style manually for this combo.

This is how a combo box will look with a horizontal scrollbar…

Horizontal scrollbar in a combo box

Horizontal scrollbar in a combo box

Here is a sample code from MSDN which is adapted a bit for this purpose…

void CDialoTestDlg::AddHScroll( CComboBox& Cmb )
{
  // Find the longest string in the combo box.
  CString str;
  CSize sz;
  int dx = 0;

  TEXTMETRIC tm = { 0 };
  CDC* pDC = Cmb.GetDC();
  CFont* pFont = Cmb.GetFont();

  // Select the listbox font, save the old font
  CFont* pOldFont = pDC->SelectObject(pFont);

  // Get the text metrics for avg char width
  pDC->GetTextMetrics(&tm);

  for (int i = 0; i < Cmb.GetCount(); i++)
  {
    Cmb.GetLBText(i, str);
    sz = pDC->GetTextExtent(str);

    // Add the avg width to prevent clipping
    sz.cx += tm.tmAveCharWidth;

    if (sz.cx > dx)
      dx = sz.cx;
  }

  // Select the old font back into the DC
  pDC->SelectObject(pOldFont);
  Cmb.ReleaseDC(pDC);

  // Set the horizontal extent so every character of all strings can
  // be scrolled to.
  Cmb.SetHorizontalExtent(dx);
}// End AddHScroll

Setting horizontal extent is useful to prevent the combo’s drop down width from extending beyond screen limits. Note that there is another function called SetDroppedWidth which sets the drop down’s width but with no scrolling.

Posted in MFC, Windows API | Tagged: , , , , | 4 Comments »

std::string caveat

Posted by Nibu Thomas on May 18, 2009

Never access an std::string’s buffer with an intent to increase/decrease it’s length nor pass such a buffer to functions which takes a char*. I did this mistake sometime back and got trapped in a strange bug with operator +=. This is how my code looked.

std::string str( ' ', MAX_PATH );
GetFolderName( pFullPath, &str[0] ); // Oop

Problem with above code is that you won’t get an immediate crash since it’s a properly allocated buffer with MAX_PATH chars. But if you do further operations on such string expect plenty of inconsistencies. This is how my code looked after above piece of code…

str += "\\"; // Append backslash

I was expecting a valid path with backslash appended towards it’s end, but this never happened and debugging with debugger too didn’t help.

So now let me tell you what the exact problem is! When you do &str[0] you pass the address to the first char in std::string’s buffer. So when function GetFolderName fills in this buffer with folder path the length of std::string is not updated since it’s a C style function and it’s neither expected to do so. So the function terminates given buffer with a ” with std::string’s length way high (MAX_PATH). So now when I do a += std::string internally fails some condition leading to unexpected results, note that this piece of code never caused a crash but I was quite lucky and watchful enough to fix this stupid bug. Sigh!

So watchout, there is no CString::GetBuffer or CString::GetBufferSetLength type of function for std::string, well at least for now.

Posted in C++, VC++, STL, Strange bugs | Tagged: , , | Leave a Comment »

Project Conversion Bug in VS2008

Posted by Nibu Thomas on May 11, 2009

Are you having trouble with VS2008 after conversion from VS2005 to VS2008? Most common complaints are that the executable is way to slow when compared to it’s counterpart generated with VS2005. The reason for this is given in this MSDN forum thread have a look…

http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/fb32033b-7bad-439b-a94c-943a17f0cbb2

The essence of this thread is given below (quote from the thread, thanks to Jon Baggott)…

In Visual Studio 2008 SP1 (SP1 not RTM) there is a serious bug with /O2 optimization. One way this bug can be triggered is by upgrading a project from a previous version. Even though the project setting shows the release build is set to /O2, the build can be not optimized at all. To work around it you have to change the setting to no optimization, apply, and then change it back to /O2. The quick way to see if this is needed is to check whether the setting for optimization is in bold or regular – if’s it’s bold you’re OK; if it’s regular text you’re not. This bug has been reported to Microsoft by many people over the past few months via the Connect feedback site but every case has been closed by them without doing anything and for completely invalid reasons.

Posted in C++, VC++, Strange bugs, Visual studio | Tagged: , , | 1 Comment »