Apostate Café


By joshua

Pubished:

Posted in: programming

Hungarian Notionan

Hungarian Notionan
- [Hungarian Notation][] - [Object Hungarian Notation Naming Conventions for VB][] - [From Win98 Developers Handbook][] - [More VB stuff][] - [From some unknown web page][] - [Recommended for Delphi][] Hungarian Notation ================== Charles Simonyi Microsoft Corporation Reprinted November 1999 MSDN Online Library, Program Identifier Naming Conventions ===================================== This monograph is intended to give you the flavor of the major ideas behind the conventions. When confronted with the need for a new name in a program, a good programmer will generally consider the following factors to reach a decision: 1. Mnemonic value—so that the programmer can remember the name.

2. Suggestive value—so that others can read the code. 3. “Consistency”—this is often viewed as an aesthetic idea, yet it also has to do with the information efficiency of the program text. Roughly speaking, we want similar names for similar quantities.

4. Speed of the decision—we cannot spend too much time pondering the name of a single quantity, nor is there time for typing and editing extremely long variable names. All in all, name selection can be a frustrating and time consuming subtask. Often, a name that satisfies some of the above criteria will contradict the others. Maintaining consistency can be especially difficult. Advantages of the Conventions ============================= The following naming conventions provide a very convenient framework for generating names that satisfy the above criteria. The basic idea is to name all quantities by their types. This simple statement requires considerable elaboration. (What is meant by “types”? What happens if “types” are not unique?) However, once we can agree on the framework, the benefits readily follow. The following are examples: 1. The names will be mnemonic in a very specific sense: If someone remembers the type of a quantity or how it is constructed from other types, the name will be readily apparent.

2. The names will be suggestive as well: We will be able to map any name into the type of the quantity, hence obtaining information about the shape and the use of the quantity.

3. The names will be consistent because they will have been produced by the same rules.

4. The decision on the name will be mechanical, thus speedy. 5. Expressions in the program can be subjected to consistency checks that are very similar to the “dimension” checks in physics. Type Calculus ============= As suggested above, the concept of “type” in this context is determined by the set of operations that can be applied to a quantity. The test for type equivalence is simple: could the same set of operations be meaningfully applied to the quantities in questions? If so, the types are thought to be the same. If there are operations that apply to a quantity in exclusion of others, the type of the quantity is different. The concept of “operation” is considered quite generally here; “being the subscript of array *A*” or “being the second parameter of procedure *Position*” are operations on quantity *x* (and *A* or *Position* as well). The point is that “integers” *x* and *y* are not of the same type if *Position (x,y)* is legal but *Position (y,x)* is nonsensical. Here we can also sense how the concepts of type and name merge: *x* is so named because it is an x-coordinate, and it seems that its type is also an x-coordinate. Most programmers probably would have named such a quantity *x*. In this instance, the conventions merely codify and clarify what has been widespread programming practice. Note that the above definition of type (which, incidentally, is suggested by languages such as SIMULA and Smalltalk) is a superset of the more common definition, which takes only the quantity’s representation into account. Naturally, if the representations of *x* and *y* are different, there will exist some operations that could be applied to *x* but not *y*, or the reverse. Let us not forget that we are talking about conventions that are to be used by humans for the benefit of humans. Capabilities or restrictions of the programming environment are not at issue here. The exact determination of what constitutes a “type” is not critical, either. If a quantity is incorrectly classified, we have a style problem, not a bug. Naming Rules ============ My thesis discusses in detail the following specific naming rules: 1. Quantities are named by their type possibly followed by a qualifier. A convenient (and legal) punctuation is recommended to separate the type and qualifier part of a name. (In C, we use a capital initial for the qualifier as in *rowFirst*: *row* is the type; *First* is the qualifier.)

2. Qualifiers distinguish quantities that are of the same type and that exist within the same naming context. Note that contexts may include the whole system, a block, a procedure, or a data structure (for fields), depending on the programming environment. If one of the “standard qualifiers” is applicable, it should be used. Otherwise, the programmer can choose the qualifier. The choice should be simple to make, because the qualifier needs to be unique only within the type and within the scope—a set that is expected to be small in most cases. In rare instances more than one qualifier may appear in a name. Standard qualifiers and their associated semantics are listed below. An example is worthwhile: *rowLast*is a type *row* value; that is, the last element in an interval. The definition of *Last* states that the interval is “closed”; that is, a loop through the interval should include *rowLast*as its last value.

3. Simple types are named by short tags that are chosen by the programmer. The recommendation that the tags be small is startling to many programmers. The essential reason for short tags is to make the implementation of rule 4 realistic. Other reasons are listed below.

4. Names of constructed types should be constructed from the names of the constituent types. A number of standard schemes for constructing pointer, array, and different types exist. Other constructions may be defined as required. For example, the prefix *p* is used to construct pointers. *prowLast*is then the name of a particular pointer to a row type value that defines the end of a closed interval. The standard type constructions are also listed below. In principle, the conventions can be enriched by new type construction schemes. However, the standard constructions have proved to be sufficient in years of use. It is worth noting that the types for data structures are generally not constructed from the tags of their fields. First of all, constructions with over two components would be unwieldy. More important, the invariant property of data structure, the set of operations in which the constructions participate, seems to be largely independent of the fields of the structure that determine only the representation. We all have had numerous experiences with changes in data structures that left the operations (but not the implementation of the operations) unchanged. Consequently, I recommend the use of a new tag for every new data structure. The tag with some punctuation (upper case initial or all upper case) should also be used as the structure name in the program. New tags should also be used if the constructions accumulate to the point where readability suffers. In my experience, tags are more difficult to choose than qualifiers. When a new tag is needed, the first impulse is to use a short, descriptive, common, and generic English term as the type name. This is almost always a mistake. One should not preempt the most useful English phrases for the provincial purposes of any given version of a given program. Chances are that the same generic term could be equally applicable to many more types in the same program. How will we know which is the one with the pretty “logical” name, and which have the more arbitrary variants typically obtained by omitting various vowels or by other disfigurement? Also, in communicating with the programmer, how do we distinguish the generic use of the common term from the reserved technical usage? By inflection? In the long run, an acronym that is not an English word may work out the best for tags. Related types may then share some of the letters of the acronym. In speech, the acronym may be spelled out, or a pronounceable nickname may be used. When hearing the special names, the informed listener will know that the special technical meaning should be understood. Generic terms should remain free for generic use. For example, a color graphics program may have a set of internal values that denote colors. What should one call the manifest value for the color red? The obvious choice (which is “wrong” here) is *RED*. The problem with *RED* is that it does not identify its type. Is it a label or a procedure that turns objects *RED*? Even if we know that it is a constant (because it is spelled all caps, for example), there might be several color-related types. Of which one is *RED* an instance? If I see a procedure defined as paint (color), may I call it with *RED* as an argument? Has the word *RED* been used for any other purpose within the program? So we decide to find a tag for the color type and use the word *Red* as a qualifier. Note that the obvious choice for the qualifier is in fact that the “correct” one! This is because the use of qualifiers are not hampered by any of the above difficulties. Qualifiers are not “exclusive” (or rather they are exclusive only within a smaller set), so we essentially need not take into account the possibility of other uses of the term *Red*. The technical use of the term will be clear to everyone when the qualifier is paired with an obviously technical type tag. Since qualifiers (usually) do not participate in type construction, there is no inherent reason why they would need to be especially short. Conversely, the tag for the type of the color value should not be “color.” Just consider all the other color-related types that may appear in the graphics program (or in a future variant): hardware encoding of color, color map entry number, absolute pointer to color map entry, color values in alternate color mapping mode, hue-brightness-saturation triples, other color values in external interfaces; printers, plotters, interacting external software, and so on. Furthermore, the tag will have to appear in names with constructed types and qualifiers. A typical arbitrary choice could be *co* (pronounced *see-oh*). Or, if *co* was already taken, *cv*, *cl*, *kl*, and so on. Note that the mnemonic value of the tags is just about average: not too bad, but not too good either. The conventions cannot help with creating names that are inherently mnemonic. Instead, they identify, compress, and contain those parts of the program that are truly individual, thus arbitrary. The lack of inherent meaning should be compensated by ample comments whenever a new tag is introduced. This is a reasonable suggestion because the number of basic tags remains very small, even in a large system. In conclusion, the name of our quantity would be *coRed*, provided that the color type *co* is properly documented. The value of the name will show later in program segments such as the following: if co == coRed then *mpcopx[coRed]+=dx … At a glance we can see that the variable co is compared with a quantity of its own kind; *coRed* is also used as a subscript to an array whose domain is of the correct type. Furthermore, as we will see, the color is mapped into a pointer to *x*, which is de-referenced (by the \*operator in this example) to yield an *x* type value, which is then incremented by a “delta *x*” type value. Such “dimensional analysis” does not guarantee that the program is completely free from bugs, but it does help to eliminate the most common kinds. It also lends a certain rhythm to the writing of the code: “Let’s see, I have a co in hand and I need an *x*; do I have a *mpcox*? No, but there is a *mpcopx* that will give me a *px*; \**px* will get me the *x*…” Naming for “Writability” ======================== A good yardstick for choosing a name is to try to imagine that there is an extraordinary reward for two programmers if they can independently come up with the same program text for the same problem. Both programmers know the reward, but cannot otherwise communicate. Such an experiment would be futile, of course, for any sizable problem, but it is a neat goal. The reward of real life is that a program written by someone else, which is identical to what one’s own program would have been, is extremely readable and modifiable. By the proper use of the conventions, the idea can be approached very closely, give or take a relatively few tags and possibly some qualifiers. The leverage of the tags is enormous. If they are communicated, are agreed on beforehand, or come from a common source, the goal becomes reachable and the reward may be reaped. This makes the documentation of the tags all the more important. An example of such a consideration is the discretionary use of qualifiers in small scopes where a quantity’s type is likely to be unique, for example in small procedures with a few parameters and locals or in data structures which typically have only a few fields. One might prefer to attach a qualifier even to a quantity with a unique type of “writability,” the ability for someone else to come up with the name without hesitation. As many textbooks point out, the “someone else” can be the same programmer sometime in the future revisiting the long-forgotten code. **Conclusion   **Do not use qualifiers when not needed, even if they seem valuable. Naming Rules for Procedures =========================== Unfortunately, the simple notion of qualified typed tags does not work well for procedure names. Some procedures do not take parameters or do not return values. The scopes of procedure names tend to be large. The following set of special rules for procedures has worked quite satisfactorily: 1. Distinguish procedure names from other names by punctuation, for example by always starting with a capital letter (typed tags of other quantities are in lower case). This alleviates the problem caused by the large scope.

2. Start the name with the tag of the value that is returned, if any. 3. Express the action of the procedure in one or two words, typically transitive verbs. The words should be punctuated for easy parsing by the reader (a common legal method of punctuation is the use of capital initials for every word).

4. Append the list of tags of some or all of the formal parameters if it seems appropriate to do so. The last point is contrary to the earlier remarks on data structure naming. When the parameters to a procedure are changed, typically all uses of the procedure will need to be updated. There is an opportunity during the update to change the name as well. In fact, the name change can serve as a useful check that all occurrences have been found. With data structures, the addition or change of a field will not have an effect on all uses of the changed structure type. Typically, if a procedure has only one or two parameters, the inclusion of the parameter tags will really simplify the choice of procedure name. **Table 1. Some examples for procedure names**
**Name** **Description**
**InitSy ** Takes an *sy* as its argument and initializes it.
**OpenFn** *fn* is the argument. The procedure will “open” the *fn*. No value is returned.

**FcFromBnRn** Returns the *fc* corresponding to the *bn,rn* pair given. (The names cannot tell us what the types *sy*, *fn*, *fc*, and so on, are.)

The following is a list of standard type constructions. (*X* and *Y* stand for arbitrary tags. According to standard punctuation, the actual tags are lowercase.) **Table 2. Standard type constructions** ————————————————————————————————- ————————————————————————————————————————- **pX** Pointer to *X*. **dX** Difference between two instances of type *X*. *X* + *dX* is of type *X*. **cX** Count of instances of type *X*. **mpXY** An array of *Y*s indexed by *X*. Read as “map from *X* to *Y*.” **rgX** An array of *X*s. Read as “range *X*.” The indices of the array are called: **iX **index of the array *rgX*. **dnX** (rare) An array indexed by type *X*. The elements of the array are called: **eX** (rare) Element of the array *dnX*. **grpX** A group of *X*s stored one after another in storage. Used when the *X* elements are of variable size and standard array indexing would not apply. Elements of the group must be referenced by means other then direct indexing. A storage allocation zone, for example, is a *grp* of blocks. **bX** Relative offset to a type *X*. This is used for field displacements in a data structure with variable size fields. The offset may be given in terms of bytes or words, depending on the base pointer from which the offset is measured. **cbX** Size of instances of *X* in bytes. **cwX** Size of instances of *X* in words. ————————————————————————————————- ————————————————————————————————————————- Where it matters, quantities named *mp*, *rg*, *dn*, or *grp* are actually pointers to the structures described above. One obvious problem with the constructions is that they make the parsing of the types ambiguous. Is *pfc* a tag of its own or is it a pointer to an *fc*? Such questions can be answered only if one is familiar with the specific tags that are used in a program. The following are standard qualifiers. (The letter *X* stands for any type tag. Actual type tags are in lowercase.) **Table 3. Standard qualifiers**
**XFirst ** The first element in an ordered set (interval) of *X* values.
**XLast ** The last element in an ordered set of *X* values. *XLast* is the upper limit of a closed interval, hence the loop continuation condition should be: *X*\<=

*XLast*.

**XLim ** The strict upper limit of an ordered set of *X* values. Loop continuation should be: *X *\< *XLim*.
XMax

Strict upper limit for all *X* values (excepting *Max*, *Mac*, and *Nil*) for all other *X*: *X* \< *XMax*. If *X* values start with

*X*=0, *XMax* is equal to the number of different *X* values. The allocated length of a *dnx* vector, for example, will be typically *XMax*.

**XMac ** The current (as opposed to constant or allocated) upper limit for all *X* values. If *X* values start with 0, *XMac* is the current number of *X* values. To iterate through a *dnx* array, for example: `for x=0 step 1 to xMac-1 do … dnx[x] …` or `for ix=0 step 1 to ixMac-1 do … rgx[ix] …`
**XNil ** A distinguished *Nil* value of type *X*. The value may or may not be 0 or -1.
**XT ** Temporary *X*. An easy way to qualify the second quantity of a given type in a scope.
**Table 4. Some common primitive types** ———————————————————————————- ————————————————————————————————————————— **f\ Flag (Boolean, ** logical). If qualifier is used, it should describe the true state of the flag. Exception: the constants **fTrue** and **fFalse**. **w\ Word with ** arbitrary contents. **ch\ Character, usually ** in ASCII text. **b\ Byte, not ** necessarily holding a coded character, more akin to *w*. Distinguished from the *b* constructor by the capital letter of the qualifier in immediately following. **sz\ Pointer to first ** character of a zero terminated string. **st\ Pointer to a ** string. First byte is the count of characters *cch*. **h\ *pp* (in ** heap). ———————————————————————————- ————————————————————————————————————————— The following partial example of an actual symbol table routine illustrates the use of the conventions in a “real life” situation. The purpose of this example is not to make any claims about the code itself, but to show how the conventions can help us learn about the code. In fact, some of the names in this routine are standard. 1 #include “sy.h” 2 extern int *rgwDic; 3 extern int bsyMac; 4 struct SY *PsySz(char sz[]) 6 { 7 char *pch; 8 int cch; 9 struct SY *psy, *PsyCreate(); 10 int *pbsy; 11 int cwSz; 12 unsigned wHash=0; 13 pch=sz; 14 while (*pch!=0 15 wHash=(wHash<>11+*pch++; 16 cch=pch-sz; 17 pbsy=&rgbsyHash[(wHash&077777)%cwHash]; 18 for (; *pbsy!=0; pbsy = &psy->bsyNext) 19 { 20 char *szSy; 21 szSy= (psy=(struct SY*)&rgwDic[*pbsy])->sz; 22 pch=sz; 23 while (*pch==*szSy++) 24 { 25 if (*pch++==0) 26 return (psy); 27 } 28 } 29 cwSz=0; 30 if (cch>=2) 31 cwSz=(cch-2/sizeof(int)+1; 32 *pbsy=(int *)(psy=PsyCreate(cwSY+cwSz))-rgwDic; 33 Zero((int *)psy,cwSY); 34 bltbyte(sz, psy->sz, cch+1); 35 return(psy); 36 } The tag *SY* is the only product specific type in this routine. The definition of *SY* is found in the include file sy.h (fair enough). The type name itself is in all capitals, a common convention. [Line 2][]—says that there is an array of words, which is called *Dic*(tionary). Remember that since *Dic* is a qualifier, it is named traditionally. [Line 3][]—is the offset pointing beyond the last *sy* (see *b* constructor + *Mac* standard qualifier.) One has to guess at this time that this is used for allocating new *sy*’s. The “base” of the offset would also have to be guessed to be *rgwDic*. Actually, the name *grpsy* would have been better instead of *rgwDic*, from this local perspective. In the real program, the *rgwDic* area is used for a number of different purposes, hence the “neutral” name. [Line 4][]—is a procedure declaration. Procedure returns a pointer to an *SY* as the result. The parameter must be a zero-terminated string. [Lines 7-12][]—declare quantities. The usages should be clear from the names. For example, *cwSz* is the number of words in some string (probably the argument), *pbsy* is a pointer to an offset of an *sy* (*p* constructor + *b* constructor). The only qualifier used here is in *wHash*—the hash code. [Line 13][]—*pch* will be a pointer to the first character of *sz*. [Line 16][]—*cch* is the count of characters (c constructor) ostensibly, in *sz*. [Line 17][]—*cwHash* is the number of words in the hash table (I would have called it *ibsyMax*). In a way, the qualifier on *rgbsyHash* could be omitted, but it helps identify the hash table in external contexts. [Lines 17-18][Line 17]—note the opportunities for dimensional checking: pbsy = &rgbsy[…] follows from pX = &rgX[…] pbsy = &psy->bsyNext follows from pX=&pY->X; or pX = &Y.X So even the use of -\> instead of . follows from local context. The *p* on the left hand side signals the need for the *&* on the right. [Line 20][]—introduces a new *sz*, qualified to distinguish it from the argument. The qualifier, very appropriately, is the source of the datum, *Sy*. [Line 23][]—given the use of *szSy* in this line, the name *pchSy* would have been a little more appropriate. No harm done, however. [Lines 29-31][]—this strange code has to do with the fact that the declaration of *SY* includes 2 bytes of *sz*, so that *cwSz* is really the number of words in the *sz*-2 bytes! This should deserve a comment or at least a qualifier *M2* (minus 2) or the like. *cwSY* is the length of the *SY* structure in words. The all caps qualifier is not strictly standard, but it helps to associate the quantity with the declaration of *SY*, rather than with any random *sy* instance. *PsyCreate* is a good procedure name; *PsyCreateCw* would have been even better. In line 32 we can also see an example of dimensional checking: While we have a *psy* inside the parenthesis, we need a *bsy* for the left side (\**pbsy*=*bsy*!) so we subtract the “base” of the *bsy* from the *psy*. bX + base = pX; hence: bX = pX - base. In closing, it is evident that the conventions participated in making the code more correct, easier to write, and easier to read. Naming conventions cannot guarantee *good* code, however; only the skill of the programmer can. Object Hungarian Notation Naming Conventions for VB =================================================== From Microsoft KB Article Q173738 Object Prefix Example ————————————————————————————————————— Form frm frmFileOpen Check box chk ReadOnly Combo box cbo cboEnglish Data-bound combo box dbc dbcEnglish Command button cmd cmdCancel Data dat datBiblio Directory list box dir dirSource Drive list box drv drvTarget File list box fil filSource Frame fra fraLanguage Grid grd grdPrices Data-bound grid dbg dbgPrices Horizontal scroll bar hsb hsbVolume Image img imgIcon Label lbl lblHelpMessage Line lin linVertical List box lst lstPolicyCodes Data-bound list box dbl dblPolicyCode Menu mnu mnuFileOpen OLE container ole oleObject1 Option button opt optFrench Picture box pic picDiskSpace Shape shp shpCircle Text box txt txtGetText Timer tmr tmrAlarm Object Prefix Example ———————————————————————————————————— Vertical scroll bar vsb vsbRate Animation button ani aniMailBox bed Pen Bedit bedFirstName Checkbox chk chkReadOnly Picture clip clp clpToolbar Communications com comFax Control ctl ctrCurrent Data control dat datBiblioDirectory Directory list box dir dirSource Common dialog ctrl dlg dlgFileOpen Drive list box drv drvTarget File list box fil filSource Form frm frmEntry Frame (3d) fra fraStyle Gauge gau gauStatus Group push button gpb gpbChannel Graph gra graRevenue Grid grd grdPrices Pen Hedit hed hedSignature Horizontalscrollbar hsb hsbVolume Image img imgIcon Pen Ink ink inkMap Keyboard key status key keyCaps Label lbl lblHelpMessage Line lin linVertical MDI child form mdi mdiNote MAPI message mpm mpmSentMessage MAPI session mps mpsSession MCI mci mciVideo Menu mnu mnuFileOpen Object obj objUserTable Option Button (3d) opt optRed Outline control out outOrgChart 3d Panel pnl (3d) pnlTitleList Report control rpt rptQtr1Earnings Shape controls shp shpCircle Spin control spn spnPages Timer tmr tmrAlarm Vertical scroll bar vsb vsbRate Database Objects Prefix Example ————————————————————————————————————— ODBC Database db dbAccounts ODBC Dynaset object dyn dynSalesByRegion Field collection fld fldCustomer Field object fld fldAddress Form frm frmNewUser Index object idx idxAge Index collection idx idxNewAge Macro mcr mcrCollectUsers QueryDef object qry qrySalesByRegion Query qry qrySalesByRegion Report rpt rptAnnualSales Snapshot object snp snpForecast Table object tbl tblCustomer TableDef object tbd tbdCustomers

The following table lists standard third-party vendor name prefix characters to be used with control prefixes: Vendor Abbreviation —————————————————————- MicroHelp (VBTools) m Pioneer Software Q+E Database p Crescent Software c Sheridan Software s Other (miscellaneous) o Objects Prefix Example ——————————————————————————————————- Alarm(Microhelp) almm almmAlarm Animate(Microhelp) anim animAnimate Callback(Microhelp) calm callback Combo Box(Pioneer) cbop cbopComboBox Combo Box(Sheridan) cbos cbosComboBox DB_Check(Pioneer) chkp chkpCheckBox chart(Microhelp) tm tmChart Clock(Microhelp) clkm clkmClock Command Button(Microhelp) cmdm cmdmCommandButton DB_Command(Pioneer) cmdp cmdpCommandButton Command Button(Group)(Microhelp) cmgm cmgmBtton Command Button (icon) (Microhelp) cmim cmimCommandButton CardDeck(Microhelp) crdm crdmCard Dice(Microhelp) dicm dicmDice SSDir(Sheridan) dirs dirsDirList SSDrive(Sheridan) drvs drvsDriveList File List(Microhelp) film filmFileList SSFile(Sheridan) fils filsFileList Flip(Microhelp) flpm flpmButton Form Scroll(Microhelp) fsrm fsrmFormScroll Gauge(Microhelp) gagm gagmGauge Graph(Other) gpho gphoGraph Q_Grid(Pioneer) grdp grdpGrid Horizontal Scroll Bar(Microhelp) hsbm hsbmScroll DB_Hscroll(Pioneer) hsbp hsbpScroll Histo(Microhelp) hstm hstmHistograph Invisible(Microhelp) invm invmInvisible Icon Tag(Microhelp) itgm itgmListBox Key State(Microhelp kstm kstmKeyState Label (3d) (Microhelp) lblm lblmLabel Line(Microhelp) linm linmLine DB_List(Pioneer) lstp lstpListBox SSList(Sheridan) lsts lstsListBox MDI Control(Microhelp) mdcm mdcmMDIChild SSMenu(Sheridan) mnus mnusMenu Marque(Microhelp) mrqm mrqmMarque OddPic(Microhelp) odpm odpmPicture Picture(Microhelp) picm picmPicture DB_Picture(Pioneer) picp picpPicture Property Vwr(Microhelp) pvrm vrmPropertyViewer DB_RadioGroup(Group)(Pioneer) radp radqRadioGroup Slider(Microhelp) sldm sldmSlider Spinner(Microhelp) spnm spnmSpinner Spreadsheet(Microhelp) sprm sprmSpreadsheet Stretcher(Microhelp) strm strmStretcher Screen Saver(Microhelp) svrm svrmSaver Switcher(Microhelp) swtm swtmSwitcher Tag(Microhelp) tagm tagmListBox Timer(Microhelp) tmrm tmrmTimer ToolBar(Microhelp) tolm tolmToolBar Tree(Microhelp) trem tremTree Input(Microhelp) (Text) txtm inpmText DB_Text(Microhelp) txtp txtpText Vertical Scroll Bar(Microhelp) vsbm vsbmScroll DB_VScroll(Pioneer) vsbp vsbpScroll From Win98 Developers Handbook ============================== Using Hungarian notation, variable names begin with one or more lowercase letters that denote the variable type, thus providing an inherent identification. For example, the prefix h is used to identify a handle, as in **hWnd** or **hDlg**, referring to window and dialog box handles, respectively. In like fashion, the prefix lpsz identifies a long pointer to a null-terminated (ASCIIZ) string. Table 2.1 summarizes the Hungarian notation conventions. **Table 2.1: Hungarian Notation Conventions** —————————————————————————————————- ——————————————————————————————————— **Prefix** **Data type** b Boolean by byte or unsigned char c Char cx /\ short used as cy size dw DWORD, double word or unsigned long fn Function h Handle i int (integer) l Long n short int p a pointer variable containing the address of a variable s string sz ASCIIZ null-terminated string w WORD unsigned int x, y short used as coordinates —————————————————————————————————- ——————————————————————————————————— More VB stuff ============= From Microsoft KB article Q110264 ### Object Naming Conventions for Standard Objects

The following tables define the MCS standard object name prefixes. These prefixes are consistent with those documented in the Visual Basic Programmers Guide. ~~~~ {.FIXEDTEXT} Prefix Object Type Example ———————————————————————————- ani Animation button aniMailBox bed Pen Bedit bedFirstName cbo Combo box and drop down list box cboEnglish chk Checkbox chkReadOnly clp Picture clip clpToolbar cmd (3d) Command button (3D) cmdOk (cmd3dOk) com Communications comFax ctr Control (when specific type unknown) ctrCurrent dat Data control datBiblio dir Directory list box dirSource dlg Common dialog control dlgFileOpen drv Drive list box drvTarget fil File list box filSource frm Form frmEntry fra (3d) Frame (3d) fraStyle (fra3dStyle) gau Gauge gauStatus gpb Group push button gpbChannel gra Graph graRevenue grd Grid grdPrices hed Pen Hedit hedSignature hsb Horizontal scroll bar hsbVolume img Image imgIcon ink Pen Ink inkMap key Keyboard key status keyCaps lbl Label lblHelpMessage lin Line linVertical lst List box lstPolicyCodes mdi MDI child form mdiNote mpm MAPI message mpmSentMessage mps MAPI session mpsSession mci MCI mciVideo mnu Menu mnuFileOpen opt (3d) Option Button (3d) optRed (opt3dRed) ole OLE control oleWorksheet out Outline control outOrgChart pic Picture picVGA pnl3d 3d Panel pnl3d rpt Report control rptQtr1Earnings shp Shape controls shpCircle spn Spin control spnPages txt Text Box txtLastName tmr Timer tmrAlarm vsb Vertical scroll bar vsbRate ~~~~ ### Object Naming Convention for Database Objects ~~~~ {.FIXEDTEXT} Prefix Object Type Example ————————————————————— db ODBC Database dbAccounts ds ODBC Dynaset object dsSalesByRegion fdc Field collection fdcCustomer fd Field object fdAddress ix Index object ixAge ixc Index collection ixcNewAge qd QueryDef object qdSalesByRegion qry (suffix) Query (see NOTE) SalesByRegionQry ss Snapshot object ssForecast tb Table object tbCustomer td TableDef object tdCustomers ~~~~ NOTE: Using a suffix for queries allows each query to be sorted with its associated table in Microsoft Access dialogs (Add Table, List Tables Snapshot). ### Menu Naming Conventions

Applications frequently use an abundance of menu controls. As a result, you need a different set of naming conventions for these controls. Menu control prefixes should be extended beyond the initial mnu label by adding an additional prefix for each level of nesting, with the final menu caption at the end of the name string. For example: ~~~~ {.FIXEDTEXT} Menu Caption Sequence Menu Handler Name Help.Contents mnuHelpContents File.Open mnuFileOpen Format.Character mnuFormatCharacter File.Send.Fax mnuFileSendFax File.Send.Email mnuFileSendEmail ~~~~ When this convention is used, all members of a particular menu group are listed next to each other in the object drop-down list boxes (in the code window and property window). In addition, the menu control names clearly document the menu items to which they are attached. ### Naming Conventions for Other Controls For new controls not listed above, try to come up with a unique three character prefix. However, it is more important to be clear than to stick to three characters. For derivative controls, such as an enhanced list box, extend the prefixes above so that there is no confusion over which control is really being used. A lower-case abbreviation for the manufacturer would also typically be added to the prefix. For example, a control instance created from the Visual Basic Professional 3D frame could uses a prefix of fra3d to avoid confusion over which control is really being used. A command button from MicroHelp could use cmdm to differentiate it from the standard command button (cmd). ### Third-party Controls

Each third-party control used in an application should be listed in the application’s overview comment section, providing the prefix used for the control, the full name of the control, and the name of the software vendor: ~~~~ {.FIXEDTEXT} Prefix Control Type Vendor cmdm Command Button MicroHelp ~~~~ ### Variable and Routine Naming

Variable and function names have the following structure: \\\\ ~~~~ {.FIXEDTEXT} Part Description Example -------------------------------------------------------------------------- Describes the use and scope of the variable. iGetRecordNext Describes the variable. iGetNameFirst Denotes a derivative of the variable. iGetNameLast The optional Visual Basic type character. iGetRecordNext% ~~~~ Prefixes: The following tables define variable and function name prefixes that are based on Hungarian C notation for Windows. These prefixes should be used with all variables and function names. Use of old Basic suffixes (such as %, &, \#, etc.) are discouraged.

Variable and Function Name Prefixes: ~~~~ {.FIXEDTEXT} Prefix Converged Variable Use Data Type Suffix -------------------------------------------------------------------------- b bln Boolean Integer % c cur Currency - 64 bits Currency @ d dbl Double - 64 bit Double # signed quantity dt dat Date and Time Variant e err Error f sng Float/Single - 32 Single ! bit signed floating point h Handle Integer % i Index Integer % l lng Long - 32 bit Long & signed quantity n int Number/Counter Integer % s str String String $ u Unsigned - 16 bit Long & unsigned quantity udt User-defined type vnt vnt Variant Variant a Array ~~~~ NOTE: the values in the Converged column represent efforts to pull together the naming standards for Visual Basic, Visual Basic for Applications, and Access Basic. It is likely that these prefixes will become Microsoft standards at some point in the near future.

Scope and Usage Prefixes: ~~~~ {.FIXEDTEXT} Prefix Description g Global m Local to module or form st Static variable (no prefix) Non-static variable, prefix local to procedure v Variable passed by value (local to a routine) r Variable passed by reference (local to a routine) ~~~~ Hungarian notation is as valuable in Visual Basic as it is in C. Although the Visual Basic type suffixes do indicate a variable's data type, they do not explain what a variable or function is used for, or how it can be accessed. Here are some examples: > iSend - Represents a count of the number of messages sent > bSend - > A Boolean flag defining the success of the last Send operation > hSend - A > Handle to the Comm interface Each of these variable names tell a programmer something very different. This information is lost when the variable name is reduced to Send%. Scope prefixes such as g and m also help reduce the problem of name contention especially in multi-developer projects. Hungarian notation is also widely used by Windows C programmers and constantly referenced in Microsoft product documentation and in industry programming books. Additionally, the bond between C programmers and programmers who use Visual Basic will become much stronger as the Visual C++ development system gains momentum. This transition will result in many Visual Basic programmers moving to C for the first time and many programmers moving frequently back and forth between both environments. ### The Body of Variable and Routine Names The body of a variable or routine name should use mixed case and should be as long as necessary to describe its purpose. In addition, function names should begin with a verb, such as InitNameArray or CloseDialog. For frequently used or long terms, standard abbreviations are recommended to help keep name lengths reasonable. In general, variable names greater than 32 characters can be difficult to read on VGA displays. When using abbreviations, make sure they are consistent throughout the entire application. Randomly switching between Cnt and Count within a project will lead to unnecessary confusion. ### Qualifiers on Variable and Routine Names

Related variables and routines are often used to manage and manipulate a common object. In these cases, use standard qualifiers to label the derivative variables and routines. Although putting the qualifier after the body of the name might seem a little awkward (as in sGetNameFirst, sGetNameLast instead of sGetFirstName, sGetLastName), this practice will help order these names together in the Visual Basic editor routine lists, making the logic and structure of the application easier to understand. The following table defines common qualifiers and their standard meaning: ~~~~ {.FIXEDTEXT} Qualifier Description (follows Body) -------------------------------------------------------------------------- First First element of a set. Last Last element of a set. Next Next element in a set. Prev Previous element in a set. Cur Current element in a set. Min Minimum value in a set. Max Maximum value in a set. Save Used to preserve another variable that must be reset later. Tmp A "scratch" variable whose scope is highly localized within the code. The value of a Tmp variable is usually only valid across a set of contiguous statements within a single procedure. Src Source. Frequently used in comparison and transfer routines. Dst Destination. Often used in conjunction with Source. ~~~~ ### User Defined Types

Declare user defined types in all caps with \_TYPE appended to the end of the symbol name. For example: ~~~~ {.CODESAMP} Type CUSTOMER_TYPE sName As String sState As String * 2 lID as Long End Type ~~~~

When declaring an instance variable of a user defined type, add a prefix to the variable name to reference the type. For example: ~~~~ {.CODESAMP} Dim custNew as CUSTOMER_TYPE ~~~~ ### Naming Constants

The body of constant names should be UPPER\_CASE with underscores (\_) between words. Although standard Visual Basic constants do not include Hungarian information, prefixes like i, s, g, and m can be very useful in understanding the value and scope of a constant. For constant names, follow the same rules as variables. For Example: ~~~~ {.CODESAMP} However, the variant data type can be extremely useful when working with databases, messages, DDE, or OLE. Many databases allow NULL as a valid value for a field. Your code needs to distinguish between NULL, 0 (zero), and "" (empty string). Many times, these types of operations can use a generic service routine that does not need to know the type of data it receives to process or pass on the data. For example: ~~~~ {.CODESAMP} Sub ConvertNulls(rvntOrg As Variant, rvntSub As Variant) ' If rvntOrg = Null, replace the Null with rvntSub If IsNull(rvntOrg) Then rvntOrg = rvntSub End Sub ~~~~

The are some drawbacks, however, to using variants. Code statements that use variants can sometimes be ambiguous to the programmer. For example: ~~~~ {.CODESAMP} vnt1 = "10.01" : vnt2 = 11 : vnt3 = "11" : vnt4 = "x4" vntResult = vnt1 + vnt2 ' Does vntResult = 21.01 or 10.0111? vntResult = vnt2 + vnt1 ' Does vntResult = 21.01 or 1110.01? vntResult = vnt1 + vnt3 ' Does vntResult = 21.01 or 10.0111? vntResult = vnt3 + vnt1 ' Does vntResult = 21.01 or 1110.01? vntResult = vnt2 + vnt4 ' Does vntResult = 11x4 or ERROR? vntResult = vnt3 + vnt4 ' Does vntResult = 11x4 or ERROR? ~~~~

The above examples would be much less ambiguous and easier to read, debug, and maintain if the Visual Basic type conversion routines were used instead. For Example: ~~~~ {.CODESAMP} iVar1 = 5 + val(sVar2) ' use this (explicit conversion) vntVar1 = 5 + vntVar2 ' not this (implicit conversion) ~~~~ ### Commenting Your Code All procedures and functions should begin with a brief comment describing the functional characteristics of the routine (what it does). This description should not describe the implementation details (how it does it) because these often change over time, resulting in unnecessary comment maintenance work, or worse yet, erroneous comments. The code itself and any necessary in-line or local comments will describe the implementation. Parameters passed to a routine should be described when their functions are not obvious and when the routine expects the parameters to be in a specific range. Function return values and global variables that are changed by the routine (especially through reference parameters) must also be described at the beginning of each routine.

Routine header comment blocks should look like this (see the next section "Formatting Your Code" for an example): ~~~~ {.FIXEDTEXT} Section Comment Description -------------------------------------------------------------------------- Purpose What the routine does (not how). Inputs Each non-obvious parameter on a separate line with in-line comments Assumes List of each non-obvious external variable, control, open file, and so on. Returns Explanation of value returned for functions. Effects List of each effected external variable, control, file, and so on and the affect it has (only if this is not obvious) ~~~~ Every non-trivial variable declaration should include an in-line comment describing the use of the variable being declared. Variables, controls, and routines should be named clearly enough that in- line commenting is only needed for complex or non-intuitive implementation details. An overview description of the application, enumerating primary data objects, routines, algorithms, dialogs, database and file system dependencies, and so on should be included at the start of the .BAS module that contains the project's Visual Basic generic constant declarations. NOTE: The Project window inherently describes the list of files in a project, so this overview section only needs to provide information on the most important files and modules, or the files the Project window doesn't list, such as initialization (.INI) or database files. ### Formatting Your Code Because many programmers still use VGA displays, screen real estate must be conserved as much as possible, while still allowing code formatting to reflect logic structure and nesting. Standard, tab-based, block nesting indentations should be two to four spaces. More than four spaces is unnecessary and can cause statements to be hidden or accidentally truncated. Less than two spaces does not sufficiently show logic nesting. In the Microsoft Knowledge Base, we use a three-space indent. Use the Environment Options dialog to set the default tab width.

The functional overview comment of a routine should be indented one space. The highest level statements that follow the overview comment should be indented one tab, with each nested block indented an additional tab. For example: ~~~~ {.CODESAMP} ************************************************************************** 'Purpose: Locate first occurrence of a specified user in UserList array. 'Inputs: rasUserList(): the list of users to be searched ' rsTargetUser: the name of the user to search for 'Returns: the index of the first occurrence of the rsTargetUser ' in the rasUserList array. If target user not found, return -1. '************************************************************************** 'VB3Line: Enter the following lines as one line Function iFindUser (rasUserList() As String, rsTargetUser as String) _ As Integer Dim i As Integer ' loop counter Dim bFound As Integer ' target found flag iFindUser = -1 i = 0 While i <= Ubound(rasUserList) and Not bFound If rasUserList(i) = rsTargetUser Then bFound = True iFindUser = i End If Wend End Function ~~~~ Variables and non-generic constants should be grouped by function rather than by being split off into isolated areas or special files. Visual Basic generic constants such as HOURGLASS should be grouped in a single module (VB\_STD.BAS) to keep them separate from application-specific declarations. ### Operators

Always use an ampersand (&) when concatenating strings, and use the plus sign (+) when working with numerical values. Using a plus sign (+) with non-numerical values, may cause problems when operating on two variants. For example: ~~~~ {.CODESAMP} vntVar1 = "10.01" vntVar2 = 11 vntResult = vntVar1 + vntVar2 ' vntResult = 21.01 vntResult = vntVar1 & vntVar2 ' vntResult = 10.0111 ~~~~ ### Scope

Variables should always be defined with the smallest scope possible. Global variables can create enormously complex state machines and make the logic of an application extremely difficult to understand. Global variables also make the reuse and maintenance of your code much more difficult. Variables in Visual Basic can have the following scope: ~~~~ {.FIXEDTEXT} Scope Variable Declared In: Visibility -------------------------------------------------------------------------- Procedure-level Event procedure, sub, or Visible in the function procedure in which it is declared Form-level, Declarations section of a form Visible in every Module-level or code module (.FRM, .BAS) procedure in the form or code module Global Declarations section of a code Always visible module (.BAS, using Global keyword) ~~~~ In a Visual Basic application, only use global variables when there is no other convenient way to share data between forms. You may want to consider storing information in a control's Tag property, which can be accessed globally using the form.object.property syntax. If you must use global variables, it is good practice to declare all of them in a single module and group them by function. Give the module a meaningful name that indicates its purpose, such as GLOBAL.BAS. With the exception of global variables (which should not be passed), procedures and functions should only operate on objects that are passed to them. Global variables that are used in routines should be identified in the general comment area at the beginning of the routine. In addition, pass arguments to subs and functions using ByVal, unless you explicitly want to change the value of the passed argument. Write modular code whenever possible. For example, if your application displays a dialog box, put all the controls and code required to perform the dialog's task in a single form. This helps to keep the application's code organized into useful components and minimizes its runtime overhead. ### Third-party Controls NOTE: The products discussed below are manufactured by vendors independent of Microsoft. Microsoft makes no warranty, implied or otherwise, regarding these products' performance or reliability.

The following table lists standard third-party vendor name prefix characters to be used with control prefixes: ~~~~ {.FIXEDTEXT} Vendor Abbv ------------------------- MicroHelp (VBTools) m Pioneer Software p Crescent Software c Sheridan Software s Other (Misc) o ~~~~

The following table lists standard third-party control prefixes: ~~~~ {.FIXEDTEXT} Control Control Abbr Vendor Example VBX File Type Name Name -------------------------------------------------------------------------- Alarm Alarm almm MicroHelp almmAlarm MHTI200.VBX Animate Animate anim MicroHelp animAnimate MHTI200.VBX Callback Callback calm MicroHelp calmCallback MHAD200.VBX Combo Box DB_Combo cbop Pioneer cbopComboBox QEVBDBF.VBX Combo Box SSCombo cbos Sheridan cbosComboBox SS3D2.VBX Check Box DB_Check chkp Pioneer chkpCheckBox QEVBDBF.VBX Chart Chart chtm MicroHelp chtmChart MHGR200.VBX Clock Clock clkm MicroHelp clkmClock MHTI200.VBX Button Command cmdm MicroHelp cmdmCommandButton MHEN200.VBX Button Button DB_Command cmdp Pioneer cmdpCommandButton QEVBDBF.VBX Button (Group) Command cmgm MicroHelp cmgmBtton MHGR200.VBX Button (multiple) Button Command cmim MicroHelp cmimCommandButton MHEN200.VBX Button (icon) CardDeck CardDeck crdm MicroHelp crdmCard MHGR200.VBX Dice Dice dicm MicroHelp dicmDice MHGR200.VBX List Box (Dir) SSDir dirs Sheridan dirsDirList SS3D2.VBX List Box (Drv) SSDrive drvs Sheridan drvsDriveList SS3D2.VBX List Box (File) File List film MicroHelp filmFileList MHEN200.VBX List Box (File) SSFile fils Sheridan filsFileList SS3D2.VBX Flip Flip flpm MicroHelp flpmButton MHEN200.VBX Scroll Bar Form Scroll fsrm MicroHelp fsrmFormScroll ??? Gauge Gauge gagm MicroHelp gagmGauge MHGR200.VBX Graph Graph gpho Other gphoGraph XYGRAPH.VBX Grid Q_Grid grdp Pioneer grdpGrid QEVBDBF.VBX Scroll Bar Horizontal hsbm MicroHelp hsbmScroll MHEN200.VBX Scroll Bar Scroll Bar DB_HScroll hsbp Pioneer hsbpScroll QEVBDBF.VBX Graph Histo hstm MicroHelp hstmHistograph MHGR200.VBX Invisible Invisible invm MicroHelp invmInvisible MHGR200.VBX List Box Icon Tag itgm MicroHelp itgmListBox MHAD200.VBX Key State Key State kstm MicroHelp kstmKeyState MHTI200.VBX Label Label (3d) lblm MicroHelp lblmLabel MHEN200.VBX Line Line linm MicroHelp linmLine MHGR200.VBX List Box DB_List lstp Pioneer lstpListBox QEVBDBF.VBX List Box SSList lsts Sheridan lstsListBox SS3D2.VBX MDI Child MDI Control mdcm MicroHelp mdcmMDIChild ??? Menu SSMenu mnus Sheridan mnusMenu SS3D3.VBX Marque Marque mrqm MicroHelp mrqmMarque MHTI200.VB Picture OddPic odpm MicroHelp odpmPicture MHGR200.VBX Picture Picture picm MicroHelp picmPicture MHGR200.VBX Picture DB_Picture picp Pioneer picpPicture QEVBDBF.VBX Property Vwr Property pvrm MicroHelp pvrmPropertyViewer MHPR200.VBX Viewer Option (Group) DB_RadioGroup radp Pioneer radqRadioGroup QEVBDBF.VBX Slider Slider sldm MicroHelp sldmSlider MHGR200.VBX Button (Spin) Spinner spnm MicroHelp spnmSpinner MHEN200.VBX Spreadsheet Spreadsheet sprm MicroHelp sprmSpreadsheet MHAD200.VBX Picture Stretcher strm MicroHelp strmStretcher MHAD200.VBX Screen Saver Screen Saver svrm MicroHelp svrmSaver MHTI200.VBX Switcher Switcher swtm MicroHelp swtmSwitcher ??? List Box Tag tagm MicroHelp tagmListBox MHEN200.VBX Timer Timer tmrm MicroHelp tmrmTimer MHTI200.VBX ToolBar ToolBar tolm MicroHelp tolmToolBar MHAD200.VBX List Box Tree trem MicroHelp tremTree MHEN200.VBX Input Box Input (Text) txtm MicroHelp inpmText MHEN200.VBX Input Box DB_Text txtp Pioneer txtpText QEVBDBF.VBX Scroll Bar Vertical vsbm MicroHelp vsbmScroll MHEN200.VBX Scroll Bar Scroll Bar DB_VScroll vsbp Pioneer vsbpScroll QEVBDBF.VBX ~~~~ From some unknown web page ==========================

**`a`** atom
**`b`** **`BOOL`** (int)

**`by`** **`BYTE`** (unsigned char)
**`c`** char (ANSI ASCII; 8-bit)
**`cb`** byte count
**`cxcy`**

int (*c* is for *count*; *x* or *y* is length)
**`dw`** **`DWORD`** (unsigned long)

**`f`** **`BOOL`**; boolean flag
**`fn`** function
**`h`** **`HANDLE`**
**`hbr`**

**`HANDLE`** to a brush
**`hDC`** **`HANDLE`** to a device context
**`i`** int
**`id`** integral id value

**`l`** **`LONG`** (long)
**`lp`** long (far) pointer
**`lpfn`** long pointer to function
**`lpsz`**

long pointer to nul-terminated string
**`n`** short
**`np`** near (short) pointer
**`p`** pointer
**`pfn`** pointer to function

**`pst`** pointer to a structure
**`psz`** pointer to a `nul`-terminated string
**`pv`** pointer to void
**`s`**

string
**`sz`** `nul` (**`'\0'`**) terminated string (string terminated by a zero byte)
**`u`** unsigned
**`v`** void

**`w`** **`WORD`** (unsigned 16-bit value; sometimes an unsigned short)
**`w`** wide char (UNICODE 16-bit)
**`x`** short or int (when used as an X coordinate)
**`y`**

short or int (when used as a Y coordinate)
* * * * * Hungarian Notation ==================

First, a little disclaimer: --------------------------- Please note that this guide is based on *MY* understanding of Hungarian notation, and may not be completely accurate. Yes, I used to work at Microsoft, but I don't have the guide we used there anymore. This document has been done almost entirely from memory and is based on how I've been writing code for the past few years, so it's probably actually a bastardized version of the form of Hungarian notation used by Microsoft. There's a very brief description of Hungarian notation in Charles Petzold's "Programming Windows", which I checked with while writing this guide. My intent is to go into much more detail than he does, though. If you DO know Hungarian, and notice anything wrong with this guide, please send me [mail][]. Thanks. What is Hungarian notation? --------------------------- Hungarian Notation is a naming convention that (in theory) allows the programmer to determine, the type and use of an identifier (variable, function, constant, etc.) It is frequently used in Windows programming, so a quick guide (such as this one) may be useful if you're working with Windows code but don't know the naming scheme. Note that there is really no such thing as "standard" Hungarian notation (at least as far as I've been able to determine). The basic ideas remain the same, however, and the key is to aim for CONSISTENCY. Variables --------- Variable names are probably the most common type of identifiers. A variable name in Hungarian notation consists of three parts: the *prefix* (or *constructor*), *base type* (or *tag*), and *qualifier*. Not all of these elements will be present in all variable names -- the only part that is really needed is the *base type*. ### Base Types (Tags) The *Tag* is NOT necessarily one of the types directly provided by the programming language; it may be application-defined (for example, a type `dbr` might represent a database record structure). *Tags* are short (usually two or three letters) descriptive reminders about the type of value the variable stores. This type will usually only be useful to someone who knows the application and knows what the basic types the application uses are; for example, a tag `co` could just as easily refer to a *co*ordinate, or a *co*lor. Within a given application, however, the `co` would always have a specific meaning -- all `co`'s would refer to the same type of object, and all references to that type of object would use the tag `co`. #### Common Tags These are many basic types that are used in any application. These tags are used for these types.
Tag Description
`f` Boolean flag. The *qualifier* should be used to describe the condition that causes the flag to be set (for example, `fError` might be used to indicate a variable that is set when an error condition exists, and clear when there is no error). The actual data representation may be a a byte, a word, or even a single bit in a bitfield.
`ch` A single-byte character.
`w` A machine word (16 bits on Win3.1 X86 machines). This is a somewhat ambiguous tag, and it is often better to use a more specific name. (For example, a word that represents a count of characters is better referred to as a `cch` than as a `w`. See the *prefixes* section for an explanation of the `cch` notation.)
`b` A byte (typically 8 bits). See the warnings for `w`.
`l` A long integer (typically 32 bits). See the warnings for `w`.
`u` An unsigned value. Usually more accurately used as a prefix with one of the integer types described above. For example, a `uw` is an unsigned word.
`r` A single-precision real number (float)
`d` A double-precision real number (double)
`bit` A single bit. Typically this is used to specify bits within other types; it is usually more appropriate to use `f`.
`v` A void. (Rather C-specific, meaning the type is not specified.) This type will probably never be used without the `p` *prefix*. This would usually be used for generic subroutines (such as `alloc` and `free`) that work with pointers but don't need to refer to the specific type of data referenced by those pointers.
`st` A Pascal-type string. That is, the first byte contains the length of the string, and the remainder contains the actual characters in the string.
`sz` A null-terminated (C-style) string.
`fn` A function. This will almost always have a `p` prefix, as about the only useful thing you can do with a function (from a variable's perspective) is take the address of it.
### Prefixes (Constructors) The base types are not usually sufficient to describe a variable, since variables frequently refer to more complex types. For example, you may have a pointer to a database record, or an array of coordinates, or a count of colors. In Hungarian notation, these extended types are described by the variable's prefix. The complete type of a variable is given by the combination of the prefix(es) and base type. Yes, it is possible to have more than one prefix -- for example, you may have a pointer to an array of database records. #### Common Constructors It is not usually necessary to create a new prefix, although it is certainly possible to do so. The list of standard prefixes should be sufficient for most uses, however.
Constructor Description
`p` A pointer.
`lp` A long (far) pointer. (Used on machines with a segmented architecture, such as X86's under DOS or Win3.1).
`hp` A huge pointer. (Similar to a far pointer, except that it handles crossing segment boundaries during pointer arithmetic correctly.)
`rg` An array. An `rgch` is an array of characters; a `pch` could point to a specific element in this array. (The notation comes from viewing an array as a mathematical function -- the input is the index, and the output is the value at that index. So the entire array is essentially the "range" of that function.)
`i` An index (into an array). For example, an `ich` could be used to index into an `rgch`. I've also seen this used for resource IDs under Windows (which makes sense if you think about it -- a resource ID is an index into a resource table).
`c` A count. `cch` could be the count of characters in the `rgch`. (As another example, note that the first byte of an `st` is the

`cch` of that string.)

`d` The difference between two instances of a type. For example, given a type `x` used to represent an X-coordinate on a graph, a `dx` could contain the difference on the X-axis of two such coordinates.
`h` A handle. Handles are commonly used in Windows programming; they represent resources allocated by the system and handed back to the application. On other systems, a "handle" might be a pointer to a pointer, in which case it might be clearer to use a `pp` (or `lplp` if appropriate).
`mp` A specific type of array, a mapping. This prefix is followed by two types, rather than one. The array represents a mapping function from the first type to the second. For example, `mpwErrisz` could be a mapping of error codes (`wErr`) to indexes of message strings (`isz`).
`v` A global variable (personally I prefer `g` for this)
### Examples Tags and constructors are both in lower case, with no seperating punctuation, so some ambiguity is possible if you are not careful in choosing your representations. For example, you probably shouldn't use `pfn` to represent a structure you've defined, as it could be taken as a pointer (`p`) to a function (`fn`). (Even if you *ARE* careful, some ambiguity is still possible. For example, if you have a handle to a pointer (unlikely, but who knows?), you'd want to represent this as `hp`, which also means huge pointer. Cases like these should be rare, however, and the true type should still be distinguishable from the context of the code.) Here are some further examples of constructors + tags:

Variable Description
`pch` A pointer to a character.
`ich` An index into an array of characters.
`rgsz` An array of null-terminated strings (most likely the values stored in the array are actually pointers to the strings, so you could arguably also use `rgpsz`).
`rgrgx` A two-dimensional array of `x`'s. (An array of arrays of

`x`'s.)

`pisz` A pointer to an index into an array of null-terminated strings. (Or possibly a pointer to a resource ID of a string -- the real meaning should be clear within the context of the code.)
`lpcw` Far pointer to a count of words.
### Qualifiers Although the combination of constructors and tags are enough to specify the type of a variable, it won't be sufficient to *distinguish* the variable from others of the same type. This is where the third (optional) part of a variable name, the *qualifier*, comes in. A qualifier is a short descriptive word or words (or reasonable facsimile) that describes *HOW* the variable is used. Some kind of punctuation should be used to distinguish the qualifier from the constructor + tag portion. Typically this is done by making the first letter of the qualifier (or of each qualifier if you choose to use more than one word) upper-case. The use of many variables will fall into the same basic categories, so there are several standard qualifiers:
Qualifier Description
`First` The first element in a set. This will often be an index or a pointer (for example, `pchFirst` or `iwFirst`).

`Last` The last element in a set. Both `First` and `Last` refer to valid values that *are* in a given set, and are often paired, such as in this sample C loop: for (iw = iwFirst; iw <= iwLast; iw++) { ... }
`Min` The first element in a set. Similar to `First`, but `Min` always refers to the first actual element in a set, while `First` may be used to indicate the first element actually dealt with (if you're working with a substring, for example).
`Max` The upper limit in a set. This is *NOT* a valid value; `xMax`

is usually equivalent to `xLast + 1`. The above example loop could also be written as for (iw = iwFirst; iw < iwMax; iw++) { ... }

I've also seen `Lim` used to indicate the limit in much the same manner.

`Mac` The *current* upper limit in a set. This is similar to `Max`, but is used where the upper limit can vary (for example, a variable length structure).

`Sav` A temporary saved value; usually used when temporarily modifying variables that you want to restore later.
`T` A temporary variable -- one which will be used quickly in a given context and then disposed of or reused.
`Src` A source. This is usually paired with `Dest` in copy/transfer operations.
`Dest` A destination. This is usually paired with `Src`.
### Structures and structure members Structures are usually by definition their own types, so a given structure usually defines its own tag (for example, the `dbr` I used earlier in this document). Structure members should simply be named the same way variables are. Since the context is usually only within the structure itself, name conflicts are less likely, so qualifiers are often not as necessary. If you have multiple instances of a variable type within the structure, you'll still need the qualifiers, of course (for example, if you're creating a structure containing name and address string records, you could name them `szName` and `szAddress`). If the language does not support seperate contexts for each structure (I think the Microsoft Macro Assembler (MASM) falls into this category, but I haven't worked with it in a few years), then the structure name is appended to the name of the member as a qualifier. (So the examples given above might be named `szNameDbr` and `szAddressDbr` if these fields appeared in the `dbr` structure.) Procedures ---------- The simple rules for naming variables don't always work quite as well for procedures. This is because specifying what the procedure actually *does* is important, and many procedures won't have a return value. Also, the context for procedures is usually the entire program, so you have more chance for naming conflicts. To handle these problems, a few modifications are made to the rules: 1. Procedure names are distinguished from variable names by using some punctuation -- for example, function names have the first letter capitalized while variable names begin with lowercase letters. 2. If the procedure *explicitly* returns a value (as opposed to implicitly returning one through a variable argument), then the procedure name will begin with the type of value that is returned.

3. If the procedure is a true function (that is, it operates on its parameters and returns a value with no side-effects), then it is typical to name it `XFromYZ...`, where `X` is the type returned and `Y`, `Z`, etc., are the types of the parameters. For example, `DxFromWnd(hwnd)` (or possibly `DxFromHwnd(hwnd)` if you really want to be specific) could be used for a function that returns the width of a window. 4. If the procedure has side-effects, then follow the type (if any) with a few words that describe what the procedure does. Each word should be capitalized. For example, `FTryMove()` could be used to indicate a procedure that checks the validity of a move (in a game, for instance), and returns a boolean value (true/false) to indicate if the move is valid.

5. If the procedure operates on an object, the type of the object should be appended to the name. For example, `InitFoo(pfoo)` could indicate a procedure that initializes a structure `foo` (or more accurately in this case, a structure `foo` that the procedure is given a pointer to). Macros and constants -------------------- Macros are usually handled the same way as procedures. Constants may be handled as variables (such as `fTrue` and `fFalse`), although you'll often see constants defined in all upper-case (`IWFIRST`, for example). Some people will use underscores to seperate parts of a constant name if they capitalize them (`I_W_FIRST`). If I remember correctly, this capitaliztion is *NOT* really a part of "proper" Hungarian, but I use it myself to distinguish between constants and variables. Labels ------ If you need a label for some reason, it can be considered to be a variation on a procedure -- labels are effectively identifiers specifying a piece of code. Since labels don't take parameters or return a value, no types are specified. `EndLoop` or `OutOfMem` are typical examples. * * * * *
![][] Hungarian Notation Reference =======================================================

Example of an Identifier in Hungarian Notation:

---------------------------------------- ------------------------------------ `CString* m_ps` `NameFirst` Prefix Qualifier ---------------------------------------- ------------------------------------

- [What is Hungarian Notation?][] - [Type Prefixes][] - [Standard Qualifiers][] - [Other Hungarian Naming Conventions][] - [More Information About Hungarian Notation][] - [Back to **Mark Riedl**][]
![][] What is Hungarian Notation? --------- [Top][] ---------
Hungarian is a naming convention for identifiers in code, especially, but not exclusively, the C++ and Java languages. Each identifier would have two parts to it, a *type* and a *qualifier*. - **type**: the first characters of the identifier specify what type the object is an instance of. This is achieved by adopting part of the name of the type as a prefix on the identifier. The prefix is always entirely lower-case. - **qualifier**: the remainder of the name of the identifier describes what the variable is used for. The qualifier portion can be one word or a run-on word. The qualifier begins with a capital to distinguish it from the type prefix. Example: : `String sNameFirst; //s is a prefix for String type` `char cLetter; //c is a prefix for the char type` `Button butPushMe; //but is a prefix for the Button type` [More explanation about Hungarian notation][More Information About Hungarian Notation].
![][] Type Prefixes --------- [Top][] ---------
### Common Type Prefixes

| [b][] | [by y][] | [c][] | [C][] | [d][] | [dw][] | [f][]

| [g\_][] | [h][] | [I][] | [l][] | [m\_][] | [n][] | [p][] | [s str][] | [sz psz][] | [u][] | [v][] | [w][] | [x][] | [X][] |

**Prefix** **Meaning** **Example** **Notes**
p Pointer `Finger* pRude;` In most cases, *p* is combined with another prefix; the prefix of the type of object being pointed to. For example: `String* psName` is a pointer to a string object containing a name.
s str String `String sName;String strName;` This convention is generally used for first-class string classes.
sz psz zero-terminated / null-terminated string `char szName[16];char* pszName;`
h Handle `HWND hWindow`
c Character (char) `char cLetter;` Sometimes *c* is used to denote a counter object.
by y Byte or Unsigned Char `byte byMouthFull;byte yMouthFull;`
n Integer (int) `int nSizeOfArray;`
f Float `float fRootBeer;`
d Double `double dDecker;`
b Boolean `boolean bIsTrue;BOOL bIsTrue;int bIsTrue;` An integer can store a boolean value as long as you remember not to assign it a value other than 0 or 1
u Unsigned...
w Word or Unsigned Integer `unsigned int wValue;`
l Long `long lIdentifier;` Sometimes *l* is appended to *p* to denote that the pointer is a long. For example: `lpszName` is a long pointer to a zero-terminated string.
dw Unsigned Long Integer
C or just a capital first letteri Class `Class CObject;Class Object;` *C* is used heavily in Microsoft's Foundation Classes but using just a capital first letter is emphasized by Microsoft's J++.
I Interface (ususally a struct or class with only pure virtual methods and no member variables) class IMotion { public: virtual void Fly() = 0; }; Used extensively in COM.
X Nested Class class CRocket { public: class XMotion:public IMotion { public: void Fly(); } m_xUnknown; } Used extensively in COM.
x Instantiation of a nested class. class CAirplane { public: class XMotion:public IMotion { public: void Fly(); } m_xUnknown; } Used extensively in COM.
m\_ Class Member Identifiers class CThing { private: int m_nSize; };
g\_ Global `String* g_psBuffer` Constant globals are usually in all caps. The *g\_* would denote that a particular global is not a constant.
v Void (no type) `void* pvObject` In most cases, *v* will be included with *p* because it is a common trick to typecast pointers to void pointers.

[Top of table][Type Prefixes]

### Type Prefixes for non-common Types In many cases, you will have identifiers of non-standard types. In this case, it will not do to borrow prefixes from the list of standard prefixes. Instead, the programmer needs to invent his own and, even more importantly, remain consistent with his own notation. To invent a prefix, abreviate the type name in a *short* and *meaningful* fashion. If it is not possible to abbreviate and the type name is not too long, you can just use the type name as a prefix. The Type Prefix will always be entirely lowercase and should reflect the name of the type by abbreviating it distinctively.
Example:

`Button buttonPushMe; //this is okay, but awkwardButton butPushMe; //a better abreviation for the type prefixButton bPushMe; //BAD: can be mistaken for a Boolean`
![][] Standard Qualifiers --------- [Top][] ---------
The Qualifier portion of the identifier can be anything but should accurately and concisely describe the purpose of the object. There is a set of standard qualifiers for variables used in commonly performed programming tasks. --------------- ------------------------------------------------------------------------------ **Qualifier** **Explanation** `Sav` A temporary from which the value will be restored `Prev` A value that follows one behind a current value in an iteration (eg. linked list node pointer) `Cur` Current value in some iteration `Next` Next value in some iteration `Nil` A special illegal value that is distinguished from all legal values. Typically denotes a certain absense of a legal value. `Min` Smallest legal index in an array or list. Typically zero. `Max` A strict upper limit for legal indexes in an array or list. --------------- ------------------------------------------------------------------------------
![][] Other Hungarian Naming Conventions --------- [Top][] ---------
### Identifiers Containing Multiple Words If the identifier contains multiple words, then the first letter of each word in the name is capitalized. Example: : `int nThisIsAReallyLongIdentifier` If the identifier contains adjectives that describe the purpose of the object, the adjective succeeds the word it describes. Example: : `CString sNameFirst; //first nameint nNumCowsBrown; //number of brown cows` ### Functions Functions should start out with a capital letter and no type prefix. It is not unheard of to start a function with a lowercase letter however. Microsoft urges the use of a capital first letter though the Java awt libraries use a lower-case first letter on member functions. Example: : `CString GetName (); //Microsoft C++ standardString getName (); //Sun Java standard` ### Macros and constants Macros and constants should be entirely in capitals. Example: : `#define MAXSIZE 100const int MAXSIZE = 100;`
![][] More Information About Hungarian Notation --------- [Top][] ---------
### The need for a standard Programmers typically do not name their identifiers randomly; Programmers commonly name their identifiers mnemonically. However, every programmer is unique and one mnemoic identifier name may mean a lot to one person and nothing to another. A *convention* is merely a codified style of choosing mnemonics. One important reason for a standard naming convention is to make your code more easily read by other people. Additional information about an object can be coded into its identifier so that someone reading code does not have to frequently refer back to the objects declaration to find out what *type* it is. Furthermore, if the identifier relates to what the object is used for in the code, then reading code is greatly simplified because the reader does not have to infer it from how it is used. ### Origins of Hungarian notation Charles Simonya, chief architect at Microsoft is the originator of the Hungarian Notation standard, which is used extensively in Microsoft Windows code. Simonya first used the notation in 1972. The notation was refered to as *Hungarian* originally as a criticism. At first glance, identifiers using Hungarian Notation appear to be gibberish until the pattern is deduced. Friends of Simonya compared Simonya's notation convention to some obscure foreign language and since Simonya is Hungarian, that was the obscure foreign language refered to. Since its inception in 1972, Hungarian Notation has been adopted by Xerox, Apple, 3Com, and of course Microsoft. * * * * * Recommended for Delphi ====================== From the Orange County Delphi Users Group Delphi/Pascal Coding Standards ***0.2******A Recommended Form of Hungarian Notation for Delphi*** ---------- ------ --------------- ----------- --------- Category Item Notation Type Nota-tion Example ---------- ------ --------------- ----------- --------- ----------------- --------------------------- ------------------- --- ----------------------------- Types & classes Exception classes Upper case prefix E ESyntax = class (Exception) All other types & classes " T TEmployee = class (TObject) ----------------- --------------------------- ------------------- --- ----------------------------- --------------------------------------------- ------------------------------------ ------------------- ------------- ---------------------------------------- Variables, except properties (see note \#1) Integer Lower case prefix i iCount: byte; Small Integer " n Long Integer " l Byte " by Word " w Real (floating point) " r rPrice: Real; Single " f Double " d Extended " e Comp " dl Char " c cLetter: Char; Pascal string or huge string (2.0) " s sTitle: String[80]; Null (zero)-terminated string " sz szDescription: array[0..1000] of char; Pointer " p pCount: \^iCount; pChar " psz or lpsz pszDescription: pChar; Boolean " b bSallaried: Boolean; Byte Boolean " byb Word Boolean " wb Long Boolean " lb Date/time " dt dtBirthday: TDateTime; --------------------------------------------- ------------------------------------ ------------------- ------------- ---------------------------------------- -------------- --------------------------------------------------------------- ------------------------ ----------------------- ---------------------------------- VCL controls Form Lower case prefix frm frmEmployee: TForm; Label (see note \#2) " lbl lblStatus: TDBLabel; (other standard controls) " (see chart below) sbtnGo: TSpeedButton; (subclassed standard controls) " (same as base) sbtnGo: TMySpeedButton; (all other controls, e.g. custom controls for the project at\ " (spell out) linkedimageUSAMap: TlinkedImage; hand) Persistent database field Delphi-assigned prefix (table or query name) tblEmployeesName: TStringField; -------------- --------------------------------------------------------------- ------------------------ ----------------------- ---------------------------------- ------------ --------------------------------------------------- --------------------- -- ----------------------------------------- Procedures Procedures, Functions, and Methods (see note \#3) No special notation procedure ToggleEmployeeState (Sender: TObject); ------------ --------------------------------------------------- --------------------- -- ----------------------------------------- ------------------- -------------------------------- --------------------------------------- ------------------------------------------------- ------------------------------------------------- Other identifiers constants (typed or untyped) Upper case name with underscores MAX\_HEIGHT: Integer = 24; Enumerated type values Programmer assigned lower case prefix (2-letter code for item type being enumer-ated) TVagueness = (vnBefore, vnAfter, vnOn, vnAbout) Compiler directive identifiers Upper case name with underscores {\$DEFINE QA\_MODE} ------------------- -------------------------------- --------------------------------------- ------------------------------------------------- ------------------------------------------------- ***0.1******Delphi Standard Controls*** ------------------- --------------------- ------------ **Palette Group** **Component** **Prefix** Standard TButton btn TCheckBox chk TComboBox cbo TEdit edt TGroupBox grp TLabel lbl TListBox lbo TMainMenu mmnu TMemo mem TMenuItem mnu TPanel pnl TPopupMenu pmnu TRadioButton rbtn TRadioGroup rgrp TScrollBar sbr Additional TBevel bvl TBitBtn bbtn TDrawGrid dgrd THeader hdr TImage img TMaskEdit medt TNotebook nbk TOutline oln TScrollBox sbo TShape shp TSpeedButton sbtn TStringGrid sgrd TTabbedNotebook tbnbk TTabSet tbs Data Access TBatchMove bmv TDatabase db TDataSource ds TQuery qry TReport rpt TStoredProc prc TTable tab Data Controls TDBCheckBox dbchk TDBComboBox dbcbo TDBEdit dbedt TDBGrid dbgrd TDBImage dbimg TDBListBox dblbo TDBLookupCombo dblcbo TDBLookupList dbllbo TDBMemo dbmem TDBNavigator dbnav TDBRadioGroup dbrgrp TDBText dbtxt Dialogs TColorDialog dlgcl TFindDialog dlgfn TFontDialog dlgft TOpenDialog dlgop TPrintDialog dlgpr TPrinterSetupDialog dlgps TReplaceDialog dlgrp TSaveDialog dlgsv System TDDEClientConv ddecc TDDEClientItem ddeci TDDEServerConv ddesc TDDEServerItem ddesi TDirectoryListBox dir TDriveComboBox drv TFileListBox fil TFilterComboBox filt TMediaPlayer mpl TOLEContainer olec TPaintBox pbx TTimer tmr ------------------- --------------------- ------------ * * * * * *** *** The Simonyi (Hungarian Notation) Naming Conventions Microsoft Corporation has substantially adopted a naming convention for its program modules and variables which is sometimes referred to as *Hungarian Notation*. Charles Simonyi, a Hungarian, developed this method of naming and presented it in his doctoral thesis. He worked for Microsoft and promulgated his theories in the *C*, *Visual Basic*, and *ACCESS* areas of the company. In this naming convention/style, object names are composed of four parts: 1) prefixes; 2) tag; 3) base name; and, 4) qualifier. Prefixes and tags are always lower-case so the reader’s eyes jump easily to the *base name* which begins with a uppercase letter. The *base name* succinctly describes the object, not its class. *Object tags* are short and mnemonic. *Object prefixes* provide further information or definition to the object tags and name. Two of the common prefixes are *a*rray and *i*ndex to an array. The index to an array would use the combined prefix of: *i* and *a* to denote that *iaintPartNum*is an index variable to an array of integer Part Numbers. *giaintPartNum* would be a global index variable to an array of integer Part Numbers. As you can see, a first character of "g" indicates a global variable. Procedures should be named in the form of *VerbNoun*. The name should be descriptive of what that procedure does. Remember, a procedure should do one thing only and do it correctly and completely. The following tags are suggested for the respective variable types: ------------------------------------------------------------------------------------ ------------------------------------------------------------------------------- **Variable Type** **Tag** Boolean bol Container con Control ctl Currency cur Date dte Database db Document doc Double dbl Flag (Y/N, T/F) f Field fld Form frm Group gru Index idx Integer int Long lng Object obj Parameter prm Property prp Report rpt Single sng (or sgl) String str (or sz) Variant var Yes/No ysn ------------------------------------------------------------------------------------ ------------------------------------------------------------------------------- Constants should have names (per the C custom) all in uppercase letters.   From Microsoft Access 95 Developer’s Handbook, by Paul Liwin and Ken Getz, Sybex, Inc., 1995 (ISBN: 0-7821-1765-1) come the following prefixes to be used for the various objects involved in a VBA environment. This list is augmented by prefixes found in an article by Randy Kahle, "Consistent Naming Clarifies Code", in the January, 1995 edition of Visual Basic Programmer’s Journal. ------------------------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------------------------------- **Tag** **Object Type** app Application chk Check Box cbo Combo Box cmd Command Button ctl Control ctls Controls dat Data Control dir Directory List Box drv Drive List Box ocx Custom Control dcm DoCmd fil File List Box frm Form frms Forms grd Grid grl Group Level hsb Horizontal Scroll Bar img Image lbl Label lin Line lst List Box bas Module ole Object Frame opt Option Button fra Option Group (frame) brk Page Break pal Palette Button pic Picture Box prps Properties shp Rectangle rpt Report rpts Reports scr Screen sec Section sfr Subform shp Shape srp SubReport txt TextBox tgl Toggle Button tmr Timer udt User Defined Type\*\*\*\*\*\*\*\*\* vsb Vertical Scroll Bar ------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------   * * * * * Proposal for Object Naming Standards Robert J. Gray When building object-oriented systems, you will be creating a lot of different components, all of which are objects. This is especially true when you get into GUI programming, even if the rest of your application is not built using OO. So that you can keep them all straight, I recommend that you develop some kind of naming standard. One that I have used is a sort of "Hungarian notation", where the first characters of the name refer to the type of object. The following quote from Charles Petzold's book Programming Windows 3.1 explains some of the history behind it. "Many Windows programmers use a variable-naming convention known as Hungarian notation, in honor of the legendary Microsoft programmer Charles Simonyi. Very simply, the variable name begins with a lowercase letter or letters that denote the data type of the variable. For example, the lpsz prefix in lpszCmdParam stands for "long pointer to a string terminated by zero". What I have tried to do here is take this idea and expand it to objects and GUIs. I've also tried to keep the length consistent (3 characters or 4 characters, depending) so that you could reliably extract substrings if necessary. This has proven to be beneficial when creating such things as automatic GUI builders. Note that, with the exception of the prefix, the first letter of each word is capitalized. The following is a table of recommended values: GUI Components (from the Interface Workbench) edt Edit Box txt Text Box (multiple line) lbl Label Box (single line) rbg Radio Button Group btn Push Button cbx Check Box slb Single List Box (only select a single item) mlb Multiple List Box (able to select multiple items) cbo Combo Box sld Slider spn Spin Box tbl Table Object wdo Window or PopupFrame pop Popup Frame dlg Dialog Box or Dialog Frame mnb Menu Bar mnf Menu Frame mni Menu Item mns Menu Separator After the 3 characters that identify the component type, use the next three characters to identify the window that the character is part of, such as W01-W99. For example, an Edit Box on window wdoW01 would be called edtW01________. The remainder of the object name would be something that would identify the object, such as edtW01LastName or rbgW07SelectType. Normally, this part of the name field for an Edit Box and its associated Label Box will have the same name as the slot (attribute) on the domain object that the Edit Box links to for data entry and display. The naming convention for menu components is slightly more complex. The Menu Bar takes the suffix "Top" or perhaps "Bar", such as mnbW01Top. Since a window can only have one menu bar, it is possible to drop the "Top/Bar" completely. Each Menu Frame on the bar will use the basic window identifier, plus the name of the frame, such as mnfW01File. If you have second level menu frames, then append the name of the second to the name of the first, such as mnfW01ObjectType. For more clarity in separating levels, use an underscore (mnfW01_Object_Type). The menu items on the frame will also append their title to the frame title, such as mniW01ObjectTypeClass. Menu Separators use the suffix "sep"; if you have more than one Menu Separator on a Menu Frame, use "sep1", "sep2", etc. For example, mnsW01File_sep1. To avoid overly long names, it may be necessary to abbreviate some of the name elements. Use underscores as necessary to maintain clarity. Variable Values You can use these prefixes when creating value slots in Kappa, or input and output variables in OMW. Note that the data types listed with an asterisk are not instantiable (as of Kappa 3.1). KAPPA typ *PrkType col *PRKCollection arr PrkArray lis PrkList slt PrkStackList str PrkString num *PrkNumber chr PrkChar fix PrkFixNum flt *PrkFloat sft PrkSingleFloat dft PrkDoubleFloat sym PrkSymbol err PrkError tem *PrkTemporal dte PrkDate tme PrkTime dtm PrkDateTime obj PrkObject app PrkApp mon PrkMonitor cls PrkClass ins PrkInstance rsd PrkRawSlotData rfd PrkRawFacetData srf PrkSlotReference sdd PrkSd met PrkMethod cvl PrkCValue htb PrkHashTable note: you might want to use the "met" prefix on the names of method slots, as an alternative to the "!" convention. OMW Naming Conventions Object Diagrams: prefix all names with "ODnn", where nn is a sequence number from 01 through 99. If you have more than 99 diagrams, you could use hex notation, I guess, but it might be better to rethink the size of your domain! The rest of the diagram name should be something descriptive of the function of the diagram. ssociation names: If possible, have all relationship names be more than one word, separated by underscores (e.g. has_department). If you must use only one word, precede the word with an underscore (e.g. _stores). Also, single word relationship names should avoid very generic words such as "is", "has", ect. One of the major purposes of these association name conven- tions is to avoid later confusion when using the Business Rule Editor. Event Diagrams: prefix all names with "EDnn". The top-level diagram name should be something like ED01Main or ED01Top. You may find it desirable to use the naming convention to show your Event Diagram hierarchy, as shown below: Business Rules: the standard for Business Rule names has three parts: ( prefix ( Event Diagram ( rule meaning Prefix all rules with "rle", followed by the Event Diagram identifier, followed by a meaning for the rule (e.g. rleED05Balance_GT_ 5000). In the case of rules on Event Partitions, the "meaning" part of the rule should be the same as the description of the associated Event in the partition. If desired, you can use the prefix to distinguish between different types of rules. For example: trl Trigger Rule on an Event Partition crl Trigger Rule on a Condition vrl Trigger Rule used to set an input variable drl Derivation Rule irl Integrity Rule

[]: ../corner.gif [What is Hungarian Notation?]: #what [Type Prefixes]: #prefixes [Standard Qualifiers]: #qualifiers [Other Hungarian Naming Conventions]: #conventions [More Information About Hungarian Notation]: #info [Back to Mark Riedl]: ../../index.html [Top]: #top [b]: #b [by y]: #by [c]: #c [C]: #C [d]: #d [dw]: #dw [f]: #f [g_]: #g [h]: #h [I]: #I [l]: #l [m_]: #m [n]: #n [p]: #p [s str]: #s [sz psz]: #sz [u]: #u [v]: #v [w]: #w [x]: #x [X]: #X