Ok, so I've given up on the two-control dialog and gone with two separate dialogs. (See the post "frustrations in using dialogs and controls" (http://discussion.forum.nokia.com/fo...d.php?t=124421) I just posted on this same discussion board.)
The first dialog is defined by the following resource:
KMaxExtensionDigits is defined as 8 in the app's .hrh file.Code:RESOURCE DIALOG r_authorisation_extension_query_dialog { flags = EGeneralQueryFlags; buttons = R_AVKON_SOFTKEYS_OK_CANCEL; items = { DLG_LINE { type = EAknCtQuery; id = EAuthQueryDlgExtensionEntryId; itemflags = EAknEditorFlagNoT9; control = AVKON_DATA_QUERY { layout = ENumberLayout; // class CAknIntegerEdwin can be instantiated based on a // AVKON_INTEGER_EDWIN control: control = AVKON_INTEGER_EDWIN { min = 0; unset_value = 0; maxlength = KMaxExtensionDigits; }; }; } }; }
The following code is from the view container class that instantiates the dialog:
The resource R_STRING_EXTENSION_PROMPT contains the instruction to the user to enter an extension number, since the DLG_LINE's prompt field is useless (see my post "frustrations in using dialogs and controls" just posted before this one). The resource R_AUTHORISATION_EXTENSION_QUERY_DIALOG is the dialog resource whose definition I gave above. (The idea here is to use the same CMobUiAuthorisationQueryDialog class for entering both the extension number, and, later, the PIN, just instantiated with a different resource ID. But that's beside the point here.)Code:TBool CMobUiAuthorisationViewContainer::HandleAuthorisation() { HBufC* iExtensionDigits( NULL ); HBufC* headerText = StringLoader::LoadLC( R_STRING_EXTENSION_PROMPT ); iAuthQueryDlg = new ( ELeave ) CMobUiAuthorisationQueryDialog( *headerText, EFalse, iExtensionDigits ); CleanupStack::PopAndDestroy( headerText ); iAuthQueryDlg->SetMopParent( this ); iAuthQueryDlg->ExecuteLD( R_AUTHORISATION_EXTENSION_QUERY_DIALOG ); //!!! continue... }
When the line iAuthQueryDlg->ExecuteLD is executed, the dialog comes up on the emulator screen, showing the instruction text and an edit box (= the control). I can enter digits into the edit box, and after the eighth one, no more are accepted, because of the maxlength definition in the dialog resource, as expected. When I press the OK softkey, the program execution moves to the following function:
Everything goes fine until the line I've marked with /* CRASH HERE: */. The function call ControlOrNull gives me a non-null pointer, which I presume is to the control identified by EAuthQueryDlgExtensionEntryId, which was used in the resource definition to identify the dialog line.Code:TBool CMobUiAuthorisationQueryDialog::OkToExitL( TInt aKeycode ) { switch ( aKeycode ) { case EAknSoftkeyOk: { if ( !iExtensionOrPin ) // I'm reusing the same code for the PIN dialog. // EFalse here just means we're executing the // dialog for entering an extension number. { // We're getting the extension number. Get the editor control: CAknIntegerEdwin* extensionEditor = static_cast< CAknIntegerEdwin* >( ControlOrNull( EAuthQueryDlgExtensionEntryId ) ); if ( extensionEditor == NULL ) { // something is very wrong if the control can't be accessed User::Leave( EMobilityUi ); } TInt enteredExtension; /* CRASH HERE: */ CAknNumericEdwin::TValidationStatus validationStatus = extensionEditor->GetTextAsInteger( enteredExtension ); if ( ( validationStatus != CAknNumericEdwin::EValueValid ) || ( enteredExtension == 0 ) ) { // Can't exit the dialog if nothing was entered, or if an // invalid set of digits were entered. return EFalse; } // discard any previous content of iEnteredDigits: delete iEnteredDigits; iEnteredDigits = NULL; iEnteredDigits = HBufC16::NewLC( 0 ); // convert the read integer to a string, while assigning the // result to the descriptor object owned by the caller: iEnteredDigits->Des().Format( KSingleIntegerFormatString, enteredExtension ); } else { // We're getting the PIN. Get the editor control: CAknNumericSecretEditor* passwordEditor = static_cast< CAknNumericSecretEditor* >( Control( EAuthQueryDlgPasswordEntryId ) ); //!! continue.... } return ETrue; // yes, dialog can exit if softkey OK pressed } case EAknSoftkeyCancel: { return ETrue; // yes, dialog can exit if softkey Cancel pressed } default: { return EFalse; // no, dialog can't exit otherwise } } }
What happens is that on the emulator screen, the error App. closed: Application Name EIKON-EDWIN 8 is displayed. EIKON-EDWIN 8 is apparently the ninth code (first one is 0) in enum TEikEdwinPanic in file epoc32\include\eikedwin.pan, namely EEikPanicEdwinNoText.
This is strange, as I most definitely did enter text into the control, and even if I hadn't, that should not be communicated by a panic, but rather by a value of EEmpty (of type CAknNumericEdwin::TValidationStatus) returned by the function GetTextAsInteger.
I googled for other mentions of people getting a panic of type EIKON-EDWIN 8, but found nothing useful. Someone mentioned that when an EDWIN control has been defined with a flag EEikEdwinUserSuppliedText, this problem might occur, but (a) this is an AVKON_INTEGER_EDWIN control, and (b) the flag I used was EGeneralQueryFlags, which is defined as EAknDialogGenericQueryFlags in avkon.hrh, which is defined as (EEikDialogFlagWait | EEikDialogFlagNoDrag | EEikDialogFlagNoTitleBar | EEikDialogFlagCbaButtons) in the same file; i.e., no EEikEdwinUserSuppliedText.
I thought that I was doing something wrong with the AVKON_INTEGER_EDWIN control, so tried, instead, an EDWIN control, and changed the code accordingly. Instead of calling extensionEditor->GetTextAsInteger, which is not available for the CEikEdwin class that goes with an EDWIN control, I called extensionEditor->GetTextInHBufL, which should simply return an HBufC* containing the entered text. Instead, when I tried to step over that line in the debugger, I got, again, a panic of type EIKON-EDWIN 8.
So, I'm stumped. What the hell am I doing wrong now? What undocumented or underdocumented little programming detail or details have I overlooked now? Please, anybody?!?



