Archive

Archive for the ‘Windows API’ Category

Blog moved to www.ntcoder.com/bab

February 17, 2011 Leave a comment
Categories: Windows API

2010 in review

January 6, 2011 Leave a comment

The stats helper monkeys at WordPress.com mulled over how this blog did in 2010, and here’s a high level summary of its overall blog health:

Healthy blog!

The Blog-Health-o-Meter™ reads Wow.

Crunchy numbers

Featured image

The Louvre Museum has 8.5 million visitors per year. This blog was viewed about 75,000 times in 2010. If it were an exhibit at The Louvre Museum, it would take 3 days for that many people to see it.

In 2010, there were 4 new posts, growing the total archive of this blog to 314 posts. There were 7 pictures uploaded, taking up a total of 206kb.

The busiest day of the year was January 7th with 571 views. The most popular post that day was How to use SendInput?.

Where did they come from?

The top referring sites in 2010 were en.wordpress.com, google.com, stackoverflow.com, codeproject.com, and social.msdn.microsoft.com.

Some visitors came searching, mostly for typedef array, cmfcpropertygridctrl, sendinput, visual studio 2008 “list control” clistctrl -listbox, and mfc feature pack.

Attractions in 2010

These are the posts and pages that got the most views in 2010.

1

How to use SendInput? August 2009
19 comments and 1 Like on WordPress.com,

2

MFC Feature Pack Tutorial – Part 3 – CMFCPropertyGridCtrl June 2008
9 comments

3

MFC Feature Pack Tutorial – Part 1 – Getting started May 2008
20 comments

4

How to convert ANSI string to UNICODE string and vice versa? July 2008
5 comments

5

typedef a fixed length array July 2008
4 comments

Categories: Windows API

Mandatory styles for a child dialog

If you are creating a dialog with style WS_CHILD then make sure you also have DS_CONTROL  and DS_CONTROLPARENT enabled for the dialog.

The reason being that the dialog at a time is a control (embedded inside another window) and a control parent (housing other controls). If these styles are not specified calls to GetWindowRect and then a subsequent ScreenToClient will return top co-ordinates in negative leading to some confusion.

How to show “Open with” dialog?

February 12, 2010 1 comment

It’s quite handy to show the standard windows open with dialog, which lists all installed applications along with a browse button. In Windows XP there is no straight forward way of doing this.

In Windows Vista onwards Microsoft has provided a shell API for this purpose. It’s called SHOpenWithDialog.

Some sample code (couldn’t test this though since I’m on XP at home)…

OPENASINFO Info = { 0 };
Info.oaifInFlags = OAIF_EXEC | OAIF_ALLOW_REGISTRATION;
SHOpenWithDialog(NULL, &Info);

A screenshot of the dialog in XP…

Open with dialog

Open with dialog

How to create a unicode window in a non-unicode application?

December 22, 2009 Leave a comment

Recently a user asked this question in MSDN forums. He had MBCS enabled for his application and also wanted to enable unicode characters in a particular edit control. Note MFC only create unicode controls if UNICODE is defined in project settings.

So in order to explicitly create controls that support UNICODE characters we use the ‘W’ functions. For example: for our user he should use “CreateWindowW” function. Note the last ‘W’ in the function. ANSI windows are created by calling “CreateWindowA” function (this also means that we can explicitly create a non-unicode control).

Also make sure you use only UNICODE API’s for a control created in this manner. For e.g. always call GetWindowTextW instead of GetWindowTextA. Never use MFC on such a control if it’s not created by MFC framework, I mean don’t call CWnd::Attach on this control. Mainly because MFC is operating in non-unicode environment but our control is a UNICODE one.

Now once such a control is created you can paste characters of different languages, for e.g. Chinese, Japanese, etc even though the application is not a UNICODE supporting one.

Some issues when working with ComboBox

August 11, 2009 2 comments

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. 🙂

How to use SendInput?

August 4, 2009 20 comments

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 ));
}
%d bloggers like this: