{"id":2353,"date":"2010-03-08T23:00:00","date_gmt":"2010-03-08T23:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/visualstudio\/2010\/03\/08\/wpf-in-visual-studio-2010-part-3-focus-and-activation\/"},"modified":"2022-10-14T13:12:07","modified_gmt":"2022-10-14T20:12:07","slug":"wpf-in-visual-studio-2010-part-3-focus-and-activation","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/visualstudio\/wpf-in-visual-studio-2010-part-3-focus-and-activation\/","title":{"rendered":"WPF in Visual Studio 2010 \u2013 Part 3 : Focus and Activation"},"content":{"rendered":"<p>&nbsp;<\/p>\n<p>Continuing the <a href=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wpf-in-visual-studio-2010-part-1-introduction\/\">WPF in Visual Studio 2010<\/a> series, today\u2019s post is on the subject of \u201cFocus and Activation\u201d. Of all the problems we had to deal with in the new WPF UI, this was probably the most tricky to get right. Focus problems are notoriously hard to debug, partly because interacting with the debugger moves focus again. (Tip: Using a remote debugger helps.) Here I\u2019ll describe one class of focus problems we had to deal with in our move to a WPF UI.<\/p>\n<h3>What is focus?<\/h3>\n<p>For a desktop application, focus is (very) loosely defined as \u201cthe destination for keystrokes\u201d. When you press a key on the keyboard, it\u2019s the window or control which handles that keystroke. Focus moves around as users interact with the application but, at any time, it should be obvious where the focus is. This is usually indicated by a visual adornment, such as a <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/dd162479(VS.85).aspx\">dotted rectangle<\/a>, or by a blinking <a href=\"http:\/\/www.bing.com\/Dictionary\/search?q=caret\">caret<\/a>. Users shouldn\u2019t have to <a href=\"http:\/\/www.bing.com\/Dictionary\/search?q=intuit\">intuit<\/a> where the focus is and they get horribly confused if their keystrokes don\u2019t go where they think they should.<\/p>\n<h3>What is activation?<\/h3>\n<p>You may have many applications running on your Windows\u00ae desktop, but there\u2019s only ever one <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms632599(VS.85).aspx#active\">active window<\/a>. When you switch between applications using <a href=\"http:\/\/support.microsoft.com\/kb\/79869\">Alt+Tab<\/a> or clicking on their windows, you are changing the active window. Even WPF applications have a main window which is hosted on the desktop, so there\u2019s no exception there. For the most part activation is straightforward except when an application has more than one top-level windows. In addition to the main window, Visual Studio creates top-level windows for <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/z4y0hsax(VS.100).aspx\">floating document and tool windows<\/a>. When one of the floating windows is active, its caption changes color.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/4\/2019\/06\/image_2.png\"><img decoding=\"async\" title=\"image\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2010\/03\/image_thumb-3.png\" alt=\"image\" width=\"211\" height=\"30\" border=\"0\" \/><\/a><\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/4\/2019\/06\/image_4.png\"><img decoding=\"async\" title=\"image\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2010\/03\/image_thumb_1-2.png\" alt=\"image\" width=\"210\" height=\"29\" border=\"0\" \/><\/a><\/p>\n<p>The active window is remembered when the user switches to a different application so that it can be restored when the user switches back.<\/p>\n<h3>Foci <em>&#8211; <a href=\"http:\/\/dictionary.reference.com\/browse\/foci\"><strong>noun<\/strong>, pl. of focus<\/a><\/em><\/h3>\n<p>In an application, such as Visual Studio 2010, where we have a mixture of both WPF and Win32 content, there are two separate systems of focus, each with its own APIs.<\/p>\n<ul>\n<li>There\u2019s good old <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms646267(VS.85).aspx#_win32_Keyboard_Focus_and_Activation\">Win32 focus<\/a> with its attendant functions <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms646312(VS.85).aspx\">SetFocus<\/a>, <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms646294(VS.85).aspx\">GetFocus<\/a> and notifications <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms646283(VS.85).aspx\">WM_SETFOCUS<\/a> and <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms646282(VS.85).aspx\">WM_KILLFOCUS<\/a>.<\/li>\n<li>WPF has its own <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa969768(VS.100).aspx\">notion of focus<\/a> which is further augmented by the concept of \u201c<a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa969768(VS.100).aspx#Keyboard_Focus\">keyboard focus<\/a>\u201d, \u201cfocus scopes\u201d and \u201c<a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa969768(VS.100).aspx#Logical_Focus\">logical focus<\/a>\u201d.<\/li>\n<\/ul>\n<p>For the most part, you can simplify these two systems into:<\/p>\n<ol>\n<li>The HWND to which <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/dd458624(VS.85).aspx\">WM_KEY*<\/a> messages are dispatched and<\/li>\n<li>The \u201ckeyboard focused element\u201d in the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms753391.aspx#logical_tree\">WPF logical tree<\/a> to which WPF keyboard input is routed.<\/li>\n<\/ol>\n<p>Now, for a simple WPF application with one top-level window and no hosted HWNDs, these two models work well together. As far as Win32 is concerned, there\u2019s only one place the focus could be: the top-level HWND. As long as the application is active, all keystroke messages are dispatched to that window. Once the keystroke is dispatched, WPF\u2019s <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.windows.input.inputmanager.aspx\">InputManager<\/a> routes the message to the element with keyboard focus.<\/p>\n<p>For a WPF application with some hosted Win32 controls, at first things also work well. When focus is somewhere in WPF content, then the top-level WPF window gets all keyboard messages as before. When the user puts focus in a Win32 control, then it becomes the Win32 focused element (via a SetFocus call) and, from then on, keyboard messages are dispatched directly to that control.<\/p>\n<p>Things begin to break down when these two systems get out of sync, or when the visual cues given to the user don\u2019t match the application\u2019s current focus state.<\/p>\n<h3>Temporary Focus Scopes (Focus stealing and restoration)<\/h3>\n<p>Imagine you\u2019re typing in the Visual Studio text editor. The blinking caret indicates where your keystrokes will go. We could say that focus is \u201cin the text editor\u201d. In Visual Studio 2010, the text editor is part of the WPF tree, so keystroke messages are being dispatched to the WPF main window and WPF routes them to the element with keyboard focus. Now, let\u2019s say you press \u201cAlt+F\u201d to drop down the file menu. The file menu appears and the first enabled menu item is highlighted. The caret stops blinking in the text editor. Where should the focus be now?<\/p>\n<p>You could be forgiven if you said \u201cfocus should be in the menu\u201d \u2013 after all, the menu is just another WPF element and the next keystroke should affect the highlight in the menus. Indeed, looking deeper, the menu is a new top-level popup window with a distinct HWND and it should be possible to call SetFocus on that window and ensure that all keystrokes are dispatched there. For most WPF applications, this is in fact what happens. The WPF menu system takes keyboard focus and the text editor loses it.<\/p>\n<p>If you said \u201cfocus should stay in the text editor\u201d, then good for you! You may have said this if you\u2019re an advanced Win32 programmer, because that is, in fact, what happens with Win32 menus. When a Win32 menu is shown, it doesn\u2019t take focus. Instead, keyboard messages are intercepted and dispatched via a special \u201c<a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms647595(VS.85).aspx\">menu modal loop<\/a>\u201d. For as long as the menu is active, this menu modal loop dispatches messages directly to the menus even though Win32 focus is not there. This sounds like the kind of thing we want to happen too. Let\u2019s explore this a little more.<\/p>\n<p>Why should focus stay in the text editor? Because when a command is selected from the menu, we want it to behave just as if focus never left the text editor. Take the \u201cCut\u201d command, for example. When it executes, we want it to take the currently selected item (maybe a selection in the text editor, or a control on a graphical designer) and move it to the clipboard. To do this, focus had better not move around, otherwise we\u2019ll end up moving the wrong item. \u201cCut\u201d is bound to the Ctrl+X keyboard shortcut and that doesn\u2019t change focus, so it also shouldn\u2019t move focus if you interact with the menus. \u201cA-ha!\u201d, you might say, \u201cWPF could remember where focus is when the menu is first shown and, just before executing the command, it could put focus back there\u201d. True enough, that\u2019s what WPF does, but there\u2019s one, tiny little problem.<\/p>\n<p>Expanding on the \u201cCut\u201d example above, imagine that you\u2019re responsible for all the clipboard commands in Visual Studio. Part of that responsibility means you own the code which decides whether the Cut, Copy and Paste commands are available (<a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.windows.input.icommand.canexecute(VS.100).aspx\">CanExecute<\/a>) at any given time. This is so the appropriate menu items and toolbar buttons can be grayed out when the commands are not available.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/4\/2019\/06\/image_8.png\"><img decoding=\"async\" title=\"image\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2010\/03\/image_thumb_3-2.png\" alt=\"image\" width=\"244\" height=\"72\" border=\"0\" \/><\/a> <a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/4\/2019\/06\/image_10.png\"><img decoding=\"async\" title=\"image\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2010\/03\/image_thumb_4-1.png\" alt=\"image\" width=\"244\" height=\"76\" border=\"0\" \/><\/a><\/p>\n<p>The CanExecute logic is dependent on where the currently selected item is and that depends on where the focus is. If focus were \u201cin the menu\u201d when the Edit menu is dropped down, then the logic for the clipboard commands would be looking in the wrong place for selection. If focus stayed &#8220;in the text editor\u201d, then the CanExecute handlers would work as expected*.<\/p>\n<p>OK, I hope I\u2019ve convinced you that WPF menus should not steal focus when they become active. Since what we want is not WPF\u2019s default behavior, we have to override that behavior.<\/p>\n<h3>HwndSource.DefaultAcquireHwndFocusInMenuMode<\/h3>\n<p>Winning the prize for (quite probably) the longest new property name in WPF 4.0 is <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.windows.interop.hwndsource.defaultacquirehwndfocusinmenumode(VS.100).aspx\">HwndSource.DefaultAcquireHwndFocusInMenuMode<\/a>. The default value is \u2018true\u2019, so to prevent focus stealing, we set it to \u2018false\u2019:<\/p>\n<blockquote><p>\/\/ By default, WPF menus will acquire Win32 focus for the HwndSource in which they are contained.\n\/\/ This flag prevents WPF menus from acquiring Win32 focus when they receive WPF focus.\nHwndSource.DefaultAcquireHwndFocusInMenuMode = false;<\/p><\/blockquote>\n<p>As it happens, this is only half the story. WPF also needs to be told not to restore focus when leaving menu mode by adjusting another new WPF 4.0 property, <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.windows.input.keyboard.defaultrestorefocusmode(VS.100).aspx\">Keyboard.DefaultRestoreFocusMode<\/a>:<\/p>\n<blockquote><p>\/\/ Ensure that the MainWindow&#8217;s HwndSource and all subsequently-created\n\/\/ HwndSources on the UI thread have their RestoreFocusMode set appropriately.\nKeyboard.DefaultRestoreFocusMode = RestoreFocusMode.None;<\/p><\/blockquote>\n<p>These two settings combined will stop WPF taking Win32 focus (that\u2019s the \u201cHwndFocus\u201d part of the long property name) when interacting with menus. WPF still moves <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa969768(VS.100).aspx#Keyboard_Focus\">keyboard focus<\/a> to the menu and restores it when the menu is dismissed.<\/p>\n<p>But wait, there\u2019s more! \u201cMenuMode\u201d is a new concept in WPF 4.0 and, by default, attached to <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.windows.controls.menu(VS.100).aspx\">Menu<\/a> controls, but there are reasons to enter menu mode besides interacting with menus. Who\u2019s to say, with WPF at your disposal, that your application even has standard menus and toolbars? You may have an application with completely custom \u201cadministrative\u201d UI, but still need the capability to redirect all keyboard input temporarily. This is what MenuMode is for, and Visual Studio uses it for <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.windows.controls.toolbar(VS.100).aspx\">Toolbars<\/a>.<\/p>\n<p>To see this in action, think back to our clipboard example. The clipboard commands &#8211; cut, copy and paste \u2013 appear on the Standard toolbar:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/4\/2019\/06\/image_6.png\"><img decoding=\"async\" title=\"image\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2010\/03\/image_thumb_2.png\" alt=\"image\" width=\"80\" height=\"29\" border=\"0\" \/><\/a><\/p>\n<p>When the user clicks on, say, the Cut button, if focus moved away from the currently selected item, it would miss the very thing the user intends to cut to the clipboard. To have Toolbar participate in MenuMode behavior, we need to tell WPF to enter MenuMode when the toolbar would normally get focus and to leave MenuMode afterwards. The trick here is to use the \u201c<a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.windows.uielement.previewgotkeyboardfocus(VS.100).aspx\">PreviewGotKeyboardFocus<\/a>\u201d and the \u201c<a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.windows.uielement.lostkeyboardfocus(VS.100).aspx\">LostKeyboardFocus<\/a>\u201d events on the toolbar. Hopefully the following code snippets will get the idea across.<\/p>\n<p><strong>Markup (XAML):<\/strong><\/p>\n<blockquote><p>&lt;ToolBar Name=&#8221;toolBar1&#8243; PreviewGotKeyboardFocus=&#8221;toolBar1_PreviewGotKeyboardFocus&#8221;\nPreviewLostKeyboardFocus=&#8221;toolBar1_LostKeyboardFocus&#8221;&gt; &#8230;&lt;\/ToolBar&gt;<\/p><\/blockquote>\n<p><strong>Code:<\/strong><\/p>\n<blockquote><p>PresentationSource _menuSite;<\/p>\n<p>\/\/ Go into menu mode when the toolbar gets focus\nprivate void toolBar1_PreviewGotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)\n{\n_menuSite = HwndSource.FromVisual(this);\nInputManager.Current.PushMenuMode(_menuSite);\n}<\/p>\n<p>\/\/ Leave menu mode when the toolbar loses focus\nprivate void toolBar1_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)\n{\nInputManager.Current.PopMenuMode(_menuSite);\n_menuSite = null;\n}<\/p><\/blockquote>\n<p>In essence, when WPF tries to move keyboard focus to the toolbar, we tell it to enter MenuMode. When focus leaves the toolbar, we tell WPF to leave menu mode. Note that these two events are hooked to WPF\u2019s \u201ckeyboard focus\u201d which is still moved during MenuMode, even if Win32 focus movement is suppressed with DefaultAcquireHwndFocusInMenuMode.<\/p>\n<h3>Conclusion<\/h3>\n<p>There\u2019s a <a href=\"http:\/\/microsoftpdc.com\/Sessions\/CL09\">video of a presentation<\/a> I gave at <a href=\"https:\/\/devblogs.microsoft.com\/visualstudio\/visual-studio-sessions-at-pdc-09\/\">PDC last year<\/a> which covers this same topic, including a live demonstration (fast forward to timestamp 00:33:19) showing why MenuMode may be necessary and how to integrate it in your own application. Some of the code snippets in this article are taken from that demo.<\/p>\n<p>MenuMode is new for WPF 4.0 and, looking back, we wrestled for quite a while with focus problems and some exotic workarounds before realizing that a change in WPF was necessary. Even before we started work on Visual Studio 2010, we interviewed the Expression Web team about their experience with WPF and \u201cfocus bugs\u201d was called out as a risk. I remember giving a talk about a year ago at the <a href=\"http:\/\/www.mvpsummit2009.com\/\">MVP Summit<\/a> where I talked about our WPF conversion work (this was before Beta 1 was released) and I identified focus management as our most challenging unsolved problem. I\u2019m really proud that, between Beta 1 and Beta 2, the WPF team took up the challenge, worked with us to understand our needs, and developed the MenuMode solution. With that, a whole class of focus bugs was swept away.<\/p>\n<p>That\u2019s all for this part. Next time, <a href=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wpf-in-visual-studio-2010-part-4-direct-hosting-of-wpf-content\/\">Part 4: \u201cDirect Hosting of WPF content\u201d<\/a>.<\/p>\n<p>Previous posts in the series:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wpf-in-visual-studio-2010-part-1-introduction\/\">Part 1 : Introduction<\/a><\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wpf-in-visual-studio-2010-part-2-performance-tuning\/\">Part 2: Performance<\/a><\/p>\n<p>&nbsp;<\/p>\n<p><a id=\"Footnote1\"><\/a><em>*Actually, this still isn\u2019t quite the whole story for Visual Studio since it has its own <\/em><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/microsoft.visualstudio.shell.interop.ivsmonitorselection.aspx\"><em>selection tracking service<\/em><\/a><em>. However, consider the tricky case of in-place renaming of an item in the Solution Explorer. If you visit the Edit menu while renaming, the temporary edit control is not part of selection tracking and yet the clipboard commands still work correctly because we didn\u2019t let WPF steal focus. <\/em><\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/4\/2019\/06\/clip_image002_2.jpg\"><em><img decoding=\"async\" title=\"clip_image002\" src=\"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-content\/uploads\/sites\/4\/2010\/03\/clip_image002_thumb-2.jpg\" alt=\"clip_image002\" width=\"101\" height=\"101\" align=\"left\" border=\"0\" \/><\/em><\/a><\/p>\n<p><strong>Paul Harrington<\/strong> \u2013 Principal Developer, Visual Studio Platform Team\n<strong>Biography: <\/strong>Paul has worked on every version of Visual Studio .Net to date. Prior to joining the Visual Studio team in 2000, Paul spent six years working on mapping and trip planning software for what is today known as Bing Maps. For Visual Studio 2010, Paul designed and helped write the code that enabled the Visual Studio Shell team to move from a native, Windows 32-based implementation to a modern, fully managed presentation layer based on the Windows Presentation Foundation (WPF). Paul holds a master\u2019s degree from the University of Cambridge, England and lives with his wife and two cats in Seattle, Washington.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>&nbsp; Continuing the WPF in Visual Studio 2010 series, today\u2019s post is on the subject of \u201cFocus and Activation\u201d. Of all the problems we had to deal with in the new WPF UI, this was probably the most tricky to get right. Focus problems are notoriously hard to debug, partly because interacting with the debugger [&hellip;]<\/p>\n","protected":false},"author":13,"featured_media":255385,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1196,155],"tags":[20,133],"class_list":["post-2353","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-desktop","category-visual-studio","tag-wpf","tag-xaml"],"acf":[],"blog_post_summary":"<p>&nbsp; Continuing the WPF in Visual Studio 2010 series, today\u2019s post is on the subject of \u201cFocus and Activation\u201d. Of all the problems we had to deal with in the new WPF UI, this was probably the most tricky to get right. Focus problems are notoriously hard to debug, partly because interacting with the debugger [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/posts\/2353","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/users\/13"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/comments?post=2353"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/posts\/2353\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/media\/255385"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/media?parent=2353"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/categories?post=2353"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/tags?post=2353"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}