|
|
Classification: |
C++ |
Category: |
UIKON |
Created: |
06/23/2003 |
Modified: |
07/14/2003 |
Number: |
FAQ-0884 |
Platform: |
Symbian OS v6.0, Symbian OS v6.1, Symbian OS v7.0, Symbian OS v7.0s |
|
Question: What pattern should I follow to ensure the correct creation of my UI controls?
Answer: For each UI control:
1) Create the control object (e.g. iMyControl = new (ELeave) CMyNiftyControl;) 2) Set the control's container window (e.g. iMyControl->SetContainerWindowL(*this);) 3) Call second phase control construction (e.g. iMyControl->ConstructL();)
Each control should then in its second phase construction method (ConstructL() or ConstructFromResourceL()) repeat the steps
above (if necessary) for any child controls.
4) Once the entire view is constructed, you should set the size of it. Never set the size of the child control(s) in the second
phase construction method! When the control's size changes, a call is made to the control's SizeChanged() method. That's the
method you should override for all controls that you create and do the layout of all that control's child controls. By setting
the size of all child controls in the SizeChanged() method, layout changes will trickle down the entire control tree whenever
a control higher up in the hierarchy has its size changed. Call the MinimumSize() method on the child(ren) to find the size
they prefer.
5) Once the entire view has been constructed, and the size has been set, activate it for drawing by calling ActivateL() on it.
Never call ActivateL() one control at a time, but call it on the top control when it's fully constructed. Child controls will
then automatically be activated recursively.
When you code your own UI controls, try always to follow the pattern above. Avoid breaking the pattern by, for example, adding
NewL() methods to your controls. It is recommended that you use NewL() and NewLC() methods for other classes, but avoid using
them for CCoeControl derived ones. Strictly, the reason for this is that a CCoeControl that a has a NewL() method instead
of a public constructor can't be added to a dialog, because the dialog framework relies on the control having a public constructor
and a ConstructFromResourceL() method. You might argue it's still better to have a private c'tor and a NewL() method for controls
that you know will never be added to a dialog, but we still strongly recommend that you ALWAYS use the pattern described above
anyway!
Notes a) Window-owning controls (i.e. CCoeControl classes that call CreateWindowL() in their ConstructL() method) do not require you
to set their container window, but for consistency it is recommended that you always do that anyway. Previously (UIQ v2.0
and before), you had to know if the control you were about to create was window-owning or not, because calling SetContainerWindowL()
on a window-owning control would cause a panic. But this is not the case from UIQ v2.1. The problem is that there is really
no way to know (other than maybe finding the answer in the documentation or just trying to make the SetContainerWindowL()
call to see if it panicked or not). Hence, the panic was removed; so for consistency, always follow the pattern above.
b) Make sure you never activate a control before it has been given it's size. A window owning control that is given its size
AFTER it has been activated will cause the entire screen to blank and be redrawn.
|
|
|