Getting the hWnd of the edit component within a ComboBox control

I'm currently in the process of dusting off the bugs from a tool written back in 2011. One of the bugs involves an editable ComboBox control paired with a separate Button control. When the button is clicked a popup menu is shown, and when an item in this menu is clicked, the text of the ComboBox is updated.

The problem with this scenario is by default, as soon as the ComboBox loses focus, the SelectionStart, SelectionLength and SelectedText properties are reset, thus preventing my little menu from replacing the selected text. While this article doesn't solve this problem (I'll save that for the next article!), it does describe how you can get the hWnd, or window handle (in .NET terms the Handle) of the edit component, thus opening the door for a little Win32 API fun.

There are various approaches to doing this - you could use FindWindow and search for a child window with a class of edit, or use SendMessage with the CB_GETCOMBOBOXINFO message. Or, easiest of all, we can use the GetComboBoxInfo function.

Interop Declarations

Using this API is very simple, as there's one method and two simple structs.

[DllImport("user32.dll")]
public static extern bool GetComboBoxInfo(IntPtr hWnd, ref COMBOBOXINFO pcbi);

[StructLayout(LayoutKind.Sequential)]
public struct COMBOBOXINFO
{
  public int cbSize;
  public RECT rcItem;
  public RECT rcButton;
  public int stateButton;
  public IntPtr hwndCombo;
  public IntPtr hwndEdit;
  public IntPtr hwndList;
}

[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
  public int left;
  public int top;
  public int right;
  public int bottom;
}

Calling the API

There is one (well, many, but lets start simple!) caveat which you may fall foul of if you are new to Win32 API programming - often the contents of structs need to be initialized with their size first. But how to you know how big a structure is? Lucky for you, you don't need to calculate it manually - the Marshal.SizeOf function will handle this for you.

If you forget to set the size, then the structure simply won't be populated.

NativeMethods.COMBOBOXINFO info;

info = new NativeMethods.COMBOBOXINFO();
info.cbSize = Marshal.SizeOf(info);

if (NativeMethods.GetComboBoxInfo(control.Handle, ref info))
{
  // the info structure is now populated, go wild!
}

Getting the edit control handle

With the above in place, then getting the handle of the edit component is very straightforward.

private IntPtr GetEditHandle(ComboBox control)
{
  NativeMethods.COMBOBOXINFO info;

  info = new NativeMethods.COMBOBOXINFO();
  info.cbSize = Marshal.SizeOf(info);

  return NativeMethods.GetComboBoxInfo(control.Handle, ref info) ? info.hwndEdit : IntPtr.Zero;
}

Bear in mind that the edit control is a Win32 control - not a managed .NET control. In order to do anything with this therefore, you need to use additional Win32 API methods, or perhaps bind it to a NativeWindow class for easy subclassing. I'll briefly cover some of this in a future article.

Other goodies

The COMBOBOXINFO structure has other information, such as the handle of the list control, which you see if you set the DropDownStyle property of the ComboBox to Simple and the state of the dropdown button. You can view the MSDN Documentation to learn more about the structure.

Downloads

Filename Description Version Release Date
GetComboBoxInfoDemo.zip
  • md5: 4fcc1a5a01f589b63820d14e3288db50

Sample project for the getting the hWnd of the edit component within a ComboBox control blog post.

1.0.0.0 29/09/2013 Download

About The Author

Gravatar

The founder of Cyotek, Richard enjoys creating new blog content for the site. Much more though, he likes to develop programs, and can often found writing reams of code. A long term gamer, he has aspirations in one day creating an epic video game. Until that time, he is mostly content with adding new bugs to WebCopy and the other Cyotek products.

Leave a Comment

While we appreciate comments from our users, please follow our posting guidelines. Have you tried the Cyotek Forums for support from Cyotek and the community?

Styling with Markdown is supported