|
OOFILE | Downloads | Purchasing | Press | Services | Company Information | Soapbox | References | F.A.Q. | HOME |
You only need to read this document if you are interested in HOW the AppMaker MFC generator works, including some ways in which it generates code. It is essential reading for anyone trying to modify the generator.
Places which may need updating are marked with comments <** **>
Comments like Prosise p298 refer to pages in Jeff Prosise's "Programming Windows95 with MFC". The 2nd edition "Programming Windows with MFC" of this book is highly recommended and any new references will include quotes and Prosise 2e.
Currently all commands are passed through the uniquifying process which assigns back to the name, including the standard commands in AM Prefs. We also update the shortID field. Hence, after MFC generation you are asked if you want to save your document. This is common to several (most?) AppMaker languages.
AppMaker operates under the assumption that Windows will be connected to a Document's data (by default, to the DataDef "docData") but Dialogs may have their own private DataDef used to get values out of the controls on the dialog.
With MFC we have a choice of three Windowing models:
SDI
Single Document per instance of the application and only one main Window containing
the menu bar, connected to the document. You can open separate floating Dialogs.
MDI
Multiple Documents allowed at once, with an overall frame window containing
the menu bar and document windows restricted within the frame window (most users
maximise the frame window but it can be used without occupying the entire screen).
You can also have free-floating dialogs extend outside the frame window.
FDI
Unofficially, the "Floating Document Interface" as used in CodeWarrior
(which also offers MDI) and popularized to Windows developers in Visual BASIC.
(It may also be referred to as the Project or Workspace model.) It operates
like an MDI model which has freed up document windows and comes closest to the
Macintosh paradigm. However, the menubar is still within a window and not just
at the top of the screen (although most users would keep the "menu window"
at the top).
AppMaker/MFC provides makefiles for all the above (**FDI yet to be implemented as of September 2000**).
In all three cases, Dialogs are handled as generating standalone dialog windows.
The AppMaker Windows generate slightly different code depending on the model: SDI - only the first AM Window is invoked and it takes up the "main" window. (we generate resources for all the other windows but not currently code to create them - you could still call their MakeWindow factory methods).
MDI - each of the AM Windows will generate a Window that opens as soon as you open or create a document. This child window is restricted to the MDI frame. Multiple Windows in AM mean generation of multiple views for a single document and functions on the document to make each of those visible, so you can close a window without closing the document. If you remember the DialogDirector classes in TCL, the frames created for each child window resemble the "Controller" role played by DialogDirector.5
FDI - each of the AM Windows will generate a Window that opens as soon as you open or create a document. This window is freely draggable around the desktop.
The file resource.h must contain symbolic names for all the MFC controls & dialogs etc. - it is used by the resource editor to provide the translation for symbolic names in the .rc file.
Generation of these symbolic names is unique to MFC - we only generate symbolic names for Command ID's in PowerPlant. <** is this still true? **>
Remember that these symbolic names are menu item and control ID's, and NOT corresponding to PP commands. The name comes from the menu item or control name, NOT from the associated command title.
However, there's a little bit of cross-over for use of the default commands. If you have default OK or Cancel commands on a button, for example, then the symbolic IDOK or IDCANCEL will be used, rather than symbols based on the button name.
Note: this implies we should add standard commands to the AM Interface: Yes, No, Retry, Abort, Ignore, Help <** discuss with Spec **>
ID's are all generated in the loop that calls writeID to generate entries in the resource.h file. Ultimately we call uniquifyNameAndID for controls, dialogs and menu components.
This overloaded routine makes sure names are unique within a global namespace, given a suitable prefix, to make sure we put unique entries into resource.h but don't keep generating names unnecessarily (eg: if the Back button exists on every screen, we want only one IDC_BACK identifier, not 70 variations).
To avoid the overhead of storing the symbolic names back into the AM project, we have another calcSymbName method added. This avoids the uniquifyNameAndId being called repeatedly - the global namespaces being searched in the MFC generator make this much less desirable than for PP.
To avoid confusion with the original PP templates, getMcmdNr & getCcmdNr are replaced by the logic in writeID which, if a command is not standard, will call uniquifyNameAndID.
Menu items
- if standard command use standard ID (eg: ID_EDIT_CUT)
- else
- name uniquified with ID_ prefix & generated into resource.h
- symbolic name always obtained from calcSymbName to above rules
- ID range starts at 32769 but we use the first two values for Revert
and Show Clipboard (standard on Mac but not Windows)
Controls
- if standard command use standard ID (eg: IDOK)
- else
- name uniquified with IDC_ prefix & generated into resourc.h
- symbolic name always obtained from calcSymbName to above rules
- ID range starts at 8
Dialogs
- ID range starts at 2
- name uniquified with IDD_ prefix
Nested Views
- treated as Dialogs
- ID range starts at 1 <** is this correct/safe? **>
- name uniquified with IDD_ prefix & control number suffix
<** PP needs updating to 2.5.2 **> <** Contents & Roles of Template Files below is correct **>
GenWhat contains large Application.genResources which invokes dialog.write and window.write (in Dialog and Window respectively). Through the inherited View.writeItems (in views) the nested items are written.
Utility routines for writing items to the resource file are combined in ItemResources.
Nested views are written by View.writeItems calling View.writeSubItems which explicitly calls WriteItems on the subitems. It's a recursive solution.
Resource ID's are unsigned longs for PPobs which are usually alphanumeric.
GenResources contains large Application.genResources which invokes dialog.write and window.write (in WdwsAndDlgs). Through the inherited View.writeItems the nested items are written. All these resource writing subroutines are stored in WdwsAndDlgs.
Under MFC we must generate separate dialogs to simulate a nested view structure. (Ironically this is easier to edit than Constructor's overlaid panes for tabbed panels.)
Nested views are implemented as separate dialog resources generated by a prepass, View.preprocessNestedViews. The code to link these dialogs to their parents is generated separately and is not resource-based, just C++. Nested views encountered whilst writing the resources are therefore ignored.
Unlike the PowerPlant approach, there is no way to attach a command directly to a control. MFC is more like traditional Mac programming in that you respond to events such as a mouse button being released on a given object.
In classical MFC you have an ON_BN_CLICKED macro specify that a given CButton control should call a handler function when clicked. The naming convention is that a button called Return will have a handler OnReturn().
The compromise for AppMaker generation is that the handler names are named after the commands. Thus, if you have a button named Return with the command Back, the button will call a DoBack method. These methods are also used for menu handling.
If you don't specify a command, a button handler will be generated that follows the normal MFC convention. Other handlers are only generated if commmands exist, ie: clicks on Checkboxes and Popup menus and single/double-clicks on lists. (As in PP, the assumption is that these are normally value-entries rather than command objects.)
The hookup to command handlers is (in classical MFC) driven by the button symbolic identifiers, therefore we can't just use the command loop from PowerPlant generator but also have to loop through window items. ie: the window items know their names and commands but the commands don't have knowledge of which window items use them.
For the Document and App generators, we of course just work from the command list as for PP. <** not sure about this **>
Note that there is a generation loop for these message handlers, generating the MESSAGE MAP macros, that corresponds to the PowerPlant ListenToMessage cases generation. When using the PowerPlant portability kit, we have ListenToMessage generated instead (and it was copied straight from the current PP generators).
Data exchange (DDX) is MFC's mechanism for copying data between controls and data structures that you supply. It is only used by the code generator for non-OOFILE fields. OOFILE supplies its own mechanism for copying data between onscreen controls and the database (which happens field-by-field, not on exiting a dialog).
The DoDataExchange virtual method is also used to hookup the Win controls to the MFC objects (equivalent to PP's FinishCreateSelf).
When the MFC generator is revised to support the latest AppMaker DataDefs facility, it will copy between controls and the DataDef structures (this is still pending due to low demand for Classic MFC).
For now, we generate public member variables in the MFC dialog as most MFC examples show. This may be retained as an option in future.
See Prosise p361 for discussion of accessing dialog members.
Prosise p405 deriving controls in Dialogs.
Loading ComboBoxes (MFC Internals p213) uses extra DLGINIT resource that describes the sequence of MFC messages sent to load combos or lists.
In PowerPlant we generally use factory functions, which AppMaker generates to not only create the dialog but then call ConnectToData.
Although it is not standard MFC, it's not that strange an idiom to propagate into the MFC code. However, for modal dialogs, we also want to generate a flavour of their ctor that takes mData as a 2nd param.
Classical MFC uses the DoDataExchange method to initialise controls from data members and copy data back.
What is not obvious is that if you use DDX_Control calls in this method that it performs the linkage/creation of the c++ objects to manage OS controls. This is due to an ultimate call to GetDlgItem which, if an object doesn't exist for an OS control, creates one through the CreateObject RTCI mechanism (MFC Internals p159). (Do not underestimate the importance of this subtle point as, like many MFC issues, there's no visible relationship!).
If you want to link OS controls to c++ objects outside this context, CWnd::SubclassDlg(ID, pParent) is the appropriate call, containing very similar logic to DDX_Control but without requiring a CDataExchange object.
Most importantly, if using nested views (in tab panels) we make all our control objects at the topmost layer, rather than using DoDataExchange in the individual nested dialogs.
In generation runtime, the PowerPlant templates have two levels of redirection because they need to generate CDEF ID's. The Properties template contains getProcID procedures which are used in getClassID to create matching 4 char int identifiers. The procID stuff is also used in writing resources.
The MFC generators have a much simpler range of control flavours so currently bypass getProcID and set similar classID variables in getClassID.
Search the MFC templates for getClassID implementations to see local documentation on which flavours are supported or ignored.
The PowerPlant templates make the Dialog a Listener to LEditText's explicitly and (by virtue of generating a RidL) it is already a Listener to Controls.
The message sent on clicking a control comes from the SetValue method calling LControl::BroadcastValueMessage. The ValueMessage is written to the PPob rather than being set in code.
LEditText::HandleKeyPress calls UserChangedText which similarly calls BroadcastMessage to send the ValueMessage.
Note:
Anyway, our target behaviour for MFC is to respond to changes in edit fields as we tab out of the field and changes in controls when the mouse is released. On closing a dialog the current edit field should be copied if it has been changed. We can't blindly update the DataDef structure because there may not have been any changes - we want sensible "dirty document" detection.
shortID is updated all the time with unique values so each time you generate, your AppMaker document will be dirtied and prompt to save (this is also common with other generators).
MENU ID's and symbolic names are generated from the Title not the name, hence not unique.
Standalone menu resources lack a space between the symbolic name and the word "MENU"
The 'next default values' section at the bottom of resource.h is hardcoded, not updated to the actual next available values.
Contents & Roles of Template Files ================================== App --- contains Application.genApp which writes out the App class, also utilities Application.getNormalClassName Application.getAppCommands Application.genApp Application.genOverrideH Application.genOverrideCp Application.baseMain Commands -------- contains utilities related to writing command constants and relating commands to the classes that react to those commands, or windows opened by commands Application.genCmdCodes Application.getAppCommands Application.getDocCommands Document.getDocCommands View.getViewCommands WindowItem.getCommands List.getCommands Command.isStandard Root.getDialogList Command.getCommandDialogs Command.getInvokedDialog Command.declareDoCommand Command.genMsgMapEntry Command.declareDoCommandMsg Dialog.genIncludeDialog Command.enable Command.callDoCommand Command.callDoCommandHandled Command.genDeclDoCommand Command.genDoCommand Command.genDoCommandBody Command.genInvokeDialog Command.genFinishDialog Command.callFinishDialog Command.addIncludeName Application.genSrcCmdIncludes Document.genSrcCmdIncludes Command.calcSymbName Command.writeID Command.baseWriteID DataDef ------- contains methods to generate data definitions for different levels of the tree of App and Doc that can own DataDefs and DataDef utilities to write these definitions DataDef.getNormalClassName Application.uniquifyDataDefs DataDef.uniquifyMembers Application.genDataDefs DataDef.genDataDef Member.uniquifyNameID Member.inferKind DataDef.genIncludeNames DataDef.genOverrideH DataDef.genOverrideCp Dialog ------ contains Dialog.genDialog which writes out the Dialog classes, and utilities: Dialog.getNormalClassName Dialog.genDialog Dialog.genOverrideH Dialog.genOverrideCp Doc --- contains Document.genDoc which writes out the Document class, and utilities: Document.getNormalClassName Document.genDoc Document.genOverrideH Document.genOverrideCp GenMainSDI GenMainMDI GenMainFDI GenMainSDIPP GenMainMDIPP GenMainFDIPP ------- contain the Application.main declaring genPPcompatible and genAppWindowingModel to vary builds GenResources ------------ contains Application.genResources to write the resource script and utilities: Application.genResources Application.writeMisc Application.writeRsrcHead Application.writeStrings Application.writeVersion Application.writeRsrcTail Application.initCommandIDs Application.writeCommandIDs View.uniquifyNameAndID WindowItem.uniquifyItems GenWhat ------- contains the Application & Root level utility procedures Application.genSources Application.getMainDoc Root.calcMDIchildFrameClass Root.calcMDIchildType Root.getClassName Root.tryGenOverride Application.genStdInclude Application.genDef Application.checkHasStatusBar Application.checkHasToolBar Root.baseUniquifyNameAndID Root.calcWinName Root.cleanMacStringForWin Root.calcASCIIchar Root.baseCalcSymbName Root.calcPPname Root.calcPPclass Application.genAppleScript iButton ------- contains procedures for writing Buttons in resources and code Button.writeItem Button.getClassName Button.addIncludeName Button.genMemberDecl Button.genInitMember Button.ConnectToData Button.DataChanged Button.declareItemDoCommandMsg Button.declareItemDoCommand Button.genItemDoCommand Button.writeID Button.writeAttachedImage Button.calcBMPButtonName Button.calcPPname Button.calcPPclass iCheckBox --------- contains procedures for writing CheckBoxes in resources and code CheckBox.writeItem CheckBox.genDataExchangeEntry CheckBox.genDataMemberDecl CheckBox.getClassName CheckBox.addIncludeName CheckBox.genMemberDecl CheckBox.genGetSetDecl CheckBox.genGetSetDef CheckBox.setFromData CheckBox.getData CheckBox.MessageName CheckBox.ConnectToData CheckBox.DataChanged CheckBox.ListenToMessage CheckBox.calcPPname CheckBox.calcPPclass iEditText --------- contains procedures for writing Buttons in resources and code EditText.getClassID EditText.writeItem EditText.genDataExchangeEntry EditText.genDataMemberDecl EditText.getClassName EditText.addIncludeName EditText.genMemberDecl EditText.genLinkFieldCall EditText.getOOFitem EditText.MessageName EditText.ConnectToData EditText.DataChanged EditText.ListenToMessage EditText.calcPPname EditText.calcPPclass iIcon ----- contains procedures for writing Icons in resources and code Icon.writeItem Icon.genInitMember iImage ----- contains procedures for writing BITMAP items to access Images in resources and code ImageItem.getClassID ImageItem.getClassName ImageItem.addIncludeName ImageItem.writeItem ImageItem.writeID ImageItem.calcPPclass ImageItem.genInitMember iLayer ------ contains procedures for writing Layers in resources and code Layer.writeItem Layer.writeItems Layer.writeID Layer.writeLayers Layer.adjustedSizes Layer.genMemberDecl Layer.genLayerInit Layer.genInitMembers Layer.genLayerDecl Layer.getClassName Layer.genInitMember Layer.genCtorInitEntry iLine ----- contains procedures for writing simple static Lines in resources and code Line.genInitMember Line.writeItem iList ----- contains procedures for writing Lists in resources and code List.writeItem List.getClassName List.addIncludeName List.genMemberDecl List.getOOFitem List.genOOFviewLink List.genOOFtableDecl List.genOOFtableDelete List.checkHierTables List.genItemDoCommand List.declareItemDoCommandMsg List.declareItemDoCommand List.calcPPname List.calcPPclass List.writeID Images ------ contains procedures for writing Images in resources and separate files Image.writeBMPfile Image.writeBMPfilePlaceholder WindowItem.maybeWriteImage Image.calcBmpName Image.calcBmpMacFileName Image.write Image.calcSymbName Image.writeID iPopup ------ contains procedures for writing Popup menus in resources and code Popup.writeItem Popup.addIncludeName Popup.genMemberDecl Popup.calcPPname Popup.calcPPclass iProgressBar ------------ ProgressBar.getClassID ProgressBar.writeItem ProgressBar.genDataExchangeEntry ProgressBar.genDataMemberDecl ProgressBar.getClassName ProgressBar.calcPPname ProgressBar.calcPPclass ProgressBar.addIncludeName ProgressBar.genMemberDecl ProgressBar.genGetSetDecl ProgressBar.genGetSetDef ProgressBar.setFromData ProgressBar.getData ProgressBar.MessageName ProgressBar.ConnectToData ProgressBar.DataChanged ProgressBar.ListenToMessage ProgressBar.genInitMember iRadioButton --------------------- contains procedures for writing Radio Buttons in resources and code RadioButton.writeItem RadioButton.genDataExchangeEntry RadioButton.genDataMemberDecl RadioButton.addIncludeName RadioButton.genMemberDecl RadioButton.calcPPname RadioButton.calcPPclass iRadioGroup ----------- contains procedures for writing Radio Groups in resources and code, including just as plain group boxes RadioGroup.writeItem RadioGroup.writeRadios RadioGroup.writeGroup RadioGroup.writeItems RadioGroup.addIncludeName RadioGroup.genInitMember RadioGroup.calcPPname iRectangle ---------- contains procedures for writing Rectangles (group boxes) in resources and code GroupBox.genInitMember GroupBox.writeItem iScrollBar ---------- ScrollBar.getClassID ScrollBar.writeItem ScrollBar.genDataExchangeEntry ScrollBar.genDataMemberDecl ScrollBar.getClassName ScrollBar.calcPPname ScrollBar.calcPPclass ScrollBar.addIncludeName ScrollBar.genMemberDecl ScrollBar.genGetSetDecl ScrollBar.genGetSetDef ScrollBar.setFromData ScrollBar.getData ScrollBar.MessageName ScrollBar.ConnectToData ScrollBar.DataChanged ScrollBar.ListenToMessage ScrollBar.genInitMember iStaticText ----------- contains procedures for writing StaticText in resources and code StaticText.writeItem StaticText.writeID StaticText.addIncludeName StaticText.genMemberDecl StaticText.genInitMember StaticText.genLinkFieldCall StaticText.getOOFitem StaticText.calcPPname StaticText.calcPPclass iTabPanel ----- contains procedures for writing TabPanels in resources and code TabPanel.writeItem TabPanel.getClassName TabPanel.addIncludeName TabPanel.genMemberDecl TabPanel.genInitMember TabPanel.genGetSetDecl TabPanel.genGetSetDef TabPanel.setFromData TabPanel.getData TabPanel.MessageName TabPanel.ConnectToData TabPanel.DataChanged TabPanel.ListenToMessage TabPanel.calcPPname TabPanel.calcPPclass Main ---- contains Application.genMain which writes out the CMainFrame class (application frame window) and appropriate ChildFrame classes for MDI applications. Menus ----- contains utilities related to menu dictionaries and writing menu resources Application.initMenuKindDict Menu.findHierMenus MenuBar.write Menu.writeStandalone Menu.write MenuItem.write MenuBar.writeAccelerators Menu.writeAccelerators MenuItem.writeAccelerators Menu.writeID MenuItem.writeID Root.getStandardisedCommandName Application.genCmdCodes Menu.calcSymbName MenuItem.calcSymbName MenuItem.uniquifyNameAndID MFCSDI.AMMake MFCMDI.AMMake MFCFDI.AMMake MFCSDIPP.AMMake MFCMDIPP.AMMake MFCFDIPP.AMMake ------------- Makefiles controlling the build of the software for the AM Compiler using GenMain variants OOFILEbits ---------- utilities for OOFILE database generation dbTable.genHdrFieldDecls dbTable.genHdrFieldDefs dbTable.genHdrFieldIndexDefs dbField.genHdrFieldDecl dbField.genHdrFieldDef dbField.genHdrFieldIndexDef dbField.getFieldTypeName dbField.getFieldIndexTypeName dbTable.getDefaultSort dbView.genViewAppends Properties ---------- contains utilities for calculating a single ProcID and other properties used to distinguish different flavours of control Button.getProcID Button.getProperties CheckBox.getProcID CheckBox.getProperties EditText.getProcID GroupBox.getProcID ImageItem.getProcID ImageItem.getProperties Layer.getProcID LayerGroup.getProcID Line.getProcID List.getProcID MultiPict.getProcID Palette.getProcID Popup.getProcID ProgressBar.getProcID ProgressBar.getProperties RadioButton.getProcID RadioButton.getProperties RadioGroup.getProcID ScrollBar.getProcID ScrollBar.getProperties StaticText.getProcID TabPanel.getProcID Miscellany.getProcID WindowItem.getProperties Image.getGraphicType WindowItem.getGraphicKinds WindowItem.getImageIDs WindowItem.putImageIDs WindowItem.putPaletteInfo Root.getImageID Root.writeGraphicResDef Root.getApprenticeID Root.writeApprenticePICTs Styles ------ contains utilities related to menu dictionaries and writing menu resources View.initializeStyles View.accumulateStyles View.initialize3D View.accumulate3D View.checkStdCtlFont View.checkStdTextFont Color.write Color.writePart TargetData ---------- contains utilities used in combination with DataDefs for data associated with apps, windows etc. Application.makeData Document.makeData Dialog.makeData Dialog.makeDataDef Panel.makeData Panel.makeDataDef Window.makeData WindowItem.makeData WindowItem.makeTarget Checkbox.makeTarget EditText.makeTarget List.makeTarget Palette.makeTarget Popup.makeTarget ProgressBar.makeTarget RadioGroup.makeTarget ScrollBar.makeTarget TabPanel.makeTarget WindowItem.makeTargetMember DataDef.addMember WindowItem.getTargetAccessor WindowItem.getTargetGetter WindowItem.getTargetSetter WindowItem.getTargetID WindowItem.getEnablerName WindowItem.getEnablerID List.getSourceName WindowItem.addDataName View ---- contains utilities for view c++ codegen for Windows and Dialogs View.genOptBlankLine View.genIncludeData View.genDataExchangeEntries View.getNormalClassName View.genView *** now disused - see Dialog and Window.genWindow View.genItemDoCommands View.genSrcInitMembers View.genSrcItemIncludes View.genHdrItemFwdClasses View.getAllDlgNames View.genOOFtableDecls View.genOOFtableDeletes View.genOOFviewLinks View.getOOFitems View.genLinkFieldCalls View.declareItemDoCommandMsgs View.declareItemDoCommands View.genCtorInitEntries WdwsAndDlgs ----------- contains utilities related to views, view IDs and writing view item resources View.writeItems View.baseWriteItems WindowItem.baseWriteItems View.writeLayers View.baseWriteLayers View.writeItemIDs WindowItem.adjustedSizes View.adjustedSizes View.writeID View.write View.calcSymbName WindowItem.writeID WindowItem.baseWriteID WindowItem.writeItem WindowItem.calcSymbName WindowItem.uniquifyNameAndID Window ------ contains Window.genWindow which writes out the Window classes Window.getNormalClassName Window.genWindow Window.genCallCreate Window.genOverrideH Window.genOverrideCp Window.genIncludeWindow WindowItem ---------- contains utilities for item c++ codegen mainly default DataDef and Classic MFC Data Exchange behaviours WindowItem.DefineMessage WindowItem.SetInitialValue WindowItem.SetChangedValue WindowItem.EnableControl WindowItem.ChangeEnabling WindowItem.SetTargetValue WindowItem.getClassName WindowItem.addIncludeName WindowItem.genMemberDecl WindowItem.genInitMember WindowItem.genDataMemberDecl WindowItem.baseGenInitMember WindowItem.genPPMemberDecl WindowItem.genDataMemberDecls WindowItem.genGetSetDecl WindowItem.genGetSetDef WindowItem.getTabField WindowItem.MessageName WindowItem.genMessageName WindowItem.ConnectToData WindowItem.genConnectToData WindowItem.DataChanged WindowItem.genDataChanged WindowItem.ListenToMessage WindowItem.genListenToMessage WindowItem.setFromData WindowItem.getData WindowItem.getFinalData WindowItem.genSetFromData WindowItem.genGetData WindowItem.genGetFinalData WindowItem.addClassName WindowItem.getAllClassNames WindowItem.getAllDataNames WindowItem.getAllIncludeNames WindowItem.genMemberDecls WindowItem.genInitMembers WindowItem.baseGenInitMembers WindowItem.genGetSetDecls WindowItem.genGetSetDefs WindowItem.getDlgNames WindowItem.genLinkFieldCalls WindowItem.genLinkFieldCall WindowItem.getOOFitems WindowItem.getOOFitem WindowItem.genOOFtableDecls WindowItem.genOOFtableDecl WindowItem.genOOFtableDeletes WindowItem.genOOFtableDelete WindowItem.genOOFviewLinks WindowItem.genOOFviewLink WindowItem.genCtorInitEntry WindowItem.genCtorInitEntries WindowItem.genDataExchangeEntries WindowItem.genDataExchangeEntry WindowItem.genMessageMapEntries WindowItem.genMessageMapEntry WindowItem.genLayerDecl WindowItem.genLayerDecls WindowItem.genItemDoCommand WindowItem.declareItemDoCommandMsg WindowItem.declareItemDoCommand WindowItem.genLayerInit WindowItem.genLayerInits