Internet Explorer programming Overview (12) correctly set and transfer focus

Source: Internet
Author: User

Keywords: Focus, focus, acceleration key, accelerator, oleiverb_uiactivate, ihtmlwindow2, ihtmldocument4 1. Overview for Windows applications with UI in 99%, keyboard operations are indispensable and easy to forget. If you perform a one-by-one test on Windows Components, we will find that all Windows components provided by Microsoft are fully controlled through the keyboard (the "Calculator" is special, it is a program with many buttons and each button cannot get the focus, but we can still find the shortcut keys for each button in the help document ), this is very important for a professional windows application or software. In other words, users should not be helpless even if they do not have a mouse. Users should be able to complete the desired functions through keyboard operations. The transfer of focus is undoubtedly an important aspect of keyboard operations, especially in browser programming. 2. Basic concepts of focus: in windows, there are two methods for transferring focus through the keyboard: first, there is a tag prompt near the input box, press and hold Alt + a preset letter (accelerator, accelerator key) to quickly move the focus to the input box. As shown in, press "Alt + D", the focus should be transferred to the address input box; press "Alt + G", and the focus should be transferred to the search box (this article will not discuss this ). Second, press and hold the tab key to move the focus to the next window controlled by the application that can get the focus. Press SHIFT + TAB to move the focus to the previous window that can get the focus. As shown in, if the address input box is the window with the current focus, when you press tab, the focus should be transferred to the search box, and then SHIFT + tab, and the focus should return to the address input box.

Focus setting and transfer is a considerate and important design for user experience, but unfortunately many Windows applications make more or less mistakes:
  1. There is no acceleration key at all.
This is especially common in Chinese information systems. Poor information systems often have dozens of input boxes in a window. If an acceleration key is provided for each edit box, the problem arises. There are only 26 primary keys, and even the number keys are used, they cannot meet the requirements. Therefore, many information systems simply do not need acceleration keys.
  1. The acceleration key used for the configuration.
Some applications do not even know the significance of the acceleration key. They only know that the acceleration key is marked by a tag next to the input box, but that's all, you cannot transfer the focus to the input box through Alt + acceleration.
  1. Transfer focus incorrectly (or not)
For dialog box-based applications, the common mistake is that when a user presses the tab key, the focus is unexpected. In such an example, the common mistake is that the focus cannot be transferred by tab, or the focus can be transferred by tab, but the focus cannot be transferred by SHIFT + TAB.
  1. Lack of processing for embedded ActiveX Controls
For embedded ActiveX controls, especially webbrowser controls, focus processing is even more troublesome (this is one of the difficulties in browser Programming Based on webbrowser ). Common browsers either do not process the focus transfer between the conventional window and the webbrowser control (Maxthon and gosurf only support the transfer of focus between input boxes); or they are incomplete, once the focus is transferred from an input box to the webbrowser control, it will no longer be returned (such as greenbrowser); more importantly, it will not process any focus transfer (such as window of the world browser ). According to the conventions of this series of articles, the purpose of this article is to provide a complete (not necessarily perfect) solution-1. Focus on transmission between input boxes embedded in rebar; 2, the focus is transmitted between the common Windows window (input box) and the webbrowser control. 3. Setting goals shows the normal focus transfer behavior we want to achieve:
  • Start from any input box on the toolbar, press tab to move focus to the next input box, and press SHIFT + TAB to move focus to the previous input box
  • If the focus field is the last input box on the toolbar, press tab to move the focus to the current active HTML element of the webbrowser control (the last element that gets the focus)
  • If the focus field is the first input box on the toolbar, press SHIFT + TAB to move the focus to the current HTML element of the webbrowser control.
  • In the preceding two cases, if the webbrowser control does not have the currently active HTML element, the focus should be transferred from the input box to the first or last HTML element of the webbrowser control.
  • If the focus is currently in the webbrowser control, press tab to move the focus to the next HTML element, and press SHIFT + TAB to move the focus to the previous HTML element.
  • If the focus is currently in the webbrowser control, and the current active HTML element is the last HTML element that can obtain the focus, press tab to move the focus to the first input box of the toolbar.
  • If the focus is currently in the webbrowser control and the current active HTML element is the first HTML element that can obtain the focus, press shif + TAB to move the focus to the final input box of the toolbar.
For example, "Google Daquan" is the HTML element with the current focus of webbrowser, for example:
  • Example 1: if the current focus is in the address input box, press the tab key and do not release it. The focus shift sequence should be: "address bar", "search bar", "Google Daquan "...... "Set Google as Homepage", "address bar", "search bar", "personalized homepage", "search records "......
  • Example 2: assume that the current focus is in the address input box, And the webbrowser control does not have an active HTML element that obtains the focus. Press the tab key and do not release it. The focus Transfer sequence should be "address bar ", "search bar", "personalized homepage", "search records "...... "Set Google as Homepage", "address bar ",......
  • Example 3: assume that the current focus is on the "search record" and the shift + Tab key is not released. The focus shift sequence should be: "search record" and "personalized homepage ", "search bar", "address bar", "set Google as the homepage "...... "Search records "......
 

4. Focus is transferred between the input boxes of the toolbar to achieve unified processing. We derive a cdialogbarex class from cdialogbar, which processes the tab and shift tab buttons, while the input boxes (such as editbox and ComboBox) put it in the derived class of cdialogbarex (such as curladdressbar and csearchbar), so that the input box can focus on other functions. The sample code is as follows:
Bool cdialogbarex: pretranslatemessage (MSG * PMSG ){ If(PMSG-> message = wm_keydown )){ If(PMSG-> wparam = vk_tab) {// how to transfer the focus by mainframe, press shift to indicate that the focus should be transferred to the previous window g_pmainframe-> setfocustonextcontrol (getkeystate (vk_shift)> = 0); Return true ;}}...... ReturnCdialogbar: pretranslatemessage (PMSG );} VoidCmainframe: setfocustonextcontrol ( BoolBnext) {// m_wndrebar is a crebarex, which can be derived from the crebar if (! M_wndrebar.setfocustonextcontrol (bnext) {// If the crebarex cannot find the next (upper) window in its subwindow, the focus is transferred to webbrowsercchildframe * pchildframe = (cchildframe *) mdigetactive (); If(Pchildframe & pchildframe-> getactiveview () {pchildframe-> getactiveview ()-> setfocus ();}}} BoolCrebarex: setfocustonextcontrol ( BoolBnext ){ ReturnBnext? Focusnextcontrol (): focusprevcontrol ();} BoolCrebarex: focusnextcontrol () {rebarbandinfo rbbi; rbbi. cbsize = sizeof (rbbi); rbbi. fmask = rbbim_child; // first find the banduint nband with the current focus; For(Nband = 0; nband <m_rbctrl.getbandcount (); nband ++) {verify (m_rbctrl.getbandinfo (nband, & rbbi); If (: ischild (rbbi. hwndchild,: getfocus () {break ;}// if you run it here, you must be able to find the bandassert (nband <m_rbctrl.getbandcount () with the current focus ()); For(Nband = nband + 1; nband <m_rbctrl.getbandcount (); nband ++) {verify (m_rbctrl.getbandinfo (nband, & rbbi);: setfocus (rbbi. hwndchild ); If(: Ischild (rbbi. hwndchild,: getfocus () {// you have found and set the focus to the next window. Return True; }}// The current focus window is the last focus window in rebarex. Return False;} Bool crebarex: focusprevcontrol () {// similar to focusnextcontrol, skipped here} VoidCrebarex: onsetfocus (cwnd * poldwnd) {// If shift is in the pressed state, the focus may be transferred from the first active HTML element of webbrowser, // The focus is transferred to the last input box. Otherwise, the focus is transferred to the first input box. // The implementation of setfocustolastcontrol and setfocustofirstcontrol is quite simple and omitted. ReturnGetkeystate (vk_shift) <0? Setfocustolastcontrol (): setfocustofirstcontrol ();}
5. The transfer of focus from webbrowser to tool bar input box processing buttons in the browser was also one of the programming difficulties embedded in the webbrowser control. Delphi's encapsulation of webbrowser has a great problem in supporting buttons. The method mentioned in programming Internet Explorer is to process the pretranslatemessage of mainframe, obtain the ioleinplaceactiveobject interface from the document query of webbrowser, and send the buttons to the translateaccelerator member area of ioleinplaceactiveobject for processing. When ioleinplaceactiveobject: translateaccelerator is called, The mshtml engine calls the translateaccelerator method of the idochostuihandler interface to provide developers with an interface to process keys. So for applications that implement the idochostuihandler interface, it is very easy to press the button.
// Transfer the focus from webbrowser to the input box hresult cmyview: ontranslateaccelerator (lpmsg, const guid * pguid1_group, DWORD n1_id ){ If(Lpmsg & lpmsg-> message = wm_keydown & lpmsg-> wparam = vk_tab) {lpdispatch = gethtmldocument (); ccomqiptr <ihtmldocument2> phtmldoc = lpdispatch; If(Phtmldoc) {ccomqiptr <ihtmlelement> pelement; If(Succeeded (phtmldoc-> get_activeelement (& pelement ))&&! Pelement) {// html element without any activity, move the focus to rebarg_pmainframe-> m_wndrebar.setfocus (); // notify mshtml not to proceed with the button ReturnS_ OK ;}}} ReturnS_false ;}
6. Make webbrowser focus so that the browser can focus on it. I wrote in an old article twebbrowser programming briefing that there are several ways to make webbrowser focus: ioleobject: doverb (oleiverb_uiactivate ...) ihtmlwindow2: Focus (), ihtmldocument4: Focus (). In fact, there are differences between these methods (we do not know the internal implementation, nor care about it ).
  • Ioleobject: doverb can set the focus to the HTML element that gets the focus when the focus is lost in webbrowser. The disadvantage is that if webbrowser does not get the focus of any HTML element when it loses the focus last time, doverb cannot guarantee that the focus will be transferred to webbrowser.
  • Ihtmlwindow2: focus, regardless of November 21, transfers the focus to the HTML element starting with webbrowser. This is obviously not what we want.
  • In the test result, ihtmldocument4: focus seems to be able to meet the requirements: Be able to remember the HTML element that gets the focus when webbrowser lost the focus last time; when webbrowser loses focus last time and no HTML element obtains focus, the focus can be shifted to the HTML element at the beginning. But in fact it is not ideal. If you press and hold the tab key and call ihtmldocument4: Focus multiple times, we will find that the focus is no longer in the webbrowser.
Is there a perfect solution? The answer is positive, as shown below:
VoidCmyview: onsetfocus (cwnd * poldwnd) {lpdispatch lpdisp = gethtmldocument (); ccomqiptr <ihtmldocument2, & iid_ihtmldocument2> phtmldoc (lpdisp ); If(Phtmldoc) {ccomqiptr <ihtmlelement> pelement; If(Succeeded (phtmldoc-> get_activeelement (& pelement ))&&! Pelement) {// No activity element. Move the focus to the beginning of webbrowser ccomqiptr <ihtmlwindow2> phtmlwnd; If(Succeeded (phtmldoc-> get_parentwindow (& phtmlwnd) {phtmlwnd-> focus (); Return;}}// An active element (the previous focus) is directly transferred over the focus. // cwnd: setfocus () will call ioleobject: doverb () set focus correctly m_wndbrowser.setfocus ();}
7. So far, even if we fully implement the transfer of the focus between the common window and the browser, press and hold the tab key at any time and do not release it, focus will be transmitted cyclically between all windows with available focus. Similarly, if you press shift-tab, the focus will be transmitted in the opposite direction. The user cannot transfer the focus to the browser window, or the focus cannot be transferred from the browser window to the input box. Of course, there is another important and abstract point that enhances the user experience. 8. References: programming Internet Explorer Reference address: Internet Explorer programming Overview (12) Correctly Setting and transferring focus points
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.