why do I get panic EIKON-EDWIN 8 when trying to use an AVKON_INTEGER_EDWIN control?
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" ([url]http://discussion.forum.nokia.com/forum/showthread.php?t=124421[/url]) I just posted on this same discussion board.)
The first dialog is defined by the following resource:
[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;
};
};
}
};
}
[/CODE]
[B]KMaxExtensionDigits[/B] is defined as 8 in the app's .hrh file.
The following code is from the view container class that instantiates the dialog:
[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...
}
[/CODE]
The resource [b]R_STRING_EXTENSION_PROMPT[/b] contains the instruction to the user to enter an extension number, since the DLG_LINE's [b]prompt[/b] field is useless (see my post "frustrations in using dialogs and controls" just posted before this one). The resource [B]R_AUTHORISATION_EXTENSION_QUERY_DIALOG[/b] 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.)
When the line [b]iAuthQueryDlg->ExecuteLD[/b] 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 [b]maxlength[/b] definition in the dialog resource, as expected. When I press the OK softkey, the program execution moves to the following function:
[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
}
}
}
[/CODE]
Everything goes fine until the line I've marked with [b]/* CRASH HERE: */[/b]. The function call [b]ControlOrNull[/b] gives me a non-null pointer, which I presume is to the control identified by [b]EAuthQueryDlgExtensionEntryId[/b], which was used in the resource definition to identify the dialog line.
What happens is that on the emulator screen, the error [b]App. closed: Application Name EIKON-EDWIN 8[/b] is displayed. [b]EIKON-EDWIN 8[/b] is apparently the ninth code (first one is 0) in [b]enum TEikEdwinPanic[/b] in file [b]epoc32\include\eikedwin.pan[/b], namely [b]EEikPanicEdwinNoText[/b].
This is strange, as I most definitely did enter text into the control, [i]and even if I hadn't,[/i] that should not be communicated by a panic, but rather by a value of [b]EEmpty[/b] (of type [b]CAknNumericEdwin::TValidationStatus[/b]) returned by the function [b]GetTextAsInteger[/b].
I googled for other mentions of people getting a panic of type [b]EIKON-EDWIN 8[/b], but found nothing useful. Someone mentioned that when an EDWIN control has been defined with a flag [b]EEikEdwinUserSuppliedText[/b], this problem might occur, but (a) this is an AVKON_INTEGER_EDWIN control, and (b) the flag I used was [b]EGeneralQueryFlags[/b], which is defined as [b]EAknDialogGenericQueryFlags[/b] in avkon.hrh, which is defined as [b](EEikDialogFlagWait | EEikDialogFlagNoDrag | EEikDialogFlagNoTitleBar | EEikDialogFlagCbaButtons)[/b] in the same file; i.e., no [b]EEikEdwinUserSuppliedText[/b].
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 [b]extensionEditor->GetTextAsInteger[/b], which is not available for the [b]CEikEdwin[/b] class that goes with an EDWIN control, I called [b]extensionEditor->GetTextInHBufL[/b], which should simply return an [b]HBufC*[/b] containing the entered text. Instead, when I tried to step over that line in the debugger, I got, again, a panic of type [b]EIKON-EDWIN 8[/b].
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?!?
Re: why do I get panic EIKON-EDWIN 8 when trying to use an AVKON_INTEGER_EDWIN contro
Update: googling for the problem reveals that others have experienced this problem. Nickname "wowman" was trying to do the very same thing I was, and writes at [url]http://discussion.forum.nokia.com/forum/showthread.php?t=72150:[/url]
[quote]
I'm trying to retrieve an integer value from a DLG_LINE on a S60 device. Below is a sample from my *.rss file that defines a part of the interface.
[code]
DLG_LINE
{
type = EAknCtQuery;
id = EGeneralAmountQuery;
control = AVKON_DATA_QUERY
{
layout = ENumberLayout;
label = "Amount (£):";
control = AVKON_INTEGER_EDWIN
{
min = 1;
max = 10;
unset_value=0;
};
};
}
[/code]
I use the following code to obtain a reference to the editor, and then call GetTextAsInteger(Tint x) to retrieve the value entered by the user.
[code]
CAknIntegerEdwin* amountEditor = static_cast<CAknIntegerEdwin*>(ControlOrNull(EGeneralAmountQuery));
if (amountEditor)
{
CAknNumericEdwin::TValidationStatus amountStatus = amountEditor->GetTextAsInteger(tmpAmount);
}
[/code]
The above code causes a runtime error. I found that this is caused by the nested control struct in the DLG_LINE. If I remove the outer control struct (and therefore also the label and layout fields of that struct) the code works fine and the values can be retrieved.
All books and online examples seem to have an outer control struct of type AVKON_DATA_QUERY with an inner control struct of type AVKON_INTEGER_EDWIN (for example), but nowhere can I find the code to retrieve the values entered by the user.
Summary: Does anyone have any code or can offer any help in retrieving values from an interface defined by the rss code at the top of this post.[/quote]
No one answered him. (I wonder why [i]do[/i] all the code examples and books give a nested control structure, if that does not work?)
It does make sense that the line [b]id = EGeneralAmountQuery[/b] refers to the control that immediately follows, that is, the [b]AVKON_DATA_QUERY[/b], rather than the [B]AVKON_INTEGER_EDWIN[/B] control nested inside that one, which the C++ code is trying to access.
However, when I tried to do what he advised, namely removing the outer AVKON_DATA_QUERY control (and the fields "layout" and "label", of course), the resource compiles, but when I run the application, it crashes right away with a [b]BAFL 4[/b] panic. So I wonder how exactly he did get his resource to work.
Re: why do I get panic EIKON-EDWIN 8 when trying to use an AVKON_INTEGER_EDWIN contro
The solution is:
- get the control which is AknCtControl and
- get the layout which is edwin
CAknQueryControl* control = static_cast<CAknQueryControl*>(ControlOrNull(EGeneralQuery));
CEikEdwin* nameEdwin = static_cast<CEikEdwin*> ( control->ControlByLayoutOrNull( EDataLayout ) );
[url]http://discussion.forum.nokia.com/forum/showthread.php?t=127534[/url]
cheers
Naveen
Re: why do I get panic EIKON-EDWIN 8 when trying to use an AVKON_INTEGER_EDWIN contro
Hint:
use
CAknQueryControl* control = QueryControl();
instead of
CAknQueryControl* control =
static_cast<CAknQueryControl*>(ControlOrNull(EGeneralQuery));
Both methods work, but the first one reads a little bit easier :). Very good answer! Compliment to pncbose! Thanks for helping me to find my solution.
BR,
Rene