第12课 - 注释符号

第12课 - 注释符号

1. 下面的注释正确吗?

在现代软件开发中,代码量动辄几十万行,这么庞大的程序非常需要注释,否则代码可能看的一头雾水。

先检验一下大家对注释的掌握程度,下面这个程序中的注释都正确吗?

 1 #include<stdio.h>
 2 
 3 int main()
 4 {
 5     int/**/i;
 6 
 7     char* s = "abcdefg     //ijklmn"; 8 
 9     //Is it a \
10      valid comment?
11 
12     in/**/t j;
13 
14     return 0;
15 }

怎么验证上面的注释是否正确呢?因为注释是由预处理器处理的,我们使用 gcc -E命令 预处理上面的代码,看处理结果是什么样的。

 1 root@ubuntu:/home/swj/c_course/ch_12# gcc -E 12-1.c 
 2 # 1 "12-1.c"
 3 # 1 "<built-in>"
 4 # 1 "<command-line>"
 5 # 1 "/usr/include/stdc-predef.h" 1 3 4
 6 # 1 "<command-line>" 2
 7 # 1 "12-1.c"
 8 
 9 
10 int main()
11 {
12     int i;  这里注释被替换成了空格
13 
14     char* s = "abcdefg     //ijklmn";  字符串字面量中的注释没有起效
15 
16     由接续符连接的两行代码被注释掉了
17 
18 
19     in t j;  这里注释被替换成了空格,引起了语法错误
20 
21     return 0;
22 }

为什么结果是这样的呢?我们来看下C语言中注释的规则。

2. 注释的规则

(1)预处理器在处理注释时,使用空格替换整个注释

(2)字符串字面量中的 // 和 /*...*/ 不代表注释符号,即注释无效

(3)/*...*/ 型注释不能被嵌套

了解了这三条规则之后,再分析前面代码的预处理结果就很明了了。

3. 有趣的问题

你觉得 y= x/*p; 是什么意思?

作者本意是将x除以*p的结果赋值给y。那实际是什么样的呢?我们写代码测试一下。

 1 int main()
 2 {
 3     int x = 2;
 4     int y = 1;
 5     int *p = &y;
 6 
 7     y = x/*p;
 8 
 9     return 0;
10 }

从代码提示中可以看到 /* 后面的代码全部被当做注释了,我们编译这个代码也报错了,可见这里语法有问题。  

     

为什么会产生这个结果呢?编译器将 /* 作为一段注释的开始,把 /* 后的内容和都当成注释内容,直到 */ 出现为止。

在编译器看来,注释和其它程序元素是平等的。因此,作为工程师不能轻视注释。

解决方法:将 / 两边各加一个空格,防止 结合就可以了。

4. 糟糕的注释

(1)教科书型注释!注释用于阐述原因和意图而不是描述程序的运行过程,下面的注释对理解程序毫无帮助!

 1 int main()
 2 {
 3     r = n / 2;                //r是n的一半
 4     while ((r - n / r) <= t)  //循环,仅当r - n/r 不大于t
 5     {
 6     }
 7  
 8     r = r + n * t;            //对变量r进行赋值
 9     n++;                      //变量n自增1 
10 
11     return 0;
12 }

(2)迷惑型的注释!写注释不是晒心情,必须无二义性,起到对代码进行提示的作用,避免使用缩写!

下面的注释中,0x723是10进制的1827,是贝多芬去世的那一年。R.I.P.L.V.B是Rest In Peace. Ludwig Van Beethoven.(路德维希·凡·贝多芬安息吧!)的缩写。  鬼能看懂!!!

 1 int main()
 2 {
 3     init();
 4 
 5     //......
 6     //......
 7 
 8     sad = 0x723;    //R.I.P.L.V.B.
 9 
10     //......
11     //......
12 
13     finalize();
14 
15     return 0;
16 }

(3)忽悠型注释!注释是对代码的提示,避免臃肿和喧宾夺主。

 1 int main()
 2 {
 3     //......
 4     //......
 5 
 6     //Bob 07/24/1995
 7     /*我知道这个问题很难解决而且现在必须依赖于这个contains函数
 8      *但我以后会用一种更加直观优雅有意义的方式重写这段代码。
 9      *现在这么做只是由于时间紧近,但我一定会解决的。
10     */
11 
12     if (contains(s, "error"))
13     {
14         exit(1);
15     }
16 
17     //......
18     //......
19 
20     return 0;
21 }

(4)搞笑型注释!佛祖是佛学专业的大师,但是没学过编程,因此保佑不了你,你只能靠自己避开bug。

         

 看了上面那么多糟糕的注释之后,大家肯定很想知道正确的注释是什么样的,下面展示一下高通公司(Qualcomm)代码中的注释是如何写的。

   1 /*
   2   ========================================================================
   3 
   4   FILE:  Form.c
   5   
   6   SERVICES:  
   7 
   8   GENERAL DESCRIPTION: Concrete implementation of RootForm and base IForm
   9   methods
  10 
  11   ========================================================================
  12   ========================================================================
  13     
  14                Copyright ?1999-2005 QUALCOMM Incorporated 
  15                      All Rights Reserved.
  16                    QUALCOMM Proprietary/GTDR
  17     
  18   ========================================================================
  19   ========================================================================
  20 */
  21 
  22 
  23 /*==================================================================================
  24                          XXXXXXX Confidential Proprietary
  25                    (c) Copyright XXXXXXX - All Rights Reserved
  26 
  27 Revision History:
  28                          Modification
  29   Author                     Date        CR Number      Major Changes
  30 ----------------------   ------------   ------------   ----------------------------
  31 Daniel Rossler            01/18/2007     LIBkk94550    Add check for NULL pointers
  32                                                        in order to avoid a panic
  33 ==================================================================================*/
  34 
  35 
  36 
  37 #include "FormBase.h"
  38 
  39 #include "AEESoftkeyWidget.h"
  40 #include "AEEImageWidget.h"
  41 #include "AEEStaticWidget.h"
  42 #include "AEEImageStaticWidget.h"
  43 #include "AEERootContainer.h"
  44 #include "AEEWProperties.h"
  45 #include "AEEVectorModel.h"
  46 
  47 #include "AEEWeb.h"
  48 
  49 #include "AEERootForm.h"
  50 #include "AEEResFile.h"
  51 
  52 #include "FormUtil.h"
  53 #include "AEEDisplayCanvas.h"
  54 
  55 #define FORMSTACK_MIN  10
  56 #define FORMSTACK_GROW 2
  57 
  58 /////////////////////////////////////////////////////////////////
  59 // RootForm
  60 
  61 typedef struct RootForm {
  62    Form              base;
  63 
  64    IRootContainer *  piContainer;
  65    AEERect           rcContainer;
  66    AEERect           rcClient;
  67 
  68    IVectorModel *    piForms;
  69    ModelListener     mlFormActive;
  70    ModelListener     mlFormTopmostNonPopup;
  71 
  72    IWidget *         piTitle;
  73    ImageStaticInfo   titleInfo;
  74    IWidget *         piSoftkeys;
  75    IWidget *         piBackground;
  76 
  77    IWidget *         piActiveWidget;  
  78 
  79    IResFile *        piThemeFile;
  80    const char *      themeFile;
  81 } RootForm;
  82 
  83 #define DECL(c) c* me = (c *)po
  84 
  85 static __inline IForm *ROOTFORM_TO_IFORM(RootForm *me) {
  86    return (IForm *)me;
  87 }
  88 
  89 static __inline Form *ROOTFORM_TO_FORM(RootForm *me) {
  90    return (Form *)me;
  91 }
  92 
  93 static __inline IRootForm *ROOTFORM_TO_IROOTFORM(RootForm *me) {
  94    return (IRootForm *)me;
  95 }
  96 
  97 static void RootForm_FreeFormEntry(IForm *po)
  98 {
  99    IFORM_Release(po);
 100 }
 101 
 102 static void RootForm_UpdateClientArea(RootForm *me)
 103 {
 104    WidgetPos pos;
 105    WExtent titleExtent, skExtent;
 106 
 107    if (me->piSoftkeys) {
 108       IWIDGET_GetExtent(me->piSoftkeys, &skExtent);
 109  
 110       // Adjust softkey position based on current height
 111       IROOTCONTAINER_GetPos(me->piContainer, me->piSoftkeys, &pos);
 112       pos.y = me->rcContainer.dy - skExtent.height;
 113       IROOTCONTAINER_SetPos(me->piContainer, me->piSoftkeys, WIDGET_ZNORMAL, &pos);
 114    } else {
 115       SETWEXTENT(&skExtent, 0, 0);
 116    }
 117 
 118    if (me->piTitle) {
 119       IWIDGET_GetExtent(me->piTitle, &titleExtent);
 120    } else {
 121       SETWEXTENT(&titleExtent, 0, 0);
 122    }
 123    
 124    // Calculate client area
 125    SETAEERECT(&me->rcClient, 0, titleExtent.height,
 126               me->rcContainer.dx,
 127               me->rcContainer.dy - skExtent.height - titleExtent.height);
 128 }
 129 
 130 
 131 static void RootForm_UpdateTheme(RootForm *me, const char *baseName)
 132 {
 133    WExtent wextent;
 134 
 135    BUIT_LOG("FORMS EVT: Update Theme Started for %s", baseName);
 136 
 137    if (!me->piThemeFile)
 138       return;
 139 
 140    if (me->piTitle) {
 141       IWIDGET_SetProperties(me->piTitle, me->piThemeFile, baseName, "Title", "Properties", 0);
 142       IWIDGET_GetPreferredExtent(me->piTitle, &wextent);
 143       wextent.width = me->rcContainer.dx;
 144       IWIDGET_SetExtent(me->piTitle, &wextent);
 145    }
 146 
 147    if (me->piSoftkeys) {
 148       IWIDGET_SetProperties(me->piSoftkeys, me->piThemeFile, baseName, "Softkeys", "Properties", 0);
 149       IWIDGET_GetPreferredExtent(me->piSoftkeys, &wextent);
 150       wextent.width = me->rcContainer.dx;
 151       IWIDGET_SetExtent(me->piSoftkeys, &wextent);
 152    }
 153 
 154    if (me->piBackground) {
 155       IWIDGET_SetProperties(me->piBackground, me->piThemeFile, baseName, "Background", "Properties", 0);
 156    }
 157 
 158    // Update client area since sizes may have changed
 159    RootForm_UpdateClientArea(me);
 160 
 161    BUIT_LOG("FORMS EVT: Update Theme Finished for %s", baseName);
 162 }
 163 
 164 // updates the rootform with the background image, softkey and 
 165 // title text of the TOS form.
 166 static void RootForm_Update(RootForm *me, uint32 dwItemMask, IForm* piForm)
 167 {
 168    boolean bPopup = 0;
 169 
 170    // get form's popup flag
 171    bPopup = IFORM_GetIsPopup(piForm);
 172 
 173    // if the form's widget has changed, update the scroll model
 174    // for the scroll indicator in the softkey widget
 175    if (dwItemMask & FORMITEM_WIDGET) {
 176       
 177       IWidget *piWidget = NULL;
 178       // get form's widget
 179       IFORM_GetWidget(piForm, WID_FORM, &piWidget);
 180 
 181       // update the widget and the scroll model
 182       if (piWidget) {
 183 
 184          // if the active widget has been changed underneath us...
 185          
 186          if (me->piActiveWidget && piWidget != me->piActiveWidget) {
 187             // this block will only be executed when the form widget is changed
 188             // by the application logic while the form is active
 189             WidgetPos pos;
 190             WExtent we;
 191    
 192             IWIDGET_MoveFocus(FORM_WIDGET(me), (IWidget*)WIDGET_FOCUS_NONE);
 193    
 194             IWIDGET_GetExtent(me->piActiveWidget, &we);
 195             IWIDGET_SetExtent(piWidget, &we);
 196    
 197             // remove the previously active widget from the root container
 198             if (AEE_SUCCESS == IROOTCONTAINER_GetPos(me->piContainer, me->piActiveWidget, &pos)) {
 199                IROOTCONTAINER_Remove(me->piContainer, me->piActiveWidget);
 200             }
 201             
 202             // add the new widget to the root container
 203             IROOTCONTAINER_Insert(me->piContainer, piWidget, WIDGET_ZTOPMOST, &pos);
 204             // and remember it fondly
 205             RELEASEIF(me->piActiveWidget);
 206             me->piActiveWidget = piWidget;
 207             ADDREFIF(piWidget);
 208 
 209             // set focus to the new widget
 210             IWIDGET_MoveFocus(FORM_WIDGET(me), piWidget);
 211          
 212          } else if (!me->piActiveWidget) {
 213             me->piActiveWidget = piWidget;
 214             ADDREFIF(piWidget);
 215          }
 216 
 217       }
 218 
 219       RELEASEIF(piWidget);
 220    }
 221 
 222 
 223    // if the form's background image has changed...
 224    // if form is a popup, then retain the background image 
 225    // from the previous form
 226    if (dwItemMask & FORMITEM_BACKGROUND && me->piBackground && !bPopup) {      
 227       IImage *pii = NULL;
 228       
 229       // Try to grab the image from the new form.  
 230       IFORM_GetBGImage(piForm, &pii);
 231 
 232       // If non-existent, try defaulting to the root form
 233       if (!pii) IFORM_GetBGImage(ROOTFORM_TO_IFORM(me), &pii);
 234       
 235       // Apply the result (NULL or otherwise) to our background widget
 236       IWIDGET_SetImage(me->piBackground, pii);
 237       RELEASEIF(pii);
 238    }
 239    
 240    // if the form's title text has changed...  retain previous title
 241    // if we are a popup 
 242 
 243    if ((dwItemMask & FORMITEM_TITLE) && me->piTitle && !bPopup) {
 244       // Release image. Text is owned by form
 245       RELEASEIF(me->titleInfo.piImage);
 246       IFORM_GetTextPtr(piForm, FID_TITLE, &me->titleInfo.pwText);
 247       IFORM_GetTitleImage(piForm, &me->titleInfo.piImage);
 248 
 249       // Set title info
 250       IWIDGET_SetImageStaticInfo(me->piTitle, &me->titleInfo, 0);
 251    }
 252 
 253    // if the form's softkey text has changed...
 254    if ((dwItemMask & FORMITEM_SOFTKEY) && me->piSoftkeys) {
 255 
 256       IForm* piTopForm = IROOTFORM_GetTopForm(ROOTFORM_TO_IROOTFORM(me));
 257 
 258       AECHAR *pwsz = NULL;
 259       IWidget *piKey = NULL;
 260 
 261       if (piTopForm == piForm) {
 262          // set softkey 1 text
 263          IFORM_GetTextPtr(piForm, FID_SOFTKEY1, &pwsz);
 264          if (AEE_SUCCESS == IWIDGET_GetSoftkey(me->piSoftkeys, PROP_SOFTKEY1, &piKey)) {
 265             IWIDGET_SetText(piKey, pwsz, 0);
 266          }
 267          RELEASEIF(piKey);
 268    
 269          // set softkey 2 text
 270          IFORM_GetTextPtr(piForm, FID_SOFTKEY2, &pwsz);
 271          if (AEE_SUCCESS == IWIDGET_GetSoftkey(me->piSoftkeys, PROP_SOFTKEY2, &piKey)) {
 272             IWIDGET_SetText(piKey, pwsz, 0);
 273          }
 274       }
 275       RELEASEIF(piKey);
 276    }
 277 
 278    if ((dwItemMask & FORMITEM_THEME_BASENAME)) {
 279       char *baseName = 0;
 280 
 281       IFORM_GetThemeBaseName(piForm, &baseName);
 282       RootForm_UpdateTheme(me, baseName);
 283    }
 284 
 285 }
 286 
 287 static boolean RootForm_ReplaceWidget(RootForm *me, IWidget **piw, IWidget *piwNew, IWidget *piwBefore)
 288 {
 289    int        result = AEE_SUCCESS;
 290    WidgetPos  pos;
 291 
 292    if (*piw) {
 293       (void) IROOTCONTAINER_GetPos(me->piContainer, *piw, &pos);
 294       (void) IROOTCONTAINER_Remove(me->piContainer, *piw);
 295       IWIDGET_Release(*piw);
 296    }
 297 
 298    if (piwNew) {
 299       result = IROOTCONTAINER_Insert(me->piContainer, piwNew, piwBefore, &pos);
 300       
 301       if (result == AEE_SUCCESS) {
 302          IWIDGET_AddRef(piwNew);
 303       } else {
 304          piwNew = NULL;
 305       }
 306    }
 307 
 308    *piw = piwNew;
 309 
 310    // Do an update since extents may have changed
 311    RootForm_UpdateClientArea(me);
 312 
 313    return (AEE_SUCCESS == result);
 314 }
 315 
 316 static int RootForm_SetThemeName(RootForm *me, const char *themeFile)
 317 {
 318    if (!me->piThemeFile)
 319       return EBADSTATE;
 320    
 321    FREEIF(me->themeFile);
 322    me->themeFile = STRDUP(themeFile);
 323    
 324    IRESFILE_Close(me->piThemeFile);
 325    if (themeFile)
 326       return IRESFILE_Open(me->piThemeFile, themeFile);
 327    else
 328       return AEE_SUCCESS;
 329 }
 330 
 331 static int RootForm_SetDisplay(RootForm *me, IDisplay *piDisplay)
 332 {
 333    int nErr = AEE_SUCCESS;
 334    IDisplayCanvas *piCanvas = 0;
 335 
 336    nErr = ISHELL_CreateInstance(FORM_SHELL(me), AEECLSID_DISPLAYCANVAS, (void **)&piCanvas);
 337       
 338    if (!nErr) {
 339       WExtent extent;
 340       WidgetPos pos;
 341       
 342 
 343       IDISPLAY_SetClipRect(piDisplay, NULL); // reset the clipping rectangle
 344       IDISPLAY_GetClipRect(piDisplay, &me->rcContainer);
 345       SETAEERECT(&me->rcClient, 0, 0, me->rcContainer.dx, me->rcContainer.dy);
 346 
 347       IDISPLAYCANVAS_SetDisplay(piCanvas, piDisplay);
 348       IROOTCONTAINER_SetCanvas(me->piContainer, (ICanvas *)piCanvas, &me->rcContainer);
 349 
 350       if (me->piTitle) {
 351          // Set extent, title is already positioned at 0, 0
 352          IWIDGET_GetExtent(me->piTitle, &extent);
 353          extent.width = me->rcContainer.dx;
 354          IWIDGET_SetExtent(me->piTitle, &extent);
 355       }
 356 
 357       if (me->piBackground) {
 358          // Set extent, background is already positioned at 0, 0
 359          extent.width = me->rcContainer.dx;
 360          extent.height = me->rcContainer.dy;
 361          IWIDGET_SetExtent(me->piBackground, &extent);
 362       }
 363 
 364       if (me->piSoftkeys) {
 365          // Set extent
 366          IWIDGET_GetExtent(me->piSoftkeys, &extent);
 367          extent.width = me->rcContainer.dx;
 368          IWIDGET_SetExtent(me->piSoftkeys, &extent);
 369          // And position at bottom of screen
 370          IROOTCONTAINER_GetPos(me->piContainer, me->piSoftkeys, &pos);
 371          pos.y = me->rcContainer.dy - extent.height;
 372          IROOTCONTAINER_SetPos(me->piContainer, WIDGET_ZNORMAL, me->piSoftkeys, &pos);
 373       }
 374    }
 375 
 376    RELEASEIF(piCanvas);
 377 
 378    return nErr;
 379 }
 380 
 381 
 382 static void RootForm_ApplyTheme(RootForm *me)
 383 {
 384    int nrForms, i;
 385 
 386    if (!me->piThemeFile) 
 387       return;
 388    
 389    nrForms = IVECTORMODEL_Size(me->piForms);
 390    for (i = 0; i < nrForms; i++) {
 391       IForm *piForm;
 392       char* pTheme = 0;
 393       IVECTORMODEL_GetAt(me->piForms, i, (void **)&piForm);
 394       
 395       IFORM_GetThemeBaseName(ROOTFORM_TO_IFORM(me), &pTheme);
 396       pTheme = (pTheme) ? pTheme : "(None)";
 397       
 398       BUIT_LOG("FORMS EVT: Apply Theme Started for %s", pTheme);
 399       
 400       IFORM_ApplyTheme(piForm);
 401       
 402       BUIT_LOG("FORMS EVT: Apply Theme Finished for %s", pTheme);
 403    }
 404 
 405    if (nrForms == 0) {
 406       char *baseName = 0;
 407       
 408       IFORM_GetThemeBaseName(ROOTFORM_TO_IFORM(me), &baseName);
 409 #ifdef FEATURE_MOT_BREW
 410       if (baseName != NULL) {
 411           RootForm_UpdateTheme(me, baseName);
 412       }
 413 #else
 414       RootForm_UpdateTheme(me, baseName);
 415 #endif /*FEATURE_MOT_BREW*/
 416    }
 417 }
 418 
 419 boolean RootForm_HandleEvent(IRootForm *po, AEEEvent evt, uint16 wParam, uint32 dwParam)
 420 {
 421    DECL(RootForm);
 422 
 423    if (FORM_WIDGET(me)
 424       && IWIDGET_HandleEvent(FORM_WIDGET(me), evt, wParam, dwParam))
 425       return TRUE;
 426 
 427    if (evt == EVT_WDG_GETPROPERTY) {
 428       switch(wParam) {
 429       case FID_THEME_FNAME:
 430          *(const char **)dwParam = me->themeFile;
 431          return TRUE;
 432 
 433       case FID_THEME_FILE:
 434          *(IResFile **)dwParam = me->piThemeFile;
 435          ADDREFIF(me->piThemeFile);
 436          return TRUE;
 437 
 438       case WID_TITLE:
 439          *(IWidget **)dwParam = me->piTitle;
 440          ADDREFIF(me->piTitle);
 441          return TRUE;
 442 
 443       case WID_SOFTKEYS:
 444          *(IWidget **)dwParam = me->piSoftkeys;
 445          ADDREFIF(me->piSoftkeys);
 446          return TRUE;
 447 
 448       case WID_BACKGROUND:
 449          *(IWidget **)dwParam = me->piBackground;
 450          ADDREFIF(me->piBackground);
 451          return TRUE;
 452 
 453       case WID_FORM:
 454          IROOTCONTAINER_QueryInterface(me->piContainer, AEEIID_WIDGET, (void **)dwParam);
 455          return TRUE;
 456 
 457       case WID_CONTAINER:
 458          *(IContainer **)dwParam = IROOTCONTAINER_TO_ICONTAINER(me->piContainer);
 459          ADDREFIF(me->piContainer);
 460          return TRUE;
 461 
 462       default:
 463          // Fall back on formbase
 464          return Form_HandleEvent(ROOTFORM_TO_IFORM(me), evt, wParam, dwParam);
 465       }
 466 
 467    } else if (evt == EVT_WDG_SETPROPERTY) {
 468       IForm *piForm = 0;
 469 
 470       switch(wParam) {
 471       case FID_ACTIVE:
 472          piForm = IROOTFORM_GetTopForm(po);
 473          if (piForm) {
 474             // Activate or de-activate the top form
 475             IFORM_SetProperty(piForm, FID_ACTIVE, dwParam);
 476          }
 477          // and invalidate root container on activation
 478          if ((boolean)dwParam) {
 479             IROOTCONTAINER_Invalidate(me->piContainer, 0, 0, 0);
 480          }
 481          return TRUE;
 482 
 483       case FID_THEME:
 484          RootForm_ApplyTheme(me);
 485          return TRUE;
 486 
 487       case FID_THEME_FNAME:
 488          if (AEE_SUCCESS == RootForm_SetThemeName(me, (const char *)dwParam)) {
 489             RootForm_ApplyTheme(me);
 490             return TRUE;
 491          }
 492          return FALSE;
 493 
 494       case FID_BACKGROUND:
 495          // If we have a background widget, set the image into it
 496          if (me->piBackground) {
 497             IWIDGET_SetFormImage(me->piBackground, FORM_SHELL(me), (FormRes *)dwParam);
 498          }
 499          // Also load the image into our internal form, which will hold it as a default for other forms
 500          return Form_HandleEvent(ROOTFORM_TO_IFORM(me), evt, wParam, dwParam);
 501 
 502       case FID_DISPLAY:
 503          return AEE_SUCCESS == RootForm_SetDisplay(me, (IDisplay *)dwParam);
 504 
 505       case FID_WPROPS: {
 506          WPropDesc *pdesc = (WPropDesc *)dwParam;
 507          WResPropDesc wd;
 508                   
 509          wd.piResFile = me->piThemeFile;
 510          if (pdesc) {
 511             wd.args = pdesc->args;
 512             wd.piWidget = pdesc->piWidget;
 513          }
 514          return IWIDGET_SetProperty(pdesc->piWidget, PROP_APPLYWPROPS, (uint32)&wd);
 515       }
 516 
 517       case WID_TITLE:
 518          return RootForm_ReplaceWidget(me, &me->piTitle, (IWidget *)dwParam, WIDGET_ZNORMAL);
 519 
 520       case WID_SOFTKEYS:
 521          return RootForm_ReplaceWidget(me, &me->piSoftkeys, (IWidget *)dwParam, WIDGET_ZNORMAL);
 522 
 523       case WID_BACKGROUND:
 524          return RootForm_ReplaceWidget(me, &me->piBackground, (IWidget *)dwParam, WIDGET_ZBOTTOMMOST);
 525 
 526       default:
 527          // Fall back on formbase
 528          return Form_HandleEvent(ROOTFORM_TO_IFORM(me), evt, wParam, dwParam);
 529       }
 530    }
 531 
 532    // Non get/set property events are sent on to the topmost form
 533    {
 534       IForm *piForm = IROOTFORM_GetTopForm(po);
 535       if (!piForm)
 536          return FALSE;
 537       else
 538          return IFORM_HandleEvent(piForm, evt, wParam, dwParam);
 539    }  
 540 }
 541 
 542 
 543 static void RootForm_UpdateActiveListenerCB(RootForm *me, FormEvent *pEvent)
 544 {
 545    if (pEvent->base.evCode == EVT_MDL_FORM_CHANGE) {
 546       RootForm_Update(me, pEvent->dwItemMask, pEvent->piForm);
 547    }
 548 }
 549 
 550 static void RootForm_UpdateTopmostNonPopupListenerCB(RootForm *me, FormEvent *pEvent)
 551 {
 552    uint32 dwItemMask = pEvent->dwItemMask & (FORMITEM_BACKGROUND | FORMITEM_TITLE | FORMITEM_SOFTKEY);
 553 
 554    if (pEvent->base.evCode == EVT_MDL_FORM_CHANGE && dwItemMask) {
 555       RootForm_Update(me, dwItemMask, pEvent->piForm);
 556    }
 557 }
 558 
 559 static void RootForm_ShowFormWidget(IRootForm *po, IForm *piForm, boolean bShow, boolean bFocus)
 560 {
 561    DECL(RootForm);
 562    WidgetPos pos;
 563    IWidget *piWidget;
 564 
 565    if (!piForm)
 566       return;
 567 
 568    IFORM_GetWidget(piForm, WID_FORM, &piWidget);
 569    
 570    if (!piWidget)
 571       return;
 572 
 573    // Set visibility 
 574    IROOTCONTAINER_GetPos(me->piContainer, piWidget, &pos);
 575    pos.bVisible = bShow;
 576    IROOTCONTAINER_SetPos(me->piContainer, piWidget, WIDGET_ZNORMAL, &pos);
 577 
 578    // and set focus to the widget
 579    if (bShow && bFocus) {
 580       IWIDGET_MoveFocus(FORM_WIDGET(me), piWidget);
 581    } else {
 582       IWIDGET_MoveFocus(FORM_WIDGET(me), WIDGET_FOCUS_NONE);
 583    }
 584    
 585    IWIDGET_Release(piWidget);
 586 }
 587 
 588 
 589 /** Activates a given form.  Previous form should have been
 590  deactivated before this is called with bActivate set
 591  */
 592 static void RootForm_ActivateForm(IRootForm *po, IForm *piForm, boolean bActivate)
 593 {
 594    DECL(RootForm);
 595 
 596    if (!piForm)
 597       return;
 598 
 599    if (bActivate) {
 600       // Undo the currently known active widget
 601       RELEASEIF(me->piActiveWidget);
 602       IFORM_GetWidget(piForm, WID_FORM, &me->piActiveWidget);
 603       // Then go update all the items except the forms widget as this is not the 
 604       // form updating its own widget. Need to update first since theme information
 605       // affect client area which affects form activation
 606       RootForm_Update(me, FORMITEM_ALL & ~FORMITEM_WIDGET, piForm);
 607       // then activate
 608       IFORM_Activate(piForm);
 609    } else {
 610       IFORM_Deactivate(piForm);
 611    }
 612 }
 613 
 614 static int RootForm_GetFormIndex(RootForm *me, IForm **ppiForm) 
 615 {
 616    IForm *piForm;
 617    int nrForms;
 618 
 619    nrForms = IVECTORMODEL_Size(me->piForms);
 620 
 621    if (nrForms > 0) {
 622 
 623       if (*ppiForm == FORM_LAST || *ppiForm == FORM_DEFAULT) {
 624 
 625          IVECTORMODEL_GetAt(me->piForms, nrForms - 1, (void **)ppiForm);
 626          return nrForms - 1;
 627 
 628       } else if (*ppiForm == FORM_FIRST) {
 629 
 630          IVECTORMODEL_GetAt(me->piForms, 0, (void **)ppiForm);
 631          return 0;
 632 
 633       } else {
 634 
 635          int i;
 636          for (i = 0; i < nrForms; i++) {
 637             IVECTORMODEL_GetAt(me->piForms, i, (void **)&piForm);
 638             if (piForm == *ppiForm)
 639                return i;
 640          }
 641 
 642       }
 643    }
 644 
 645    return -1;
 646 }
 647 
 648 static __inline int RootForm_GetFormInsertionIndex(RootForm *me, IForm **ppiForm)
 649 {
 650    int delta;
 651 
 652    if (*ppiForm == FORM_FIRST)
 653       return 0;
 654 
 655    if (*ppiForm == FORM_LAST || *ppiForm == FORM_DEFAULT) {
 656       delta = 1;
 657    } else {
 658       delta = 0;
 659    }
 660 
 661    return RootForm_GetFormIndex(me, ppiForm) + delta;
 662 }
 663 
 664 static void RootForm_StackChange(IRootForm *po)
 665 {
 666    DECL(RootForm);
 667    IForm* piTopForm = IROOTFORM_GetTopForm(po);
 668    
 669    LISTENER_Cancel(&me->mlFormActive);
 670    LISTENER_Cancel(&me->mlFormTopmostNonPopup);
 671 
 672    // If there are still forms on the stack, then we need to set up several things:
 673    //   1. The topmost form is the active form
 674    //   2. All other forms are not active
 675    //   3. The topmost form is being listened to via mlFormActive
 676    //   4. The topmost non-popup form is being listened to via mlFormTopmostNonPopup
 677    //   5. The topmost non-popup form and all popup forms on top of it are shown
 678    //   6. Forms below the topmost non-popup form are now shown
 679    if (piTopForm)
 680    {
 681       boolean bFoundTopmostNonPopup = FALSE;
 682       IModel* piModel = NULL;
 683       IForm*  pif;
 684 
 685       // Logging stack change begin
 686       BUIT_LOG("FORMS EVT: Stack Change Starting...", 1);
 687 
 688       // Need to deal with the non-active forms first, then the active form
 689       for (pif = piTopForm; pif; pif = IROOTFORM_GetForm(po, pif, FALSE, FALSE))
 690       {
 691          boolean bPopup;
 692 
 693          bPopup = IFORM_GetIsPopup(pif);
 694          IFORM_GetFormModel(pif, &piModel);
 695          if (piModel)
 696          {
 697             if (pif != piTopForm)
 698             {
 699                RootForm_ShowFormWidget(po, pif, (boolean)(bFoundTopmostNonPopup? FALSE : TRUE), FALSE);
 700                if (IFORM_IsActive(pif))
 701                {
 702                   RootForm_ActivateForm(po, pif, FALSE);
 703                }
 704             }
 705 
 706             if (!bPopup && !bFoundTopmostNonPopup)
 707             {
 708                IMODEL_AddListenerEx(piModel, &me->mlFormTopmostNonPopup, (PFNLISTENER)RootForm_UpdateTopmostNonPopupListenerCB, me);
 709                if (pif != piTopForm)
 710                   // Only update if not the topmost form since the
 711                   // Activate below applies theme again The topmost
 712                   // non-popup (but not the top!) influences the
 713                   // background, title ans associated themes
 714                   RootForm_Update(me, FORMITEM_BACKGROUND | FORMITEM_TITLE | FORMITEM_THEME_BASENAME, pif);
 715                bFoundTopmostNonPopup = TRUE;
 716             }
 717          }
 718          RELEASEIF(piModel);
 719       }
 720 
 721       RootForm_ActivateForm(po, piTopForm, TRUE);
 722       RootForm_ShowFormWidget(po, piTopForm, TRUE, TRUE);
 723       IFORM_GetFormModel(piTopForm, &piModel);
 724       if (piModel)
 725          IMODEL_AddListenerEx(piModel, &me->mlFormActive, (PFNLISTENER)RootForm_UpdateActiveListenerCB, me);
 726       RELEASEIF(piModel);
 727       
 728       // Log that the form is about to be activated - all theme stuff has happened by now)
 729       BUIT_LOG("FORMS EVT: Stack Change Finished", 1);
 730 
 731    }
 732 
 733     // Notify change in stack
 734    Form_Notify(ROOTFORM_TO_FORM(me), FORMITEM_STACK);
 735 }
 736 
 737 
 738 int RootForm_InsertForm(IRootForm *po, IForm *piForm, IForm *pifBefore)
 739 {
 740    DECL(RootForm);
 741    IWidget *piWidget = 0;
 742    IWidget *piwBefore = 0;
 743    IForm *pifCurrent;
 744    int nrForms, formIndex, nErr;
 745 
 746    if (!piForm)
 747       return EBADPARM;
 748 
 749    // Make sure we can insert, get the index we want to insert at
 750    formIndex = RootForm_GetFormInsertionIndex(me, &pifBefore);
 751 
 752    if (formIndex < 0)
 753       return EBADPARM;
 754 
 755    nrForms = IVECTORMODEL_Size(me->piForms);
 756    pifCurrent = IROOTFORM_GetTopForm(po);
 757 
 758    // Get widget to insert
 759    IFORM_GetWidget(piForm, WID_FORM, &piWidget);
 760 
 761    // Get widget insertion point. 
 762    if (formIndex == nrForms || !nrForms) {
 763       piwBefore = WIDGET_ZTOPMOST;
 764    } else if (pifBefore == FORM_FIRST) {
 765       if (me->piBackground != NULL) {
 766      
 767          // If we have a background widget, try to insert the form's widget
 768          // above the background widget
 769          piwBefore = IROOTCONTAINER_GetWidget(me->piContainer, me->piBackground, TRUE, FALSE);
 770          if (piwBefore) {
 771             // Add a reference, so it can be released below.
 772             IWIDGET_AddRef(piwBefore);
 773          }
 774       } 
 775 
 776       if (!piwBefore) {
 777          // No background widget, insert the form's widget at the bottom.
 778          piwBefore = WIDGET_ZBOTTOMMOST;
 779       }
 780 
 781    } else {
 782       IFORM_GetWidget(pifBefore, WID_FORM, &piwBefore);
 783    }
 784 
 785    // Make sure we have space for the new form
 786    nErr = IVECTORMODEL_EnsureCapacity(me->piForms, MAX(FORMSTACK_MIN, nrForms + 1), FORMSTACK_GROW);
 787 
 788    // Now insert
 789    if (!nErr && piWidget && piwBefore) {
 790       WidgetPos pos;
 791 
 792       // Not really needed here since Activate does this to, but since
 793       // we need to give a position on insert we may as well do it
 794       // right
 795       pos.x = me->rcClient.x; 
 796       pos.y = me->rcClient.y;
 797       pos.bVisible = (piwBefore == WIDGET_ZTOPMOST);
 798       
 799       // Insert widget into widget stack
 800       nErr = IROOTCONTAINER_Insert(me->piContainer, piWidget, piwBefore, &pos);
 801    }
 802 
 803    if (!nErr) {
 804       char* pTheme = 0;
 805 
 806       // Add form to formstack
 807       IVECTORMODEL_InsertAt(me->piForms, formIndex, piForm);
 808       IFORM_AddRef(piForm);
 809 
 810       // Set rootform
 811       IFORM_SetProperty(piForm, FID_ROOT, (uint32)po);
 812 
 813       // Log info
 814       IFORM_GetThemeBaseName(ROOTFORM_TO_IFORM(me), &pTheme);
 815       pTheme = (pTheme) ? pTheme : "(None)";
 816 
 817       BUIT_LOG("FORMS EVT: Insert Set Theme Started for %s", pTheme);
 818 
 819       // Set theme on new form
 820       IFORM_ApplyTheme(piForm);
 821 
 822       BUIT_LOG("FORMS EVT: Insert Set Theme Finished for %s", pTheme);
 823       //RootForm_Update(me, FORMITEM_THEME, piForm);
 824 
 825       RootForm_StackChange(po);
 826 
 827 }
 828 
 829    RELEASEIF(piWidget);
 830    if (piwBefore != WIDGET_ZTOPMOST && piwBefore != WIDGET_ZBOTTOMMOST)
 831       RELEASEIF(piwBefore);
 832    return nErr;
 833 }
 834 
 835 int RootForm_RemoveForm(IRootForm *po, IForm *piForm)
 836 {
 837    DECL(RootForm);
 838    IWidget *piWidget = 0;
 839    IForm *piF = 0;
 840    int nrForms = 0;
 841    int formIndex;
 842    boolean bOnlyPopups = 1;
 843 
 844    if (me->piForms)
 845       nrForms = IVECTORMODEL_Size(me->piForms);
 846 
 847    if (piForm == FORM_ALL) {
 848       while (nrForms > 0) {
 849          IROOTFORM_RemoveForm(po, FORM_LAST);
 850          nrForms = IVECTORMODEL_Size(me->piForms);
 851       }
 852 
 853    } else {
 854       formIndex = RootForm_GetFormIndex(me, &piForm);
 855       
 856       if (formIndex < 0)
 857          return EBADPARM;
 858       
 859       IFORM_GetWidget(piForm, WID_FORM, &piWidget);
 860       
 861       if (piWidget) {
 862          IROOTCONTAINER_Remove(me->piContainer, piWidget);
 863       }
 864       
 865       // Hide form widget
 866       RootForm_ShowFormWidget(po, piForm, FALSE, FALSE);
 867       // Deactivate form
 868       RootForm_ActivateForm(po, piForm, FALSE);
 869       // Tell it of rootform departure
 870       IFORM_SetProperty(piForm, FID_ROOT, 0);
 871       // Delete it from the stack
 872       IVECTORMODEL_DeleteAt(me->piForms, formIndex);
 873 
 874       RootForm_StackChange(po);
 875 
 876       RELEASEIF(piWidget);
 877 
 878       // Now many forms do we now have?
 879       nrForms = IVECTORMODEL_Size(me->piForms);
 880    }
 881 
 882    // Cycle through remaining forms to determine type
 883    for (piF = IROOTFORM_GetTopForm(po); piF && bOnlyPopups; piF = IROOTFORM_GetForm(po, piF, FALSE, FALSE))
 884    {
 885       bOnlyPopups &= IFORM_GetIsPopup(piF);
 886    }  
 887 
 888 
 889    if ((0 == nrForms) || bOnlyPopups)
 890    {
 891       // If we don't have any more forms, or the only forms we do have are popups, 
 892       // ensure the title has been cleaned (the title memory is owned by the last full screen form, 
 893       // which may no longer exist).
 894       if (me->piTitle) {
 895          // Release image. Text is owned by form
 896          RELEASEIF(me->titleInfo.piImage);
 897          me->titleInfo.pwText = NULL;
 898 
 899          // Set title info
 900          IWIDGET_SetImageStaticInfo(me->piTitle, &me->titleInfo, 0);
 901       }
 902    }
 903 
 904    if (0 == nrForms) {
 905       
 906       // There are no more forms, ensure the softkey labels
 907       // have been cleaned (the softkey memory is owned by the form, which may no 
 908       // longer exist).
 909       if (me->piSoftkeys) {
 910          IWidget *piKey = NULL;
 911 
 912          (void) IWIDGET_GetSoftkey(me->piSoftkeys, PROP_SOFTKEY1, &piKey);
 913          if (piKey) {
 914             IWIDGET_SetText(piKey, NULL, 0);
 915             IWIDGET_Release(piKey);
 916             piKey = NULL;
 917          }
 918 
 919          (void) IWIDGET_GetSoftkey(me->piSoftkeys, PROP_SOFTKEY2, &piKey);
 920          if (piKey) {
 921             IWIDGET_SetText(piKey, NULL, 0);
 922             IWIDGET_Release(piKey);
 923             piKey = NULL;
 924          }
 925 
 926       }
 927    } else {
 928       RootForm_Update(me, FORMITEM_THEME_BASENAME, IROOTFORM_GetTopForm(po));
 929    }
 930 
 931    return AEE_SUCCESS;
 932 }
 933 
 934 
 935 void RootForm_GetClientRect(IRootForm *po, IXYContainer **ppo, AEERect *rc)
 936 {
 937    DECL(RootForm);
 938 
 939    if (rc) {
 940       *rc = me->rcClient;
 941    }
 942 
 943    if (ppo && me->piContainer) {
 944       *ppo = IROOTCONTAINER_TO_IXYCONTAINER(me->piContainer);
 945       IROOTCONTAINER_AddRef(me->piContainer);
 946    }
 947 }
 948 
 949 IForm *RootForm_GetForm(IRootForm *po, IForm *pifRef, boolean bNext, boolean bWrap)
 950 {
 951    DECL(RootForm);
 952    IForm *piForm = 0;
 953    int nrForms, formIndex;
 954    
 955    if (me->piForms == NULL)
 956       return NULL;
 957 
 958    nrForms = IVECTORMODEL_Size(me->piForms);
 959 
 960    if (pifRef == NULL) {
 961       formIndex = bNext ? 0 : nrForms - 1;
 962       IVECTORMODEL_GetAt(me->piForms, formIndex, (void **)&piForm);
 963       return piForm;
 964    }
 965 
 966    formIndex = RootForm_GetFormIndex(me, &pifRef);
 967 
 968    if (formIndex < 0)
 969       return NULL;
 970 
 971    formIndex += bNext ? 1 : -1;
 972    if (formIndex < 0) {
 973       formIndex = bWrap ? nrForms - 1 : -1;
 974    } else if (formIndex >= nrForms) {
 975       formIndex = bWrap ? 0 : - 1;
 976    }
 977    
 978    if (formIndex < 0)
 979       return NULL;
 980 
 981    IVECTORMODEL_GetAt(me->piForms, formIndex, (void **)&piForm);
 982    return piForm;
 983 }
 984 
 985 int RootForm_ResolveForm(IRootForm *po, char const *szFormUrl, IForm **ppiForm)
 986 {
 987    DECL(RootForm);
 988    IWebUtil *piWebUtil = 0;
 989    AEECLSID formClsId;
 990    int result;
 991    UrlParts parts;
 992    char *path = 0;
 993 
 994    if (!ppiForm || !szFormUrl)
 995       return EBADPARM;
 996 
 997    // Assume failure
 998    *ppiForm = 0;
 999 
1000    // Parse the URL
1001    result = ISHELL_CreateInstance(FORM_SHELL(me), AEECLSID_WEBUTIL, (void **) &piWebUtil);
1002 
1003    if (result == 0) 
1004       result = IWEBUTIL_ParseUrl(piWebUtil, szFormUrl, &parts);
1005 
1006       // Check the scheme
1007    if (result == 0
1008        && (!UP_HASSCHM(&parts) || STRNCMP(parts.cpcSchm,FORM_URL_SCHEME,sizeof(FORM_URL_SCHEME)-1)))
1009        result = ESCHEMENOTSUPPORTED;
1010 
1011       // Do we have a path?
1012    if (result == 0
1013        && (!UP_HASPATH(&parts) || UP_PATHLEN(&parts) <= 0))
1014       result = ESCHEMENOTSUPPORTED;
1015 
1016    // Extract the path (we need it to be NULL terminated)
1017    if (result == 0 
1018        && 0 == (path = MALLOC(UP_PATHLEN(&parts)+1)))
1019       result = ENOMEMORY;
1020 
1021    if (result == 0) {
1022       STRNCPY(path, parts.cpcHost, UP_PATHLEN(&parts)+1);
1023 
1024       // Does a handler exist for this path, of type AEEIID_FORM?
1025       if (0 == (formClsId = ISHELL_GetHandler(FORM_SHELL(me), AEEIID_FORM, path)))
1026          // Nope...
1027          result = ESCHEMENOTSUPPORTED;
1028    }
1029 
1030    if (result == 0)
1031       // Got the actual class id, lets create the form
1032       result = ISHELL_CreateInstance(FORM_SHELL(me), formClsId, (void **) ppiForm);
1033 
1034    //
1035    // TODO: We could use IWEBUTIL_ParseFormFields() to parse parts.cpcSrch 
1036    //       for known Form properties and apply them here...
1037 
1038    RELEASEIF(piWebUtil);
1039    FREEIF(path);
1040 
1041    return result;
1042 }
1043 
1044 void RootForm_Dtor(RootForm *me)
1045 {
1046    IROOTFORM_RemoveForm(ROOTFORM_TO_IROOTFORM(me), FORM_ALL);
1047 
1048    RELEASEIF(me->piTitle);
1049    RELEASEIF(me->piSoftkeys);
1050    RELEASEIF(me->piContainer);
1051    RELEASEIF(me->piBackground);
1052    RELEASEIF(me->titleInfo.piImage);
1053    RELEASEIF(me->piForms);
1054    RELEASEIF(me->piActiveWidget);
1055    RELEASEIF(me->piThemeFile);
1056    FREEIF(me->themeFile);
1057 
1058    Form_Dtor(&me->base);  
1059 }
1060 
1061 uint32 RootForm_Release(IRootForm *po)
1062 {
1063    DECL(RootForm);
1064    
1065    if (FORM_NREFS(me) == 1)
1066       RootForm_Dtor(me);
1067 
1068    return Form_Release(IROOTFORM_TO_IFORM(po));
1069 }
1070 
1071 int RootForm_QueryInterface(IRootForm *po, AEECLSID clsid, void **ppo)
1072 {
1073    if (clsid == AEEIID_ROOTFORM) {
1074       *ppo = po;
1075       Form_AddRef(IROOTFORM_TO_IFORM(po));
1076       return AEE_SUCCESS;
1077    }
1078 
1079    return Form_QueryInterface(IROOTFORM_TO_IFORM(po), clsid, ppo);
1080 }
1081 
1082 int RootForm_Construct(RootForm *me, AEEVTBL(IRootForm) *pvt, IModule *piModule, IShell *piShell)
1083 {
1084    int result;
1085    WExtent extent;
1086    WidgetPos pos;
1087    IDisplay *piDisplay = 0;
1088    ICanvas *piCanvas = 0;
1089 
1090    Form_Ctor(&me->base, (AEEVTBL(IForm) *)pvt, piModule, piShell, 
1091              (PFNHANDLER)RootForm_HandleEvent);
1092 
1093    pos.x = 0;
1094    pos.y = 0;
1095    pos.bVisible = TRUE;
1096    SETWEXTENT(&extent, 0, 0);
1097 
1098    // Form overrides
1099    pvt->Release         = RootForm_Release;
1100    pvt->QueryInterface  = RootForm_QueryInterface;
1101    // RootForm definitions
1102    pvt->InsertForm      = RootForm_InsertForm;
1103    pvt->RemoveForm      = RootForm_RemoveForm;
1104    pvt->GetClientRect   = RootForm_GetClientRect;
1105    pvt->GetForm         = RootForm_GetForm;
1106    pvt->ResolveForm     = RootForm_ResolveForm;
1107 
1108    result = ISHELL_CreateInstance(piShell, AEECLSID_VECTORMODEL, (void **)&me->piForms);
1109 
1110    if (result == 0) {
1111       IVECTORMODEL_SetPfnFree(me->piForms, (PFNNOTIFY)RootForm_FreeFormEntry);
1112 
1113       result = ISHELL_CreateInstance(piShell, AEECLSID_DISPLAY, (void **)&piDisplay);
1114    }
1115 
1116    if (result == 0)
1117       result = ISHELL_CreateInstance(piShell, AEECLSID_ROOTCONTAINER, (void **)&me->piContainer);
1118 
1119    if (result == 0)
1120       result = IROOTCONTAINER_QueryInterface(me->piContainer, AEEIID_WIDGET, (void **)&me->base.piWidget);
1121 
1122    if (result == 0)
1123       result = ISHELL_CreateInstance(piShell, AEECLSID_RESFILE, (void **)&me->piThemeFile);
1124 
1125    if (result == 0)
1126       result = ISHELL_CreateInstance(piShell, AEECLSID_IMAGEWIDGET, (void **)&me->piBackground);
1127 
1128    if (result == 0) {
1129       IWIDGET_SetFlags(me->piBackground, IDF_ALIGN_RIGHT | IDF_ALIGN_BOTTOM);
1130 
1131       // Insert, extent will be fixed up in SetDisplay below
1132       result = IROOTCONTAINER_Insert(me->piContainer, me->piBackground, WIDGET_ZBOTTOMMOST, &pos);
1133    }
1134 
1135    if (result == 0)
1136       // Construct title
1137       result = ISHELL_CreateInstance(piShell, AEECLSID_IMAGESTATICWIDGET, (void **)&me->piTitle);
1138 
1139    if (result == 0) {
1140       extent.height = 15;
1141       // Set title font to bold by default.  Apps and themes can override it.
1142       IWIDGET_SetFontClass(me->piTitle, AEECLSID_FONTSYSBOLD);
1143 
1144       IWIDGET_SetShadowOffsetY(me->piTitle, 0);
1145       IWIDGET_SetBorderWidth(me->piTitle, 0);
1146       IWIDGET_SetExtent(me->piTitle, &extent);
1147       // Add to container
1148       result = IROOTCONTAINER_Insert(me->piContainer, me->piTitle, WIDGET_ZTOPMOST, &pos);
1149    }
1150 
1151    if (result == 0)
1152       // Construct Softkeys
1153       result = ISHELL_CreateInstance(piShell, AEECLSID_SOFTKEYWIDGET, (void **)&me->piSoftkeys);
1154 
1155    if (result == 0) {
1156       IWIDGET_SetShadowOffsetY(me->piSoftkeys, -1);
1157       IWIDGET_SetBorderWidth(me->piSoftkeys, 0);
1158       IWIDGET_SetExtent(me->piSoftkeys, &extent);
1159       IWIDGET_SetLeftPadding(me->piSoftkeys, 2);
1160       IWIDGET_SetRightPadding(me->piSoftkeys, 2);
1161 
1162       // Insert at 0, 0. Correct positioning will happen in SetDisplay
1163       result = IROOTCONTAINER_Insert(me->piContainer, me->piSoftkeys, WIDGET_ZTOPMOST, &pos);
1164    }
1165 
1166    if (result == 0)
1167       result = RootForm_SetDisplay(me, piDisplay);
1168 
1169    if (result == 0) {   
1170       char* pTheme = 0;
1171       IFORM_SetThemeBaseName(ROOTFORM_TO_IFORM(me), "Root");
1172 
1173       IFORM_GetThemeBaseName(ROOTFORM_TO_IFORM(me), &pTheme);
1174       pTheme = (pTheme) ? pTheme : "(None)";
1175 
1176       BUIT_LOG("FORMS EVT: Construct Set Theme Started for %s", pTheme);
1177 
1178       IROOTFORM_SetThemeFileName(ROOTFORM_TO_IROOTFORM(me), "theme.bar");
1179 
1180       BUIT_LOG("FORMS EVT: Construct Set Theme Finished for %s", pTheme);
1181 
1182    } else {
1183       RootForm_Dtor(me);
1184    }
1185 
1186    RELEASEIF(piDisplay);
1187    RELEASEIF(piCanvas);
1188    
1189    return result;
1190 }
1191 
1192 
1193 int RootForm_New(IRootForm **ppo, IModule *piModule, IShell *piShell)
1194 {
1195    RootForm *me = MALLOCREC_VTBL(RootForm, IRootForm);
1196    int result;
1197 
1198    *ppo = (IRootForm *)me;
1199 
1200    if (!me)
1201       return ENOMEMORY;
1202 
1203    result = RootForm_Construct(me, GETVTBL(me, IRootForm), piModule, piShell);
1204    
1205    if (result != 0) {
1206       *ppo = NULL;
1207       FREE(me);
1208    }
1209    
1210    return result;
1211 }
高通公司的代码示例

 

posted @ 2019-11-13 22:49  Hengs  阅读(633)  评论(0编辑  收藏  举报