Wiley.Symbian.OS.C.plus.plus.for.Mobile.Phones.Aug.2007 (779890), страница 85
Текст из файла (страница 85)
Its default implementation is empty and youshould override it to perform any processing that may be necessary as theresult of the page change.16.6Dialog APIsThese simple dialogs are enough to show us that CEikDialog, forS60, and CQikSimpleDialog and CQikViewDialog, for UIQ, offer alarge range of framework functions, which you can override, and libraryfunctions, which you do not override but use to provide specific dialogprocessing. In this section, our quick tour of dialogs continues with anoverview of these APIs.Resource SpecificationsLet’s start with a closer look at the resource specification for dialogs. ForS60, you define a dialog using the DIALOG resource STRUCT.
A dialogresource might look like:STRUCT DIALOG{DIALOG APIs473LONG flags = 0;LTEXT title = "";LLINK pages = 0;LLINK buttons = 0;STRUCT items[];LLINK form = 0;}The flags for the dialog as a whole are specified in the flagsmember of the DIALOG structure. Flag bit values are defined by EEikDialogFlag constants in eikdialg.hrh.
Typical dialogs specifyEEikDialogFlagWait; other flags control such things as button positioning (right or bottom) and whether there is a title.The flags for a dialog line are specified in the flags member of theDLG_ITEM structure. Bit values for these flags are defined by EEikDlgItem constants in eikdialg.hrh; they allow you to specify that thereshould be a separator after the item, that the control doesn’t take focus,that it has no border, etc.When you develop a single-page dialog, you do not have to specifya pages member. For multi-page dialogs, pages members contain theresource definition for multiple pages.For UIQ, you have two options.
If you use the CQikSimpleDialogclass, you define a dialog using the QIK_DIALOG resource STRUCT:STRUCT QIK_DIALOG{BYTEversion = 0;LONGflags = 0;LTEXTtitle = "";LLINKicon = 0;STRUCT configurations[];LLINKcontrols = 0;}If you use CQikViewDialog, you define a dialog using QIK_VIEW_CONFIGURATION and QIK_CONTROL_COLLECTION resources:STRUCT QIK_VIEW_CONFIGURATION{BYTE version = 0;LONG ui_config_mode = 0;LLINK command_list = 0;LLINK view = 0;}STRUCT QIK_CONTROL_COLLECTION{STRUCT items[];}474DIALOGSFramework FunctionsCEikDialog, CQikSimpleDialog and CQikViewDialog provide arich API for derived dialog classes.
Many of the functions in the dialogAPI are either convenience functions that add to the API’s size withoutadding to its complexity or else they are for unusual requirements suchas constructing dialogs dynamically without using a resource file.S60 variantThe framework functions are a set of virtual functions that are calledwhen various events happen during dialog processing. If we want tohandle those events, we have to override the default function providedby CEikDialog. In each case, the default function does nothing.To set the control’s values and change its size and layout, we overridethe PreLayoutDynInitL() method, which is called before layout. Ifwe want to set the control values but not change the size and layout, weoverride the PostLayoutDynInitL() method, which is called afterlayout. The methods are defined as:virtual void PreLayoutDynInitL();virtual void PostLayoutDynInitL();We can control the way dialog’s component controls are constructedby overriding the CreateCustomControlL() method, which is calledwhen the control type indicated in the resource file is not recognized bythe control factory:virtual SEikControlInfo CreateCustomControlL(TInt aControlType);The OkToExitL() method has to be overridden if we want to changethe dialog behavior when the OK button is pressed.Sometimes, we may wish to do some processing when the user hasfinished working with one of the dialog’s lines.
Changes in time and dateeditors are not reported using HandleControlStateChangeL(), sowe need to intercept the event when the user changes the focused line.The solution is to provide an implementation for LineChangedL().The dialog automatically calls this function when the focused line changesand passes the ID of the control to which the focus is moving. We canfind out the ID of the control that currently has the focus by callingIdOfFocusControl():CExampleMyDialog::LineChangedL(TInt aControlId){TInt id = IdOfFocusControl();STOCK CONTROLS FOR DIALOGS475// Now do my stuff...}An older technique is to override the virtual PrepareForFocusTransitionL() method. It has a non-trivial default implementation,but it does not include a parameter specifying which line is currentlyfocused.
We override the function with:CExampleMyDialog::PrepareForFocusTransitionL(){CEikDialog::PrepareForFocusTransitionL();TInt id = IdOfFocusControl();// Now do my stuff...}We call the base-class implementation first; this leaves if the controlwith the current focus is not valid and is unable to lose focus. Thenwe call IdOfFocusControl() to get the control ID that is currentlyfocused.UIQ variantFor UIQ, we have to take into consideration the base class that we areusing to create dialogs: CQikSimpleDialog for simple dialogs andCQikViewDialog for complex dialogs. A big difference from the deprecated CEikDialog is that the layout in CQikSimpleDialog doesn’thave to be row-based and building blocks can be used as a layout.
InCQikSimpleDialog, you still find the PreLayoutDynInitL() andPostLayoutDynInitL() methods, but you do not find methods dealing with lines because of the differences in the layout. CQikViewDialogshould be treated more like a view.You can call the library functions in Table 16.1 from the frameworkfunctions.16.7 Stock Controls for DialogsA basic part of dialog programming is using stock controls in dialogs. Thegeneral techniques for using stock controls are:• specify a control type in the DLG_LINE struct, using type =• specify initialization data for the control in the DLG_LINE struct,using control= and an appropriate resource STRUCT• further initialize the control from PreLayoutDynInitL() or PostLayoutDynInitL()476DIALOGS• extract values from the control when needed, in OkToExitL() orother dialog processing functions• do other things, such as controlling the control’s visibility, using dialoglibrary functions.Table 16.1 Library FunctionsFunctionDescriptionCCoeControl* Control(TInt aControlId) const;Gets a pointer to the control whoseID is specified; panics if the ID doesnot existCCoeControl* ControlOrNull(TInt aControlId) const;Gets a pointer to the control whoseID is specified; returns 0 if the IDdoes not existCEikLabel* ControlCaption(TInt aControlId) const;Gets the caption associated with thecontrol whose ID is specifiedvoid SetLineDimmedNow(TInt aControlId,TBool aDimmed);Dims or un-dims a line; lines shouldbe dimmed if it is not currentlymeaningful to select themvoid MakeLineVisible(TInt aControlId,TBool aVisible);Makes the control on a line visible orinvisible (but does not change thevisibility of its caption)void MakeWholeLineVisible(TInt aControlId,TBool aVisible);Makes a whole line visible orinvisible, both the caption andcontrolTInt IdOfFocusControl()const;Gets the ID of the control withfocus–that is, the control currentlybeing usedvoid TryChangeFocusToL(TInt aControlId);Calls PrepareForFocusLossL()on the currently focused control and,if it does not leave, transfers focus tothe control whose ID is specified;this is the way to change focus: thecontrol with the focus should onlyrefuse the request if its state isinvalidUIQ provides 42 stock controls that you can use in dialogs.
Otheruser interfaces may have more or fewer, depending on the user interface design. In this section, we give a fast tour of those controls,including the resource STRUCT s you use to initialize them, and theirC++ classes.CUSTOM CONTROLS IN DIALOGS477Table 16.2 Stock Control Classes in UIQCEikHorOptionButtonListCEikLabeledButtonCQikSliderCQikVertOptionButtonListCQikSoundSelectorCQikTabScreenCQikTabScreenPageCQikNumericEditorCQikFloatingPointEditorCQikNumberEditorCEikAlignedControlCEikImageCEikLabelCEikBorderedControlCEikCalendarCEikClockCEikComboBoxCEikProgressInfoCEikSecretEditorCEikWorldSelectorCQikIpEditorCEikScrollBarCEikArrowHeadScrollBarCQikToolbarCQikScrollableContainerCQikTTimeEditorCQikDateEditorCQikDurationEditorCQikTimeEditorCQikTimeAndDateEditorCEikButtonBaseCEikCheckBoxCEikOptionButtonCEikCommandButtonBaseCEikTwoPictureCommandButtonCEikTextButtonCEikBitmapButtonCEikCommandButtonCEikMenuButtonCEikChoiceListBaseCQikColorSelectorCEikChoiceListCEikEdwinCEikGlobalTextEditorCEikRichTextEditorCEikListBoxCEikHierarchicalListBoxCEikTextListBoxCEikColumnListBoxAll the classes in Table 16.2 are ultimately derived from CCoeControl.
For the classes in the left-hand column the additional derivationis direct, while for those in the right-hand column it is indirect, viaCEikBorderedControl.16.8 Custom Controls in DialogsIn addition to the stock controls that are available, we may need toinclude a control of our own. To do so, carry out the following steps.1. Write the control and test it outside a dialog to make sure that itworks correctly.478DIALOGS2.If necessary, in an RH file, define a resource file struct associated withthe control, specifying the member names and types for the resourceinitialization data.3.Choose a value for the control type that is not used by any othercontrol and add its definition to an HRH file – a value of 0x1000 ormore is safe.4.In the resource file for the dialog, include a DLG_LINE struct thatspecifies the new control type value and includes the control’sresource struct, if it has one.5.If your control has a resource struct, implement the control’s ConstructFromResourceL() function to read initialization data infrom the struct.6.Implement the dialog’s CreateCustomControlL() function totest for the relevant control type, and construct and return an SEikControlInfo struct appropriate for your control.The custom dialog’s resource struct, in an RH file, normally providesdefault values for its members, as in the following example:STRUCT MYCUSTOMCONTROL{WORD width = 100;WORD height = 50;}The control type needs to be defined in an HRH file since it needs tobe #included in both the resource file and one or more C++ sourcefiles.
It is typically defined as an enumeration:enum{EMyCustomControl = 0x1000}enum{EMyControlId}An enumeration also defines the control’s ID, needed for any controlwithin a dialog.The following dialog resource is for an S60 dialog, so we omit aspecification of the dialog’s title and use one of the standard Avkon buttoncombinations. We also replace the default value for the control’s width:CUSTOM CONTROLS IN DIALOGS479RESOURCE DIALOG r_mycustomcontrol_dialog{buttons = R_AVKON_SOFTKEYS_OK_CANCEL;items ={DLG_LINE{type = EMyCustomControl;id = EMyControlId;control = MYCUSTOMCONTROL{width = 200;};}};}The ConstructFromResourceL() function of the custom controlis similar to the ConstructL() function of a normal control, exceptthat the data is read from the resource file.