Quantcast
Channel: cyotek.com Blog Summary Feed
Viewing all articles
Browse latest Browse all 559

Getting the hWnd of the edit component within a ComboBox control

$
0
0

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.

A simple demonstration application

Interop Declarations

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

[DllImport("user32.dll")]publicstaticexternbool GetComboBoxInfo(IntPtr hWnd, ref COMBOBOXINFO pcbi);

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

[StructLayout(LayoutKind.Sequential)]
publicstruct RECT
{publicint left;publicint top;publicint right;publicint 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

All content Copyright © by Cyotek Ltd or its respective writers. Permission to reproduce news and web log entries and other RSS feed content in unmodified form without notice is granted provided they are not used to endorse or promote any products or opinions (other than what was expressed by the author) and without taking them out of context. Written permission from the copyright owner must be obtained for everything else.
Original URL of this content is http://www.cyotek.com/blog/getting-the-hwnd-of-the-edit-component-within-a-combobox-control?source=rss


Viewing all articles
Browse latest Browse all 559

Trending Articles