|
1 <?xml version="1.0" encoding="utf-8"?> |
|
2 <!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. --> |
|
3 <!-- This component and the accompanying materials are made available under the terms of the License |
|
4 "Eclipse Public License v1.0" which accompanies this distribution, |
|
5 and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". --> |
|
6 <!-- Initial Contributors: |
|
7 Nokia Corporation - initial contribution. |
|
8 Contributors: |
|
9 --> |
|
10 <!DOCTYPE concept |
|
11 PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd"> |
|
12 <concept id="GUID-CFC70204-1AD4-5DF0-ADDC-CDE4B39CFF96" xml:lang="en"><title>Simulating |
|
13 and intercepting key events</title><prolog><metadata><keywords/></metadata></prolog><conbody> |
|
14 <section id="GUID-EC0588AB-A48E-42A8-A149-315B36DBE493"><title>Simulating |
|
15 key events</title> <p>Simulating key events is done by calling <xref href="GUID-ADAA039A-7BF3-3B06-8486-2E3604C2633D.dita"><apiname>CCoeFep</apiname></xref> ’s |
|
16 member function <codeph>SimulateKeyEventsL()</codeph>; this sends to the application |
|
17 a key event for each of the items in the array passed to it. There are two |
|
18 overloads of <codeph>SimulateKeyEventsL()</codeph>: in the first and most |
|
19 commonly used overload, only the character codes of the key events are specified; |
|
20 in the second overload, modifier keys can also be specified for each key event |
|
21 to be simulated. The header file <filepath>epoc32\include\E32KEYS.H</filepath> defines |
|
22 the various modifiers possible. The FEP author needs to derive from <codeph>CCoeFep::MModifiedCharacter</codeph> in |
|
23 order to use the second overload of <codeph>SimulateKeyEventsL()</codeph>, |
|
24 implementing all three of its pure virtual functions. The <codeph>ModifierMask()</codeph> function |
|
25 returns the modifiers whose value the FEP wishes to specify; the values for |
|
26 the modifiers are returned by the <codeph>ModifierValues()</codeph> function. <codeph>ModifierValues()</codeph> should |
|
27 not return values for any modifiers that are not also returned by <codeph>ModifierMask()</codeph>. </p> <p>For |
|
28 example, supposing a FEP wishes to send a key event to an application with |
|
29 the <userinput>func</userinput> modifier on and the <userinput>shift</userinput> modifier |
|
30 off. In this case the <codeph>ModifierMask()</codeph> function would return <codeph>EModifierFunc|EModifierShift</codeph> and |
|
31 the <codeph>ModifierValues()</codeph> function would return <codeph>EModifierFunc</codeph>. |
|
32 The resulting key event received by the application would then have the <codeph>EModifierFunc</codeph> modifier |
|
33 on and the <codeph>EModifierShift</codeph> modifier off (even if the shift |
|
34 key is being pressed down). All the other modifiers in the key event, since |
|
35 they were not returned in the <codeph>ModifierMask()</codeph> function, will |
|
36 reflect the current state of the keyboard. </p> </section> |
|
37 <section id="GUID-1B15C661-851B-5922-B8BC-7A772232DBD2"><title>Intercepting |
|
38 key events</title> <p>In order for a FEP to intercept key events before they |
|
39 reach the application beneath them, the FEP control must be added to the control |
|
40 stack at a high priority. This is done by using the following code in the |
|
41 control’s construction routine: </p> <codeblock id="GUID-1734E8DC-BB49-5EB9-B373-F8B4A8B92809" xml:space="preserve">STATIC_CAST(CCoeAppUi*, iCoeEnv->AppUi())->AddToStackL(this, ECoeStackPriorityFep, ECoeStackFlagRefusesFocus|ECoeStackFlagSharable);</codeblock> <p>and the following code in its destructor: </p> <codeblock id="GUID-D5BF8AAB-6BEA-5CF5-AE66-488CC2C44654" xml:space="preserve">STATIC_CAST(CCoeAppUi*, iCoeEnv->AppUi())->RemoveFromStack(this);</codeblock> <p>Passing the flag <codeph>ECoeStackFlagSharable</codeph> to <codeph>AddToStackL()</codeph> ensures |
|
42 that if an embedded object is edited from an application, for instance an |
|
43 embedded drawing is edited inside a word processor document, the FEP’s control |
|
44 will also be put onto the child application’s control stack when the child |
|
45 application is started. More importantly, the <codeph>ECoeStackFlagRefusesFocus</codeph> flag |
|
46 should be passed to <codeph>AddToStackL()</codeph> because FEPs in general |
|
47 should not “steal” focus from the target underneath them. For the same reason, <codeph>SetNonFocusing()</codeph> (a |
|
48 member function of <xref href="GUID-B06F99BD-F032-3B87-AB26-5DD6EBE8C160.dita"><apiname>CCoeControl</apiname></xref>) should be called in the |
|
49 control’s construction routine to prevent mouse or pen events from giving |
|
50 it focus. On some occasions it may be legitimate for the FEP to take the focus, |
|
51 for instance if the FEP has a floating window and it is temporarily in a mode |
|
52 where the user can move this window around the screen by using the arrow keys. |
|
53 In this case, the FEP’s control can take the focus by calling: </p> <codeblock id="GUID-183A9459-B8F1-5D7F-897E-3B5278B8BEE1" xml:space="preserve">CCoeAppUi& appUi=*STATIC_CAST(CCoeAppUi*, iCoeEnv->AppUi()); |
|
54 appUi.UpdateStackedControlFlags(this, 0, ECoeStackFlagRefusesFocus); |
|
55 appUi.HandleStackChanged(); |
|
56 </codeblock> <p>The following code causes the FEP’s control to revert to normal |
|
57 operation by losing focus: </p> <codeblock id="GUID-D5C24301-9D84-5D62-9E75-4B17892316B2" xml:space="preserve">CCoeAppUi& appUi=*STATIC_CAST(CCoeAppUi*, iCoeEnv->AppUi()); |
|
58 appUi.UpdateStackedControlFlags(this, ECoeStackFlagRefusesFocus, ECoeStackFlagRefusesFocus); |
|
59 appUi.HandleStackChanged(); |
|
60 </codeblock> <p>Adding the FEP’s control to the control stack at priority <codeph>ECoeStackPriorityFep</codeph> means |
|
61 that it gets first refusal of all key events. The UI framework offers key |
|
62 events to the FEP control by calling its <codeph>OfferKeyEventL()</codeph> virtual |
|
63 function (although key events for a FEP over an OPL application follow a different |
|
64 route, described below). The signature of this virtual function, which is |
|
65 first declared in <xref href="GUID-B06F99BD-F032-3B87-AB26-5DD6EBE8C160.dita"><apiname>CCoeControl</apiname></xref>, is: </p> <codeblock id="GUID-7823A4B2-AC86-502E-8609-9277F748C64F" xml:space="preserve">TKeyResponse OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType);</codeblock> <p>The first thing that should be done at the start of <codeph>OfferKeyEventL()</codeph> is |
|
66 to call either of the two macros below, both of which are defined in <filepath>epoc32\include\FEPBASE.H</filepath>: </p> <codeblock id="GUID-84B500B8-7B35-5E6D-8C54-77AA59C4FCD7" xml:space="preserve">#define FEP_START_KEY_EVENT_HANDLER_L(aFep, aKeyEvent, aEventCode) |
|
67 #define FEP_START_KEY_EVENT_HANDLER_NO_DOWN_UP_FILTER_L(aFep, aKeyEvent, aEventCode) |
|
68 </codeblock> <p>The <codeph>aFep</codeph> parameter must be a <xref href="GUID-ADAA039A-7BF3-3B06-8486-2E3604C2633D.dita"><apiname>CCoeFep</apiname></xref> object. |
|
69 Note that it should not be a pointer to a <xref href="GUID-ADAA039A-7BF3-3B06-8486-2E3604C2633D.dita"><apiname>CCoeFep</apiname></xref>. The <codeph>aKeyEvent</codeph> and |
|
70 the <codeph>aEventCode</codeph> parameters should be respectively the <xref href="GUID-0F8FA6A3-F172-36E4-9CF5-60814ABCD562.dita"><apiname>TKeyEvent</apiname></xref> and |
|
71 the <xref href="GUID-420348F5-4A82-3780-9D27-A3E1F4780F0B.dita"><apiname>TEventCode</apiname></xref> parameters of the <codeph>OfferKeyEventL()</codeph> function |
|
72 itself. The <codeph>OfferKeyEventL()</codeph> function should only be returned |
|
73 from by calling either of the following two macros (these are also defined |
|
74 in <filepath>epoc32\include\FEPBASE.H</filepath>): </p> <codeblock id="GUID-AE03275F-FBD7-52AF-B7CC-C6F6707B9FDC" xml:space="preserve">#define FEP_END_KEY_EVENT_HANDLER_L(aFep, aKeyEvent, aKeyResponse) |
|
75 #define FEP_END_KEY_EVENT_HANDLER_NO_DOWN_UP_FILTER_L(aFep, aKeyEvent, aEventCode, aKeyResponse) |
|
76 </codeblock> <p>Both of these two macros contain a <codeph>return</codeph> statement, |
|
77 so the <codeph>return</codeph> C++ keyword should not occur in the <codeph>OfferKeyEventL()</codeph> function |
|
78 at all. Note that the macro used at the start of the <codeph>OfferKeyEventL()</codeph> function |
|
79 should match the macro used to return from it; in other words, both should |
|
80 be of the <i>no-down-up-filter</i> type or neither should be. The <i>no-down-up-filter</i> variants |
|
81 should be used if the FEP wishes to handle <codeph>EEventKeyDown</codeph> or <codeph>EEventKeyUp</codeph> events. |
|
82 This is likely to be rare, however; most FEPs are probably only interested |
|
83 in <codeph>EEventKey</codeph> events, in which case <codeph>FEP_START_KEY_EVENT_HANDLER_L</codeph> and <codeph>FEP_END_KEY_EVENT_HANDLER_L</codeph> should be used. These variants filter out <codeph>EEventKeyDown</codeph> and <codeph>EEventKeyUp</codeph> events |
|
84 so that the FEP only receives <codeph>EEventKey</codeph> events. </p> <p>The |
|
85 first three parameters of the <codeph>FEP_END_KEY_EVENT_HANDLER_</codeph> <i>XXX</i> macros |
|
86 are the same as for the <codeph>FEP_START_KEY_EVENT_HANDLER_</codeph> <i>XXX</i> macros. |
|
87 The fourth parameter should be a <xref href="GUID-2AE56EA4-C71E-33FA-8FCE-D2D15453CD10.dita"><apiname>TKeyResponse</apiname></xref> value (an |
|
88 enum defined in <filepath>epoc32\include\COEDEF.H</filepath>). Specifying <codeph>EKeyWasNotConsumed</codeph> as |
|
89 this fourth parameter allows that key event to 'fall through' to the application, |
|
90 whereas specifying <codeph>EKeyWasConsumed</codeph> prevents the application |
|
91 from receiving that event. A good rule of thumb for a FEP that takes key events |
|
92 as its input is to intercept as few key events as possible when not inside |
|
93 a FEP transaction, but once inside a transaction to block all key events from |
|
94 getting through to the application. A transaction may be defined as the composition |
|
95 and abandoning/committing of a piece of text ('committing' means sending it |
|
96 on to the application). For a Japanese FEP, that piece of text may be an entire |
|
97 sentence, whereas for a Chinese FEP it may be just one or two characters. </p> <p>For |
|
98 a FEP running over an OPL application, the <codeph>OfferKeyEventL()</codeph> virtual |
|
99 function declared in <xref href="GUID-ADAA039A-7BF3-3B06-8486-2E3604C2633D.dita"><apiname>CCoeFep</apiname></xref> will get called. This is a |
|
100 completely independent function from <xref href="GUID-B06F99BD-F032-3B87-AB26-5DD6EBE8C160.dita"><apiname>CCoeControl</apiname></xref> ’s virtual |
|
101 function of the same name, and it has a different signature which is as follows: </p> <codeblock id="GUID-6760C373-FB46-53E5-96ED-A8273126B060" xml:space="preserve">void OfferKeyEventL(TEventResponse& aEventResponse, const TKeyEvent& aKeyEvent, TEventCode aEventCode);</codeblock> <p>This virtual function should be implemented in exactly the same way as <xref href="GUID-B06F99BD-F032-3B87-AB26-5DD6EBE8C160.dita"><apiname>CCoeControl</apiname></xref> ’s <codeph>OfferKeyEventL()</codeph>, |
|
102 the meaning of the <codeph>aKeyEvent</codeph> and <codeph>aEventCode</codeph> parameters |
|
103 being the same as for <xref href="GUID-B06F99BD-F032-3B87-AB26-5DD6EBE8C160.dita"><apiname>CCoeControl</apiname></xref> ’s <codeph>OfferKeyEventL()</codeph>. |
|
104 The <codeph>aEventResponse</codeph> parameter should be set by the function |
|
105 overriding <codeph>CCoeFep::OfferKeyEventL()</codeph> to either <codeph>CCoeFep::EEventWasNotConsumed</codeph> or <codeph>CCoeFep::EEventWasConsumed</codeph>, and this must be done before any function that can leave is called. </p> </section> |
|
106 </conbody></concept> |