{"id":1353,"date":"2012-10-13T23:30:45","date_gmt":"2012-10-13T21:30:45","guid":{"rendered":"http:\/\/mariusbancila.ro\/blog\/?p=1353"},"modified":"2012-10-13T23:30:45","modified_gmt":"2012-10-13T21:30:45","slug":"keyboard-input-and-tab-navigation-between-wpf-controls-in-win32-application","status":"publish","type":"post","link":"https:\/\/mariusbancila.ro\/blog\/2012\/10\/13\/keyboard-input-and-tab-navigation-between-wpf-controls-in-win32-application\/","title":{"rendered":"Keyboard input and TAB navigation between WPF controls in a Win32 application"},"content":{"rendered":"<p>It is possible to host WPF controls in a Win32 application, and the other way around, but because of the differences betweeb these technologies there are various issues that can appear. One of these is handling of keyboard input. Without diving too much into differences between WPF and Win32, I will show how to provide keyboard input for WPF controls hosted in a Win32 applications. For reading about the differences and the interoping between the two I suggest <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms742522.aspx\" target=\"_blank\">WPF and Win32 Interoperation<\/a>.<\/p>\n<h3>Hosting a WPF Control in Win32<\/h3>\n<p>To host a WPF control in a Win32 application you need to follow several steps.<\/p>\n<ul>\n<li>Create a new <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.windows.interop.hwndsource.aspx\" target=\"_blank\">HwndSource<\/a>, setting the parent window as it&#8217;s parent. This is a key object, that enables displaying of WPF content in a Win32 window.<\/li>\n<li>Instantiate the WPF control or window<\/li>\n<li>Assign the reference to this instance of the WPF control or window RootVisual property of the HwndSource object.<\/li>\n<\/ul>\n<p>To simplify this process, I have this small helper class:<\/p>\n<pre class=\"cpp\" name=\"code\">\r\n#pragma once\r\n\r\n#include &lt;vcclr.h&gt;\r\n\r\nclass CWpfControlWrapper\r\n{\r\n   HWND m_hwndWPF;\r\n   gcroot&lt;System::Windows::Interop::HwndSource^&gt; m_source;\r\n   gcroot&lt;System::Windows::Controls::Control^&gt; m_control;\r\n\r\npublic:\r\n   CWpfControlWrapper(void):m_hwndWPF(NULL) {}\r\n   ~CWpfControlWrapper(void) {}\r\n\r\n   template &lt;typename T&gt;\r\n   T^ Control()\r\n   {\r\n      System::Windows::Controls::Control^ obj = m_control;\r\n      return dynamic_cast&lt;T^&gt;(obj);\r\n   }\r\n\r\n   BOOL CreateControl(System::Type^ type, \r\n                      HWND parent, \r\n                      DWORD style, \r\n                      int x, int y, \r\n                      int width, int height)\r\n   {\r\n      System::Windows::Interop::HwndSourceParameters^ sourceParams = \r\n         gcnew System::Windows::Interop::HwndSourceParameters(\"WpfControlWrapper\");\r\n\r\n      sourceParams-&gt;PositionX = x;\r\n      sourceParams-&gt;PositionY = y;\r\n      sourceParams-&gt;Height = height;\r\n      sourceParams-&gt;Width = width;\r\n      sourceParams-&gt;ParentWindow = System::IntPtr(parent);\r\n      sourceParams-&gt;WindowStyle = style;\r\n      m_source = gcnew System::Windows::Interop::HwndSource(*sourceParams);\r\n\r\n      m_control = (System::Windows::Controls::Control^)System::Activator::CreateInstance(type);\r\n      m_source-&gt;RootVisual = m_control;\r\n\r\n      m_hwndWPF = (HWND)m_source-&gt;Handle.ToPointer();      \r\n\r\n      return m_hwndWPF == NULL ? FALSE : TRUE;\r\n   }\r\n};<\/pre>\n<p>With this class I can create WPF controls like this:<\/p>\n<pre class=\"cpp\" name=\"code\">\r\nCWpfControlWrapper btn1;\r\nbtn1.CreateControl(System::Windows::Controls::Button::typeid, \r\n                   m_hWnd, \r\n                   WS_CHILD|WS_VISIBLE|WS_TABSTOP, \r\n                   10, 10, 210, 24);\r\nbtn1.Control&lt;System::Windows::Controls::Button&gt;()-&gt;Content = \"Button 1\";\r\n<\/pre>\n<h3>Enabling Keyboard Input<\/h3>\n<p>While you can use the mouse with these WPF controls added like this, the keyboard in not enabled. To provide keyboard input for the WPF controls, we need to hook the HwndSource, adding a handler that receives all window messages. We must handle the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/ms645425.aspx\" target=\"_blank\">WM_GETDLGCODE<\/a> message to let the system know what kind of messages we want to handle on our own (in the WPF control). <\/p>\n<p>This is how we add the hook:<\/p>\n<pre class=\"cpp\" name=\"code\">\r\nm_source->AddHook(gcnew System::Windows::Interop::HwndSourceHook(\r\n                  &amp;CWpfControlWrapper::ChildHwndSourceHook));\r\n<\/pre>\n<p>And this is how the hook procedure looks (defined as a static member of my CWpfControlWrapper):<\/p>\n<pre class=\"cpp\" name=\"code\">\r\nstatic System::IntPtr ChildHwndSourceHook(\r\n  System::IntPtr hwnd, \r\n  int msg, \r\n  System::IntPtr wParam, \r\n  System::IntPtr lParam, \r\n  bool% handled)\r\n{\r\n  if (msg == WM_GETDLGCODE)\r\n  {\r\n     handled = true;\r\n     return System::IntPtr(DLGC_WANTCHARS | DLGC_WANTTAB | DLGC_WANTARROWS | DLGC_WANTALLKEYS);\r\n  }\r\n\r\n  return System::IntPtr::Zero;\r\n}\r\n<\/pre>\n<p>By returning all these dialog codes will let the system know that the window wants to process arrow keys, tab keys, all keys and receive the WM_CHAR message.<\/p>\n<h3>Enabling TAB Navigation<\/h3>\n<p>Even though the WPF controls now have keyboard input, it turns our that navigating with TAB (forward) or TAB+SHIFT (backwards) does not work.<\/p>\n<p>Here is an example where I have an MFC application with four WPF controls, two buttons and two text boxes. One button and one text box, as well as the OK and CANCEL buttons have tab stops.<\/p>\n<pre class=\"cpp\" name=\"code\">\r\nCWpfControlWrapper btn1;\r\nbtn1.CreateControl(System::Windows::Controls::Button::typeid, \r\n                  m_hWnd, \r\n                  WS_CHILD|WS_VISIBLE|WS_TABSTOP, \r\n                  10, 10, 210, 24);\r\nbtn1.Control&lt;System::Windows::Controls::Button&gt;()-&gt;Content = \"Button 1 (tab stop)\";\r\n\r\nCWpfControlWrapper btn2;\r\nbtn2.CreateControl(System::Windows::Controls::Button::typeid, \r\n                  m_hWnd, \r\n                  WS_CHILD|WS_VISIBLE, \r\n                  10, 40, 210, 24);\r\nbtn2.Control&lt;System::Windows::Controls::Button&gt;()-&gt;Content = \"Button 2 (no tab stop)\";\r\n\r\nCWpfControlWrapper edit1;\r\nedit1.CreateControl(System::Windows::Controls::TextBox::typeid, \r\n                   m_hWnd, \r\n                   WS_CHILD|WS_VISIBLE|WS_TABSTOP, \r\n                   10, 70, 210, 24);\r\nedit1.Control&lt;System::Windows::Controls::TextBox&gt;()-&gt;Text = \"edit 1 (tab stop)\";\r\n\r\nCWpfControlWrapper edit2;\r\nedit2.CreateControl(System::Windows::Controls::TextBox::typeid, \r\n                   m_hWnd, \r\n                   WS_CHILD|WS_VISIBLE, \r\n                   10, 100, 210, 24);\r\nedit2.Control&lt;System::Windows::Controls::TextBox&gt;()-&gt;Text = \"edit 2 (no tab stop)\";\r\n<\/pre>\n<p>The sample dialog box looks like this:<br \/>\n<img loading=\"lazy\" decoding=\"async\" alt=\"\" src=\"\/blog\/wp-content\/uploads\/2012\/10\/tabstops.png\" title=\"TAB stops demo\" class=\"alignnone\" width=\"250\" height=\"363\" \/><br \/>\nPressing the TAB key should allow navigating from button 1 to edit 1, then button OK, button CANCEL and then back to button 1. Button 2 and edit 2, not having the tab stop style defined, should not be included in the navigation.<\/p>\n<p>As already mentioned, this does not work, however. After reading about a solution for this problem, it looked like the key lied in the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.windows.interop.ikeyboardinputsink.aspx\" target=\"_blank\">IKeyboardInputSink<\/a> interface, that both HwndSource and HwndHost implement. This interface provides a keyboard sink for components that manage tabbing, accelerators, and mnemonics across interop boundaries and between HWNDs. Apparently the solution was to:<\/p>\n<ul>\n<li>derive the HwndSource class<\/li>\n<li>override the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb338485.aspx\">TabInto<\/a> method (actually, since this is a sealed method you&#8217;d have to define a new override for it) and implement there the tabbing logic<\/li>\n<li>use this derived HwndSource to present WPF content in a Win32 window<\/li>\n<\/ul>\n<p>Though I tried several things I didn&#8217;t manage to make it work. However, since I already had a hook for all window messages, and explicitly asked for receiving WM_CHAR, it was possible to use this to handle TAB and TAB+SHIFT. So here is an addition to the ChildHwndSourceHook above:<\/p>\n<pre class=\"cpp\" name=\"code\">\r\nelse if(msg == WM_CHAR)\r\n{\r\n   if(wParam.ToInt32() == VK_TAB)\r\n   {\r\n      handled = true;\r\n      HWND nextTabStop = FindNextTabStop((HWND)hwnd.ToPointer(), \r\n                                         (GetKeyState(VK_SHIFT) &amp; 0x8000) != 0x8000);\r\n      if(nextTabStop)\r\n         ::SetFocus(nextTabStop);\r\n   }\r\n}\r\n<\/pre>\n<p>So if we get a WM_CHAR and the wParam is VK_TAB, then we query the parent for the next tab stop (for forward navigation if SHIFT was not pressed, or backwards navigation if SHIFT was also pressed). If there is such a tab stop we set focus on that window.<\/p>\n<p>The FindNextTabStop method (added as a member of the CWpfControlWrapper class) looks like this:<\/p>\n<pre class=\"cpp\" name=\"code\">\r\nstatic HWND FindNextTabStop(HWND wnd, bool forward)\r\n{\r\n  HWND nextstop = NULL;\r\n  HWND nextwnd = wnd;\r\n  do\r\n  {\r\n     \/\/ get the next\/previous window in the z-order\r\n     nextwnd = ::GetWindow(nextwnd, forward ? GW_HWNDNEXT : GW_HWNDPREV);\r\n\r\n     \/\/ if we are at the end of the z-order, start from the top\/bottom\r\n     if(nextwnd == NULL) \r\n        nextwnd = ::GetWindow(wnd, forward ? GW_HWNDFIRST : GW_HWNDLAST);\r\n\r\n     \/\/ if we returned to the same control then we iterated the entire z-order\r\n     if(nextwnd == wnd)\r\n        break;\r\n\r\n     \/\/ get the window style and check the WS_TABSTOP style\r\n     DWORD style = ::GetWindowLongPtr(nextwnd, GWL_STYLE);\r\n     if((style &amp; WS_TABSTOP) == WS_TABSTOP)\r\n        nextstop = nextwnd;\r\n  }while(nextstop == NULL);\r\n  \r\n  return nextstop;\r\n}\r\n<\/pre>\n<p>It does the following:<\/p>\n<ul>\n<li>it gets the next\/previous window in the z-order (which defines the tab stop order)<\/li>\n<li>when it reaches the end\/top of the z-order, it starts all over again, which enables looping through the child windows of the parent<\/li>\n<li>if the next child the in z-order is the current control, then it finished looping through the children of the parent and it stops<\/li>\n<li>if the current child in the z-order has the WS_TABSTOP style set, then this is the window we are looking for<\/li>\n<\/ul>\n<p>With this defined, it is possible to use the TAB key to navigate between the WPF controls on a Win32 window.<\/p>\n<p>Here is the MFC demo application that you can try: <div class=\"wp-block-button\">\n<a  data-e-Disable-Page-Transition=\"true\" class=\"dlm-download-link dlm-download-default wp-block-button__link wp-element-button\" title=\"Version 1.0\" href=\"https:\/\/mariusbancila.ro\/blog\/download\/3497\/?tmstv=1792608822\" rel=\"nofollow\" id=\"download-link-3497\" data-redirect=\"false\" >\n\tMfc-Wpf Tabbing\t(<span class=\"dlm-download-count-value\">7903 downloads<\/span>\n\t)\n<\/a>\n<\/div>\n.<\/p>\n<p><a style=\"display:none\" href=\"http:\/\/www.codeproject.com\/script\/Articles\/MemberArticles.aspx?amid=562357\" rel=\"tag\">CodeProject<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>It is possible to host WPF controls in a Win32 application, and the other way around, but because of the differences betweeb these technologies there are various issues that can appear. One of these is handling of keyboard input. Without diving too much into differences between WPF and Win32, I will show how to provide &#8230; <a title=\"Keyboard input and TAB navigation between WPF controls in a Win32 application\" class=\"read-more\" href=\"https:\/\/mariusbancila.ro\/blog\/2012\/10\/13\/keyboard-input-and-tab-navigation-between-wpf-controls-in-win32-application\/\" aria-label=\"Read more about Keyboard input and TAB navigation between WPF controls in a Win32 application\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_uag_custom_page_level_css":"","advgb_blocks_editor_width":"","advgb_blocks_columns_visual_guide":"","_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[7,12,288,146,163],"tags":[301,453,326,34,291,96],"class_list":["post-1353","post","type-post","status-publish","format-standard","hentry","category-c","category-mfc","category-win32","category-windows","category-wpf-net-software-it","tag-interop","tag-mfc","tag-tabstop","tag-vc","tag-win32-2","tag-wpf"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.3 - aioseo.com -->\n\t<meta name=\"description\" content=\"Learn how to enable keyboard input and TAB navigation for WPF controls hosted in Win32 windows.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Marius Bancila\"\/>\n\t<meta name=\"keywords\" content=\"wpf,mfc,controls,vc++,interop,tabstop,win32,manage,native,c++\" \/>\n\t<link rel=\"canonical\" href=\"https:\/\/mariusbancila.ro\/blog\/2012\/10\/13\/keyboard-input-and-tab-navigation-between-wpf-controls-in-win32-application\/\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"Marius Bancila&#039;s Blog | About code. Mostly on C++\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"Keyboard input and TAB navigation between WPF controls in a Win32 application\" \/>\n\t\t<meta property=\"og:description\" content=\"Learn how to enable keyboard input and TAB navigation for WPF controls hosted in Win32 windows.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/mariusbancila.ro\/blog\/2012\/10\/13\/keyboard-input-and-tab-navigation-between-wpf-controls-in-win32-application\/\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2012-10-13T21:30:45+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2012-10-13T21:30:45+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary\" \/>\n\t\t<meta name=\"twitter:title\" content=\"Keyboard input and TAB navigation between WPF controls in a Win32 application\" \/>\n\t\t<meta name=\"twitter:description\" content=\"Learn how to enable keyboard input and TAB navigation for WPF controls hosted in Win32 windows.\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2012\\\/10\\\/13\\\/keyboard-input-and-tab-navigation-between-wpf-controls-in-win32-application\\\/#article\",\"name\":\"Keyboard input and TAB navigation between WPF controls in a Win32 application\",\"headline\":\"Keyboard input and TAB navigation between WPF controls in a Win32 application\",\"author\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\"},\"publisher\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#organization\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"\\\/blog\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/tabstops.png\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2012\\\/10\\\/13\\\/keyboard-input-and-tab-navigation-between-wpf-controls-in-win32-application\\\/#articleImage\"},\"datePublished\":\"2012-10-13T23:30:45+02:00\",\"dateModified\":\"2012-10-13T23:30:45+02:00\",\"inLanguage\":\"en-US\",\"commentCount\":3,\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2012\\\/10\\\/13\\\/keyboard-input-and-tab-navigation-between-wpf-controls-in-win32-application\\\/#webpage\"},\"isPartOf\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2012\\\/10\\\/13\\\/keyboard-input-and-tab-navigation-between-wpf-controls-in-win32-application\\\/#webpage\"},\"articleSection\":\"C++, MFC, Win32, Windows, WPF, interop, MFC, tabstop, VC++, win32, WPF\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2012\\\/10\\\/13\\\/keyboard-input-and-tab-navigation-between-wpf-controls-in-win32-application\\\/#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/#listItem\",\"name\":\"IT\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/#listItem\",\"position\":2,\"name\":\"IT\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/#listItem\",\"name\":\"Software\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#listItem\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/#listItem\",\"position\":3,\"name\":\"Software\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/#listItem\",\"name\":\"C++\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/#listItem\",\"name\":\"IT\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/#listItem\",\"position\":4,\"name\":\"C++\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/mfc\\\/#listItem\",\"name\":\"MFC\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/#listItem\",\"name\":\"Software\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/mfc\\\/#listItem\",\"position\":5,\"name\":\"MFC\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/mfc\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2012\\\/10\\\/13\\\/keyboard-input-and-tab-navigation-between-wpf-controls-in-win32-application\\\/#listItem\",\"name\":\"Keyboard input and TAB navigation between WPF controls in a Win32 application\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/#listItem\",\"name\":\"C++\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2012\\\/10\\\/13\\\/keyboard-input-and-tab-navigation-between-wpf-controls-in-win32-application\\\/#listItem\",\"position\":6,\"name\":\"Keyboard input and TAB navigation between WPF controls in a Win32 application\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/mfc\\\/#listItem\",\"name\":\"MFC\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#organization\",\"name\":\"Marius Bancila's Blog\",\"description\":\"About code. Mostly on C++\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/\",\"name\":\"Marius Bancila\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2012\\\/10\\\/13\\\/keyboard-input-and-tab-navigation-between-wpf-controls-in-win32-application\\\/#authorImage\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a84dd2831d955c38355ddea55df4df260809b88f36408bc14fd4eab8f7f131c9?s=96&d=mm&r=g\",\"width\":96,\"height\":96,\"caption\":\"Marius Bancila\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2012\\\/10\\\/13\\\/keyboard-input-and-tab-navigation-between-wpf-controls-in-win32-application\\\/#webpage\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2012\\\/10\\\/13\\\/keyboard-input-and-tab-navigation-between-wpf-controls-in-win32-application\\\/\",\"name\":\"Keyboard input and TAB navigation between WPF controls in a Win32 application\",\"description\":\"Learn how to enable keyboard input and TAB navigation for WPF controls hosted in Win32 windows.\",\"inLanguage\":\"en-US\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2012\\\/10\\\/13\\\/keyboard-input-and-tab-navigation-between-wpf-controls-in-win32-application\\\/#breadcrumblist\"},\"author\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\"},\"creator\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\"},\"datePublished\":\"2012-10-13T23:30:45+02:00\",\"dateModified\":\"2012-10-13T23:30:45+02:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/\",\"name\":\"Marius Bancila's Blog\",\"description\":\"About code. Mostly on C++\",\"inLanguage\":\"en-US\",\"publisher\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"Keyboard input and TAB navigation between WPF controls in a Win32 application","description":"Learn how to enable keyboard input and TAB navigation for WPF controls hosted in Win32 windows.","canonical_url":"https:\/\/mariusbancila.ro\/blog\/2012\/10\/13\/keyboard-input-and-tab-navigation-between-wpf-controls-in-win32-application\/","robots":"max-image-preview:large","keywords":"wpf,mfc,controls,vc++,interop,tabstop,win32,manage,native,c++","webmasterTools":{"miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/mariusbancila.ro\/blog\/2012\/10\/13\/keyboard-input-and-tab-navigation-between-wpf-controls-in-win32-application\/#article","name":"Keyboard input and TAB navigation between WPF controls in a Win32 application","headline":"Keyboard input and TAB navigation between WPF controls in a Win32 application","author":{"@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author"},"publisher":{"@id":"https:\/\/mariusbancila.ro\/blog\/#organization"},"image":{"@type":"ImageObject","url":"\/blog\/wp-content\/uploads\/2012\/10\/tabstops.png","@id":"https:\/\/mariusbancila.ro\/blog\/2012\/10\/13\/keyboard-input-and-tab-navigation-between-wpf-controls-in-win32-application\/#articleImage"},"datePublished":"2012-10-13T23:30:45+02:00","dateModified":"2012-10-13T23:30:45+02:00","inLanguage":"en-US","commentCount":3,"mainEntityOfPage":{"@id":"https:\/\/mariusbancila.ro\/blog\/2012\/10\/13\/keyboard-input-and-tab-navigation-between-wpf-controls-in-win32-application\/#webpage"},"isPartOf":{"@id":"https:\/\/mariusbancila.ro\/blog\/2012\/10\/13\/keyboard-input-and-tab-navigation-between-wpf-controls-in-win32-application\/#webpage"},"articleSection":"C++, MFC, Win32, Windows, WPF, interop, MFC, tabstop, VC++, win32, WPF"},{"@type":"BreadcrumbList","@id":"https:\/\/mariusbancila.ro\/blog\/2012\/10\/13\/keyboard-input-and-tab-navigation-between-wpf-controls-in-win32-application\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/#listItem","position":1,"name":"Home","item":"https:\/\/mariusbancila.ro\/blog\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/#listItem","name":"IT"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/#listItem","position":2,"name":"IT","item":"https:\/\/mariusbancila.ro\/blog\/category\/it\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/#listItem","name":"Software"},"previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/#listItem","name":"Home"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/#listItem","position":3,"name":"Software","item":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/#listItem","name":"C++"},"previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/#listItem","name":"IT"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/#listItem","position":4,"name":"C++","item":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/mfc\/#listItem","name":"MFC"},"previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/#listItem","name":"Software"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/mfc\/#listItem","position":5,"name":"MFC","item":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/mfc\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/2012\/10\/13\/keyboard-input-and-tab-navigation-between-wpf-controls-in-win32-application\/#listItem","name":"Keyboard input and TAB navigation between WPF controls in a Win32 application"},"previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/#listItem","name":"C++"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/2012\/10\/13\/keyboard-input-and-tab-navigation-between-wpf-controls-in-win32-application\/#listItem","position":6,"name":"Keyboard input and TAB navigation between WPF controls in a Win32 application","previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/mfc\/#listItem","name":"MFC"}}]},{"@type":"Organization","@id":"https:\/\/mariusbancila.ro\/blog\/#organization","name":"Marius Bancila's Blog","description":"About code. Mostly on C++","url":"https:\/\/mariusbancila.ro\/blog\/"},{"@type":"Person","@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author","url":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/","name":"Marius Bancila","image":{"@type":"ImageObject","@id":"https:\/\/mariusbancila.ro\/blog\/2012\/10\/13\/keyboard-input-and-tab-navigation-between-wpf-controls-in-win32-application\/#authorImage","url":"https:\/\/secure.gravatar.com\/avatar\/a84dd2831d955c38355ddea55df4df260809b88f36408bc14fd4eab8f7f131c9?s=96&d=mm&r=g","width":96,"height":96,"caption":"Marius Bancila"}},{"@type":"WebPage","@id":"https:\/\/mariusbancila.ro\/blog\/2012\/10\/13\/keyboard-input-and-tab-navigation-between-wpf-controls-in-win32-application\/#webpage","url":"https:\/\/mariusbancila.ro\/blog\/2012\/10\/13\/keyboard-input-and-tab-navigation-between-wpf-controls-in-win32-application\/","name":"Keyboard input and TAB navigation between WPF controls in a Win32 application","description":"Learn how to enable keyboard input and TAB navigation for WPF controls hosted in Win32 windows.","inLanguage":"en-US","isPartOf":{"@id":"https:\/\/mariusbancila.ro\/blog\/#website"},"breadcrumb":{"@id":"https:\/\/mariusbancila.ro\/blog\/2012\/10\/13\/keyboard-input-and-tab-navigation-between-wpf-controls-in-win32-application\/#breadcrumblist"},"author":{"@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author"},"creator":{"@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author"},"datePublished":"2012-10-13T23:30:45+02:00","dateModified":"2012-10-13T23:30:45+02:00"},{"@type":"WebSite","@id":"https:\/\/mariusbancila.ro\/blog\/#website","url":"https:\/\/mariusbancila.ro\/blog\/","name":"Marius Bancila's Blog","description":"About code. Mostly on C++","inLanguage":"en-US","publisher":{"@id":"https:\/\/mariusbancila.ro\/blog\/#organization"}}]},"og:locale":"en_US","og:site_name":"Marius Bancila's Blog | About code. Mostly on C++","og:type":"article","og:title":"Keyboard input and TAB navigation between WPF controls in a Win32 application","og:description":"Learn how to enable keyboard input and TAB navigation for WPF controls hosted in Win32 windows.","og:url":"https:\/\/mariusbancila.ro\/blog\/2012\/10\/13\/keyboard-input-and-tab-navigation-between-wpf-controls-in-win32-application\/","article:published_time":"2012-10-13T21:30:45+00:00","article:modified_time":"2012-10-13T21:30:45+00:00","twitter:card":"summary","twitter:title":"Keyboard input and TAB navigation between WPF controls in a Win32 application","twitter:description":"Learn how to enable keyboard input and TAB navigation for WPF controls hosted in Win32 windows."},"aioseo_meta_data":{"post_id":"1353","title":"Keyboard input and TAB navigation between WPF controls in a Win32 application","description":"Learn how to enable keyboard input and TAB navigation for WPF controls hosted in Win32 windows.","keywords":[{"label":"WPF","value":"WPF"},{"label":"MFC","value":"MFC"},{"label":"controls","value":"controls"},{"label":"VC++","value":"VC++"},{"label":"interop","value":"interop"},{"label":"tabstop","value":"tabstop"},{"label":"win32","value":"win32"},{"label":"manage","value":"manage"},{"label":"native","value":"native"},{"label":"C++","value":"C++"}],"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"location":null,"local_seo":null,"breadcrumb_settings":null,"limit_modified_date":false,"ai":null,"created":"2021-03-18 21:12:20","updated":"2025-12-12 07:38:19","seo_analyzer_scan_date":null,"focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"author_meta":{"display_name":"Marius Bancila","author_link":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/"},"featured_img":null,"jetpack_publicize_connections":[],"uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false},"uagb_author_info":{"display_name":"Marius Bancila","author_link":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/"},"uagb_comment_info":3,"uagb_excerpt":"It is possible to host WPF controls in a Win32 application, and the other way around, but because of the differences betweeb these technologies there are various issues that can appear. One of these is handling of keyboard input. Without diving too much into differences between WPF and Win32, I will show how to provide&hellip;","coauthors":[],"tax_additional":{"categories":{"linked":["<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">C++<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/mfc\/\" class=\"advgb-post-tax-term\">MFC<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/windows-programming\/win32\/\" class=\"advgb-post-tax-term\">Win32<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/windows\/\" class=\"advgb-post-tax-term\">Windows<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/net\/wpf-net-software-it\/\" class=\"advgb-post-tax-term\">WPF<\/a>"],"unlinked":["<span class=\"advgb-post-tax-term\">C++<\/span>","<span class=\"advgb-post-tax-term\">MFC<\/span>","<span class=\"advgb-post-tax-term\">Win32<\/span>","<span class=\"advgb-post-tax-term\">Windows<\/span>","<span class=\"advgb-post-tax-term\">WPF<\/span>"]},"tags":{"linked":["<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/net\/wpf-net-software-it\/\" class=\"advgb-post-tax-term\">interop<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/net\/wpf-net-software-it\/\" class=\"advgb-post-tax-term\">MFC<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/net\/wpf-net-software-it\/\" class=\"advgb-post-tax-term\">tabstop<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/net\/wpf-net-software-it\/\" class=\"advgb-post-tax-term\">VC++<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/net\/wpf-net-software-it\/\" class=\"advgb-post-tax-term\">win32<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/net\/wpf-net-software-it\/\" class=\"advgb-post-tax-term\">WPF<\/a>"],"unlinked":["<span class=\"advgb-post-tax-term\">interop<\/span>","<span class=\"advgb-post-tax-term\">MFC<\/span>","<span class=\"advgb-post-tax-term\">tabstop<\/span>","<span class=\"advgb-post-tax-term\">VC++<\/span>","<span class=\"advgb-post-tax-term\">win32<\/span>","<span class=\"advgb-post-tax-term\">WPF<\/span>"]}},"comment_count":"3","relative_dates":{"created":"Posted 14 years ago","modified":"Updated 14 years ago"},"absolute_dates":{"created":"Posted on October 13, 2012","modified":"Updated on October 13, 2012"},"absolute_dates_time":{"created":"Posted on October 13, 2012 11:30 pm","modified":"Updated on October 13, 2012 11:30 pm"},"featured_img_caption":"","series_order":"","jetpack_shortlink":"https:\/\/wp.me\/pYNdv-lP","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts\/1353","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/comments?post=1353"}],"version-history":[{"count":20,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts\/1353\/revisions"}],"predecessor-version":[{"id":1373,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts\/1353\/revisions\/1373"}],"wp:attachment":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/media?parent=1353"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/categories?post=1353"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/tags?post=1353"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}