home *** CD-ROM | disk | FTP | other *** search
/ Media Share 13 / mediashare_13.zip / mediashare_13 / ZIPPED / PROGRAM / WTJ9403.ZIP / VBX / VBXDECL.C < prev    next >
C/C++ Source or Header  |  1993-11-14  |  31KB  |  1,085 lines

  1. /*
  2.  * VBXDECL.C -- Dump out C declarations for VBX controls
  3.  *
  4.  * This source code accompanies the article "Secrets of the Visual Basic API"
  5.  * in the February '94 issue of Windows Tech Journal
  6.  *
  7.  * Copyright (c) 1994 Brett Foster (CIS: 70444,135)
  8.  */
  9.  
  10. /* Ignore warnings about // comments, unreferenced parameters,
  11.  * and inline assembly preventing global optimizations
  12.  */
  13. #pragma warning ( disable : 4001 4100 4704 )
  14.  
  15. #include <windows.h>
  16. #include <commdlg.h>
  17. #include "winio.h"
  18. #include <vbapi.h>
  19. #include <string.h>
  20. #include <stdlib.h>
  21.  
  22. static char dummy[0x20 - 0x10] = "foo";    // Must initialize!!
  23.  
  24. void FAR PASCAL Dispatch(void);
  25. static FARPROC entry = Dispatch;    // Must immediately follow dummy!!
  26.  
  27. // VB "Internal Error" code
  28. #define ERR_INTERNAL    51
  29.  
  30. // Declarations require _export keyword
  31. #define VBAPIFUN VBAPI _export
  32.  
  33. typedef void NEAR * NPVOID;
  34. typedef struct tagStdItem {
  35.     LPVOID    lpInfo;
  36.     PSTR    pszName;
  37. } STDITEM;
  38. typedef STDITEM    STDPROP;
  39. typedef STDITEM    STDEVENT;
  40.  
  41. typedef struct tagItemFlag {
  42.     FLONG    fl;
  43.     PSTR    pszName;
  44. } ITEMFLAG;
  45. typedef ITEMFLAG *PITEMFLAG;
  46.  
  47.     // VALSTR - use stringizing operator to produce string
  48.     // from identifier name
  49. #define VALSTR(val) val, #val
  50.  
  51. static STDPROP StdProps[] = {
  52.     VALSTR(PPROPINFO_STD_NAME),
  53.     VALSTR(PPROPINFO_STD_INDEX),
  54.     VALSTR(PPROPINFO_STD_HWND),
  55.     VALSTR(PPROPINFO_STD_BACKCOLOR),
  56.     VALSTR(PPROPINFO_STD_FORECOLOR),
  57.     VALSTR(PPROPINFO_STD_LEFT),
  58.     VALSTR(PPROPINFO_STD_TOP),
  59.     VALSTR(PPROPINFO_STD_WIDTH),
  60.     VALSTR(PPROPINFO_STD_HEIGHT),
  61.     VALSTR(PPROPINFO_STD_ENABLED),
  62.     VALSTR(PPROPINFO_STD_VISIBLE),
  63.     VALSTR(PPROPINFO_STD_MOUSEPOINTER),
  64.     VALSTR(PPROPINFO_STD_CAPTION),
  65.     VALSTR(PPROPINFO_STD_FONTNAME),
  66.     VALSTR(PPROPINFO_STD_FONTBOLD),
  67.     VALSTR(PPROPINFO_STD_FONTITALIC),
  68.     VALSTR(PPROPINFO_STD_FONTSTRIKE),
  69.     VALSTR(PPROPINFO_STD_FONTUNDER),
  70.     VALSTR(PPROPINFO_STD_FONTSIZE),
  71.     VALSTR(PPROPINFO_STD_TABINDEX),
  72.     VALSTR(PPROPINFO_STD_PARENT),
  73.     VALSTR(PPROPINFO_STD_DRAGMODE),
  74.     VALSTR(PPROPINFO_STD_DRAGICON),
  75.     VALSTR(PPROPINFO_STD_BORDERSTYLEOFF),
  76.     VALSTR(PPROPINFO_STD_TABSTOP),
  77.     VALSTR(PPROPINFO_STD_TAG),
  78.     VALSTR(PPROPINFO_STD_TEXT),
  79.     VALSTR(PPROPINFO_STD_BORDERSTYLEON),
  80.     VALSTR(PPROPINFO_STD_CLIPCONTROLS),
  81.     VALSTR(PPROPINFO_STD_NONE),
  82.     VALSTR(PPROPINFO_STD_HELPCONTEXTID),
  83.     VALSTR(PPROPINFO_STD_LINKMODE),
  84.     VALSTR(PPROPINFO_STD_LINKITEM),
  85.     VALSTR(PPROPINFO_STD_LINKTOPIC),
  86.     VALSTR(PPROPINFO_STD_LINKTIMEOUT),
  87.     VALSTR(PPROPINFO_STD_LEFTNORUN),
  88.     VALSTR(PPROPINFO_STD_TOPNORUN),
  89.     VALSTR(PPROPINFO_STD_ALIGN),
  90.     VALSTR(PPROPINFO_STD_IMEMODE),
  91.     VALSTR(PPROPINFO_STD_DATASOURCE),
  92.     VALSTR(PPROPINFO_STD_DATAFIELD),
  93.     VALSTR(PPROPINFO_STD_DATACHANGED),
  94.     NULL
  95. };
  96.  
  97. static STDEVENT StdEvents[] = {
  98.     VALSTR(PEVENTINFO_STD_CLICK),
  99.     VALSTR(PEVENTINFO_STD_DBLCLICK),
  100.     VALSTR(PEVENTINFO_STD_DRAGDROP),
  101.     VALSTR(PEVENTINFO_STD_DRAGOVER),
  102.     VALSTR(PEVENTINFO_STD_GOTFOCUS),
  103.     VALSTR(PEVENTINFO_STD_KEYDOWN),
  104.     VALSTR(PEVENTINFO_STD_KEYPRESS),
  105.     VALSTR(PEVENTINFO_STD_KEYUP),
  106.     VALSTR(PEVENTINFO_STD_LOSTFOCUS),
  107.     VALSTR(PEVENTINFO_STD_MOUSEDOWN),
  108.     VALSTR(PEVENTINFO_STD_MOUSEMOVE),
  109.     VALSTR(PEVENTINFO_STD_MOUSEUP),
  110.     VALSTR(PEVENTINFO_STD_LINKERROR),
  111.     VALSTR(PEVENTINFO_STD_LINKOPEN),
  112.     VALSTR(PEVENTINFO_STD_LINKCLOSE),
  113.     VALSTR(PEVENTINFO_STD_LINKNOTIFY),
  114.     VALSTR(PEVENTINFO_STD_LINKCHANGE),
  115.     VALSTR(PEVENTINFO_STD_NONE),
  116.     NULL
  117. };
  118.  
  119. static ITEMFLAG ClassStyles[] = {
  120.     VALSTR(CS_VREDRAW),
  121.     VALSTR(CS_HREDRAW),
  122.     VALSTR(CS_OWNDC),
  123.     VALSTR(CS_CLASSDC),
  124.     VALSTR(CS_PARENTDC),
  125.     VALSTR(CS_SAVEBITS),
  126.     VALSTR(CS_DBLCLKS),
  127.     VALSTR(CS_BYTEALIGNCLIENT),
  128.     VALSTR(CS_BYTEALIGNWINDOW),
  129.     VALSTR(CS_NOCLOSE),
  130.     VALSTR(CS_KEYCVTWINDOW),
  131.     VALSTR(CS_NOKEYCVT),
  132.     VALSTR(CS_GLOBALCLASS),
  133.     0
  134. };
  135.  
  136. static ITEMFLAG WindowStyles[] = {
  137.     VALSTR(WS_POPUP),
  138.     VALSTR(WS_CHILD),
  139.     VALSTR(WS_CLIPSIBLINGS),
  140.     VALSTR(WS_CLIPCHILDREN),
  141.     VALSTR(WS_VISIBLE),
  142.     VALSTR(WS_DISABLED),
  143.     VALSTR(WS_MINIMIZE),
  144.     VALSTR(WS_MAXIMIZE),
  145.     VALSTR(WS_BORDER),
  146.     VALSTR(WS_DLGFRAME),
  147.     VALSTR(WS_VSCROLL),
  148.     VALSTR(WS_HSCROLL),
  149.     VALSTR(WS_SYSMENU),
  150.     VALSTR(WS_THICKFRAME),
  151.     VALSTR(WS_GROUP),
  152.     VALSTR(WS_TABSTOP),
  153.     0
  154. };
  155.  
  156. static ITEMFLAG PropTypes[] = {
  157.     VALSTR(DT_OBJECT),
  158.     VALSTR(DT_HLSTR),
  159.     VALSTR(DT_PICTURE),
  160.     VALSTR(DT_YSIZE),
  161.     VALSTR(DT_YPOS),
  162.     VALSTR(DT_XSIZE),
  163.     VALSTR(DT_XPOS),
  164.     VALSTR(DT_REAL),
  165.     VALSTR(DT_ENUM),
  166.     VALSTR(DT_COLOR),
  167.     VALSTR(DT_BOOL),
  168.     VALSTR(DT_LONG),
  169.     VALSTR(DT_SHORT),
  170.     VALSTR(DT_HSZ),
  171.     0
  172. };
  173.  
  174. static ITEMFLAG PropFlags[] = {
  175.     VALSTR(PF_fDefVal),
  176.     VALSTR(PF_fEditable),
  177.     VALSTR(PF_fGetData),
  178.     VALSTR(PF_fGetHszMsg),
  179.     VALSTR(PF_fGetMsg),
  180.     VALSTR(PF_fLoadDataOnly),
  181.     VALSTR(PF_fLoadMsgOnly),
  182.     VALSTR(PF_fNoInitDef),
  183.     VALSTR(PF_fNoMultiSelect),
  184.     VALSTR(PF_fNoRuntimeR),
  185.     VALSTR(PF_fNoRuntimeW),
  186.     VALSTR(PF_fNoShow),
  187.     VALSTR(PF_fPreHwnd),
  188.     VALSTR(PF_fPropArray),
  189.     VALSTR(PF_fSaveData),
  190.     VALSTR(PF_fSaveMsg),
  191.     VALSTR(PF_fSetCheck),
  192.     VALSTR(PF_fSetData),
  193.     VALSTR(PF_fSetMsg),
  194.     VALSTR(PF_fUpdateOnEdit),
  195.     0
  196. };
  197.  
  198. static ITEMFLAG EventFlags[] = {
  199.     VALSTR(EF_fNoUnload),
  200.     0
  201. };
  202.  
  203. static ITEMFLAG ModelFlags[] = {
  204.     VALSTR(MODEL_fArrows),
  205.     VALSTR(MODEL_fChildrenOk),
  206.     VALSTR(MODEL_fDesInteract),
  207.     VALSTR(MODEL_fFocusOk),
  208.     VALSTR(MODEL_fGraphical),
  209.     VALSTR(MODEL_fInitMsg),
  210.     VALSTR(MODEL_fInvisAtRun),
  211.     VALSTR(MODEL_fLoadMsg),
  212.     VALSTR(MODEL_fMnemonic),
  213.     0
  214. };
  215.  
  216. static ITEMFLAG EventTypes[] = {
  217.     VALSTR(ET_FS),
  218.     VALSTR(ET_SD),
  219.     VALSTR(ET_CY),
  220.     VALSTR(ET_R8),
  221.     VALSTR(ET_R4),
  222.     VALSTR(ET_I4),
  223.     VALSTR(ET_I2),
  224.     0
  225. };
  226.  
  227. // Version and mode of the emulation
  228. static USHORT nVersion = VB300_VERSION;
  229. static USHORT nMode = MODE_RUN;
  230.  
  231. // Pointer to VBINITCC function
  232. typedef BOOL (CALLBACK *VBINITCCPROC)(WORD, BOOL);
  233. static VBINITCCPROC    lpfnVBINITCC;
  234.  
  235. // Pointer to VBTERMCC function
  236. typedef BOOL (CALLBACK *VBTERMCCPROC)();
  237. static VBTERMCCPROC    lpfnVBTERMCC;
  238.  
  239. // Macro to manufacture far pointer from a near in lpModel
  240. #define MKPTR(offs) MAKELP((SELECTOROF(lpModel)),(offs))
  241.  
  242. // Temporary storage for output strings
  243. static char szBuffer[1000];
  244.  
  245.  
  246.     // PrintFlags -- Print a set of flags OR'd together
  247.     // Can also be used to print any unique value, but the values
  248.     // must be listed in order of decreasing magnitude so that
  249.     // they won't be misinterpreted
  250. static FLONG PrintFlags(FLONG fl, PITEMFLAG pItemFlag)
  251. {
  252.     PSTR    szPattern = "%s | ";
  253.  
  254.     if (fl) {
  255.         int    i;
  256.  
  257.         for (i = 0; pItemFlag[i].fl; i++) {
  258.             // Test for this flag
  259.             // NOTE: This test must be for equality
  260.             // because some flags use multiple bits
  261.             if ((fl & pItemFlag[i].fl) == pItemFlag[i].fl) {
  262.                 fl &= ~pItemFlag[i].fl;
  263.                 if (!fl) {
  264.                     // No more flags, drop or bar
  265.                     szPattern = "%s";
  266.                 }
  267.                 printf(szPattern,pItemFlag[i].pszName);
  268.             }
  269.         }
  270.     } else {
  271.         // No flags
  272.         printf("0");
  273.     }
  274.  
  275.     // Return modified flags in case some not accounted for
  276.     return(fl);
  277. }
  278.  
  279.  
  280.     // PrintDeclarations -- Walk through a MODEL structure and print it out
  281. static int NEAR PrintDeclarations(LPMODEL lpModel)
  282. {
  283.     LPSTR        lpszClassName;
  284.     LPPROPLIST    lpPropList;
  285.     LPEVENTLIST    lpEventList;
  286.     FLONG        fl;
  287.     int        fNone=FALSE;
  288.  
  289.     // Get class name
  290.     lpszClassName = MKPTR(lpModel->npszClassName);
  291.  
  292.     // Generate custom property declarations
  293.     lpPropList = MKPTR(lpModel->npproplist);
  294.     for (; *lpPropList; lpPropList++) {
  295.         LPPROPINFO    lpPropInfo;
  296.         LPSTR        lpszPropName;
  297.  
  298.         if (*lpPropList >= PPROPINFO_STD_LAST) {
  299.             // Ignore standard properties for now
  300.             continue;
  301.         }
  302.  
  303.         // Get pointers
  304.         lpPropInfo = MKPTR(*lpPropList);
  305.         lpszPropName = MKPTR(lpPropInfo->npszName);
  306.  
  307.         if (lpPropInfo->npszEnumList) {
  308.             LPSTR    lpszItem;
  309.  
  310.             // Property has an item list
  311.             // Generate list declaration
  312.             wsprintf(szBuffer,"static CHAR NEAR sz%s[] =\n",
  313.                 lpszPropName);
  314.             printf("%s",szBuffer);
  315.             lpszItem = MKPTR(lpPropInfo->npszEnumList);
  316.             while (*lpszItem) {
  317.                 wsprintf(szBuffer,
  318.                     "\t\"%s\\0\"\\\n",lpszItem);
  319.                 printf("%s",szBuffer);
  320.                 lpszItem += _fstrlen(lpszItem) + 1;
  321.             }
  322.             printf("\t\"\";\n\n");
  323.         }
  324.  
  325.         // Generate property declaration
  326.         // But make sure not to generate the "None" property
  327.         // more than once
  328.         if ((*lpszPropName == ' ') && fNone) {
  329.             continue;
  330.         } else {
  331.             LPSTR    lpszName;
  332.             
  333.             if (*lpszPropName == ' ') {
  334.                 fNone = TRUE;
  335.                 lpszName = "None";
  336.             } else {
  337.                 lpszName = lpszPropName;
  338.             }
  339.             wsprintf(szBuffer,
  340.                 "static PROPINFO NEAR %sProp_%s = {\n",
  341.                 lpszClassName,lpszName);
  342.             printf("%s",szBuffer);
  343.             wsprintf(szBuffer,"\t\"%s\",\n",lpszPropName);
  344.             printf("%s",szBuffer);
  345.         }
  346.  
  347.         // Print data type
  348.         printf("\t");
  349.         fl = PrintFlags(lpPropInfo->fl & PF_datatype,PropTypes);
  350.         if (fl) {
  351.             printf("0x%02x /* unknown datatype */",fl);
  352.         }
  353.         printf(" | \n\t");
  354.  
  355.         // Print flags
  356.         fl = PrintFlags(lpPropInfo->fl & ~PF_datatype,PropFlags);
  357.         if (fl) {
  358.             printf("0x%08lx /* unknown flags */",fl);
  359.         }
  360.         printf(",\n");
  361.  
  362.         // Offset into control structure
  363.         if (!lpPropInfo->offsetData || lpPropInfo->infoData) {
  364.             // Print offset as a number if it is zero
  365.             // or if bit-packing is used
  366.             printf("\t%d,\n",lpPropInfo->offsetData);
  367.         } else {
  368.             // Use OFFSETIN macro, but display numeric
  369.             // offset in comment just in case
  370.             wsprintf(szBuffer,"\tOFFSETIN(CTLSTRUCT,%s),",
  371.                 lpszPropName);
  372.             printf("%s",szBuffer);
  373.             printf(" /* %d */\n",lpPropInfo->offsetData);
  374.         }
  375.  
  376.         // Bit-packing stuff
  377.         printf("\t0x%02x,\n",lpPropInfo->infoData);
  378.  
  379.         // Default value
  380.         if ((lpPropInfo->fl & PF_datatype) == DT_COLOR) {
  381.             // Display default color values in hex
  382.             printf("\t0x%08lx,\n",lpPropInfo->dataDefault);
  383.         } else {
  384.             // Other default values displayed in decimal
  385.             printf("\t%ld,\n",lpPropInfo->dataDefault);
  386.         }
  387.  
  388.         // Enum list
  389.         if (lpPropInfo->npszEnumList) {
  390.             wsprintf(szBuffer,"\t(PSTR)sz%s,\n",lpszPropName);
  391.             printf("%s",szBuffer);
  392.         } else {
  393.             printf("\tNULL,\n");
  394.         }
  395.  
  396.         // Enum max value
  397.         printf("\t%d\n",lpPropInfo->enumMax);
  398.  
  399.         // End of declaration
  400.         printf("};\n\n");
  401.     }
  402.  
  403.     // KLUGE: Doctor standard property list
  404.     // The first element has a segment value of 0xffff instead of 0
  405.     StdProps[0].lpInfo = (LPVOID)(((FLONG)StdProps[0].lpInfo) & 0xffff);
  406.  
  407.     // Generate property list
  408.     wsprintf(szBuffer,"static PPROPINFO %sProps_VB%x[] = \n{\n",
  409.         lpszClassName,lpModel->usVersion);
  410.     printf("%s",szBuffer);
  411.     lpPropList = MKPTR(lpModel->npproplist);
  412.     for (; *lpPropList; lpPropList++) {
  413.         if (*lpPropList >= PPROPINFO_STD_LAST) {
  414.             // Standard property
  415.             printf("\t");
  416.             fl = ((FLONG)(LPVOID)*lpPropList) & 0xffff;
  417.             fl = PrintFlags(fl,(PITEMFLAG)StdProps);
  418.             if (fl) {
  419.                 fl = ~fl;
  420.                 printf("(PPROPINFO)~0x%03lx /* unknown standard property */",fl);
  421.             }
  422.             printf(",\n");
  423.         } else {
  424.             LPPROPINFO lpPropInfo = MKPTR(*lpPropList);
  425.             LPSTR lpszPropName = MKPTR(lpPropInfo->npszName);
  426.  
  427.             // Custom property
  428.             if (*lpszPropName == ' ') {
  429.                 // Convention for unused properties in VB 1.0
  430.                 lpszPropName = "None";
  431.             }
  432.             wsprintf(szBuffer,"\t&%sProp_%s,\n",
  433.                 lpszClassName,lpszPropName);
  434.             printf("%s",szBuffer);
  435.         }
  436.     }
  437.     printf("\tNULL\n};\n\n");
  438.  
  439.     // Generate custom event declarations
  440.     lpEventList = MKPTR(lpModel->npeventlist);
  441.     for (; *lpEventList; lpEventList++) {
  442.         LPEVENTINFO    lpEventInfo;
  443.         LPSTR        lpszEventName;
  444.         LPWORD        lpParmTypes;
  445.  
  446.         if (*lpEventList >= PEVENTINFO_STD_LAST) {
  447.             // Ignore standard events for now
  448.             continue;
  449.         }
  450.  
  451.         // Get pointers
  452.         lpEventInfo = MKPTR(*lpEventList);
  453.         lpszEventName = MKPTR(lpEventInfo->npszName);
  454.         lpParmTypes = MKPTR(lpEventInfo->npParmTypes);
  455.  
  456.         if (lpEventInfo->cParms) {
  457.             int    nParm;
  458.  
  459.             // Declare an array to store the parameter types
  460.             wsprintf(szBuffer,"static WORD NEAR ParamTypes_%s[] = { ",
  461.                 lpszEventName);
  462.             printf("%s",szBuffer);
  463.  
  464.             // Supply a declaration for each parameter
  465.             nParm = 0;
  466.             for (; nParm < (int)lpEventInfo->cParms; nParm++) {
  467.                 // Print data type
  468.                 if (nParm) {
  469.                     printf(", ");
  470.                 }
  471.                 fl = PrintFlags(lpParmTypes[nParm],EventTypes);
  472.                 if (fl) {
  473.                     printf("%d /* Unknown datatype */",fl);
  474.                 }
  475.             }
  476.             printf(" };\n\n");
  477.         }
  478.  
  479.         // Generate event declaration
  480.         wsprintf(szBuffer,"static EVENTINFO NEAR %sEvent_%s = {\n",
  481.             lpszClassName,lpszEventName);
  482.         printf("%s",szBuffer);
  483.         wsprintf(szBuffer,"\t\"%s\",\n",lpszEventName);
  484.         printf("%s",szBuffer);
  485.         printf("\t%d,\n\t%d,\n\t",lpEventInfo->cParms,
  486.             lpEventInfo->cwParms);
  487.  
  488.         // Parameter types
  489.         if (lpEventInfo->cParms) {
  490.             wsprintf(szBuffer,"ParamTypes_%s",lpszEventName);
  491.             printf("%s",szBuffer);
  492.         } else {
  493.             printf("NULL");
  494.         }
  495.  
  496.         // Parameter profile
  497.         lpszEventName = MKPTR(lpEventInfo->npszParmProf);
  498.         wsprintf(szBuffer,",\n\t\"%s\",\n\t",lpszEventName);
  499.         printf("%s",szBuffer);
  500.  
  501.         // Find flags
  502.         fl = PrintFlags(lpEventInfo->fl,EventFlags);
  503.         if (fl) {
  504.             printf("0x%08lx /* unknown flags */",fl);
  505.         }
  506.         printf("\n};\n\n");
  507.     }
  508.  
  509.     // KLUGE: Doctor standard event list
  510.     // The first element has a segment value of 0xffff instead of 0
  511.     StdEvents[0].lpInfo = (LPVOID)(((FLONG)StdEvents[0].lpInfo) & 0xffff);
  512.  
  513.     // Generate property list
  514.     wsprintf(szBuffer,"static PEVENTINFO %sEvents_VB%x[] = \n{\n",
  515.         lpszClassName,lpModel->usVersion);
  516.     printf("%s",szBuffer);
  517.     lpEventList = MKPTR(lpModel->npeventlist);
  518.     for (; *lpEventList; lpEventList++) {
  519.         if (*lpEventList >= PEVENTINFO_STD_LAST) {
  520.             printf("\t");
  521.             fl = ((FLONG)(LPVOID)*lpEventList) & 0xffff;
  522.             fl = PrintFlags(fl,(PITEMFLAG)StdEvents);
  523.             if (fl) {
  524.                 printf("(PEVENTINFO)~0x%03lx /* unknown standard event */",fl);
  525.             }
  526.             printf(",\n");
  527.         } else {
  528.             LPEVENTINFO lpEventInfo = MKPTR(*lpEventList);
  529.             LPSTR lpszEventName = MKPTR(lpEventInfo->npszName);
  530.  
  531.             // Custom event
  532.             wsprintf(szBuffer,"\t&%sEvent_%s,\n",
  533.                 lpszClassName,lpszEventName);
  534.             printf("%s",szBuffer);
  535.         }
  536.     }
  537.     printf("\tNULL\n};\n\n");
  538.  
  539.     // Define for bitmap resource id
  540.     wsprintf(szBuffer,"#define IDBMP_%s %d\n\n",lpszClassName,
  541.         lpModel->idBmpPalette);
  542.     printf("%s",szBuffer);
  543.  
  544.     // Generate model declaration
  545.     wsprintf(szBuffer,"static MODEL %sModel_VB%x[] = \n{\n",
  546.         lpszClassName,lpModel->usVersion);
  547.     printf("%s",szBuffer);
  548.     printf("\t0x%04x,\n\t",lpModel->usVersion);
  549.  
  550.     // Model flags
  551.     fl = PrintFlags(lpModel->fl,ModelFlags);
  552.     if (fl) {
  553.         printf("0x%08lx /* unknown flags */",fl);
  554.     }
  555.     printf(",\n");
  556.  
  557.     // Control procedure
  558.     wsprintf(szBuffer,"\t(PCTLPROC)%sCtlProc,\n\t",lpszClassName);
  559.     printf("%s",szBuffer);
  560.  
  561.     // Class style bits
  562.     fl = PrintFlags(lpModel->fsClassStyle,ClassStyles);
  563.     if (fl) {
  564.         printf("0x%04x",fl);
  565.     }
  566.     printf(",\n\t");
  567.  
  568.     // Window style bits
  569.     fl = PrintFlags(lpModel->flWndStyle,WindowStyles);
  570.     if (fl) {
  571.         printf("0x%08lx",fl);
  572.     }
  573.  
  574.     // Extra bytes for control structure
  575.     printf(",\n\tsizeof(CTLSTRUCT),\t/* %d */\n",lpModel->cbCtlExtra);
  576.  
  577.     // Bitmap resource id
  578.     wsprintf(szBuffer,"\tIDBMP_%s,\n",lpszClassName,
  579.         lpModel->idBmpPalette);
  580.     printf("%s",szBuffer);
  581.  
  582.     // Default control name
  583.     wsprintf(szBuffer,"\t\"%s\",\n",MKPTR(lpModel->npszDefCtlName));
  584.     printf("%s",szBuffer);
  585.  
  586.     // Class name
  587.     wsprintf(szBuffer,"\t\"%s\",\n",MKPTR(lpModel->npszClassName));
  588.     printf("%s",szBuffer);
  589.  
  590.     // Parent class name
  591.     if (lpModel->npszParentClassName) {
  592.         wsprintf(szBuffer,"\t\"%s\",\n",
  593.             MKPTR(lpModel->npszParentClassName));
  594.         printf("%s",szBuffer);
  595.     } else {
  596.         printf("\tNULL,\n");
  597.     }
  598.  
  599.     // Property list
  600.     wsprintf(szBuffer,"\t%sProps_VB%x,\n",
  601.         lpszClassName,lpModel->usVersion);
  602.     printf("%s",szBuffer);
  603.  
  604.     // Event list
  605.     wsprintf(szBuffer,"\t%sEvents_VB%x,\n",
  606.         lpszClassName,lpModel->usVersion);
  607.     printf("%s",szBuffer);
  608.  
  609.     // Default property & event
  610.     printf("\t%d,\n\t%d",lpModel->nDefProp,lpModel->nDefEvent);
  611.  
  612.     if (lpModel->usVersion >= VB200_VERSION) {
  613.         // Value property field new for VB 2.0
  614.         printf(",\n\t%d",lpModel->nValueProp);
  615.     }
  616.  
  617.     if (lpModel->usVersion >= VB300_VERSION) {
  618.         // Control version field new for VB 3.0
  619.         printf(",\n\t%d",lpModel->usCtlVersion);
  620.     }
  621.  
  622.     // That's it!
  623.     printf("\n};\n\n");
  624.     
  625.     return(0);
  626. }
  627.  
  628. HANDLE VBAPIFUN VBGetHInstance(void)
  629. {
  630.     return((HANDLE)__hInst);
  631. }
  632.  
  633.  
  634. USHORT VBAPIFUN VBGetVersion(void)
  635. {
  636.     return(nVersion);
  637. }
  638.  
  639.  
  640. USHORT VBAPIFUN VBGetMode(void)
  641. {
  642.     return(nMode);
  643. }
  644.  
  645.  
  646. BOOL VBAPIFUN VBRegisterModel(HINSTANCE hInstance, LPMODEL lpModel)
  647. {
  648.     // Avoid compiler warnings
  649.     hInstance = hInstance;
  650.  
  651.     PrintDeclarations(lpModel);
  652.     return(TRUE);
  653. }
  654.  
  655.  
  656.     // VBUnknownFunction -- called for any function index
  657.     // that we don't know about
  658.     // NOTE: stack checking is turned off to prevent BX from
  659.     // getting clobbered
  660. #pragma check_stack ( off )
  661. void VBAPIFUN VBUnknownFunction(void)
  662. {
  663.     int    bxreg;
  664.  
  665.     // Copy the BX register value into a variable
  666.     // so we can display the unknown function number
  667.     _asm    mov bxreg,bx
  668.  
  669.     // Let the user know what happened
  670.     wsprintf(szBuffer,"Unknown function %04x",bxreg);
  671.     MessageBox(__hMainWnd,szBuffer,__szModule,MB_ICONSTOP);
  672.  
  673.     // Bail out
  674.     winio_closeall();
  675.     exit(1);
  676. }
  677. #pragma check_stack ( on )
  678.  
  679. int LoadControl(LPSTR lpszControl)
  680. {
  681.     int    rc=0;
  682.     HMODULE hModule;
  683.  
  684.     // Display hourglass cursor
  685.     winio_setbusy();
  686.  
  687.     // Defer painting
  688.     winio_setpaint(__hMainWnd,FALSE);
  689.  
  690.     // Load the VBX
  691.     hModule = LoadLibrary(lpszControl);
  692.     if (hModule >= HINSTANCE_ERROR) {
  693.         lpfnVBINITCC = (VBINITCCPROC)GetProcAddress(hModule,"VBINITCC");
  694.         lpfnVBTERMCC = (VBTERMCCPROC)GetProcAddress(hModule,"VBTERMCC");
  695.         if (lpfnVBINITCC) {
  696.             if (lpfnVBINITCC(nVersion,nMode == MODE_RUN)) {
  697.                 // Only call VBTERMCC if VBINITCC succeeds
  698.                 if (lpfnVBTERMCC) {
  699.                     lpfnVBTERMCC();
  700.                 }
  701.             }
  702.         }
  703.         FreeLibrary(hModule);
  704.  
  705.         if (!lpfnVBINITCC) {
  706.             printf("VBX has no VBINITCC function!");
  707.             rc = -1;
  708.         }
  709.     } else {
  710.         printf("LoadLibrary failed");
  711.         rc = -1;
  712.     }
  713.  
  714.     // Enable painting
  715.     winio_setpaint(__hMainWnd,TRUE);
  716.  
  717.     // Restore cursor
  718.     winio_resetbusy();
  719.  
  720.     return(rc);
  721. }
  722.  
  723. enum MenuIds {
  724.     NOTUSED,    // Placeholder for value of 0
  725.     OPTION_VB1,
  726.     OPTION_VB2,
  727.     OPTION_VB3,
  728.     OPTION_RUN,
  729.     OPTION_DESIGN,
  730.     FILE_NEW,
  731.     FILE_OPEN
  732. };
  733.  
  734. static USHORT OptionValues[] = {
  735.     0,
  736.     VB100_VERSION,
  737.     VB200_VERSION,
  738.     VB300_VERSION,
  739.     MODE_RUN,
  740.     MODE_DESIGN,
  741.     0
  742. };
  743.  
  744. static HMENU    hmenuOptions;
  745.  
  746. // FindId -- Returns a menu id based on an option value
  747. static int FindId(USHORT iValue)
  748. {
  749.     int    i;
  750.  
  751.     for (i = 1; OptionValues[i]; i++) {
  752.         if (iValue == OptionValues[i]) {
  753.             break;
  754.         }
  755.     }
  756.  
  757.     return(i);
  758. }
  759.  
  760.  
  761. // FileNew -- Clears the buffer
  762. static void _cdecl FileNew(HWND hwnd, int idItem)
  763. {
  764.     winio_clear(__hMainWnd);
  765. }
  766.  
  767.  
  768. // FileOpen -- Open a new VBX
  769. static void _cdecl FileOpen(HWND hwnd, int idItem)
  770. {
  771.     OPENFILENAME    of;
  772.     char        szFile[128];
  773.  
  774.     memset(&of,0,sizeof(of));
  775.     of.lStructSize = sizeof(of);
  776.     of.hwndOwner = __hMainWnd;
  777.     of.lpstrFilter = "VBX Files (*.vbx)\0*.vbx\0All Files (*.*)\0*.*\0\0";
  778.     of.lpstrFile = szFile;
  779.     *szFile = '\0';
  780.     of.nMaxFile = sizeof(szFile);
  781.     of.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
  782.     of.lpstrDefExt = "vbx";
  783.     if (GetOpenFileName(&of)) {
  784.         LoadControl(szFile);
  785.     }
  786. }
  787.  
  788.  
  789. // SetVersion -- handle selection of the VB version from the Options menu
  790. static void _cdecl SetVersion(HWND hwnd, int idItem)
  791. {
  792.     // Uncheck the previous selection
  793.     CheckMenuItem(hmenuOptions,FindId(nVersion),MF_UNCHECKED);
  794.  
  795.     // Check the new one
  796.     CheckMenuItem(hmenuOptions,idItem,MF_CHECKED);
  797.  
  798.     // Set the new version
  799.     nVersion = OptionValues[idItem];
  800. }
  801.  
  802.  
  803. // SetMode -- handle selection of the VB mode from the Options menu
  804. static void _cdecl SetMode(HWND hwnd, int idItem)
  805. {
  806.     // Uncheck the previous selection
  807.     CheckMenuItem(hmenuOptions,FindId(nMode),MF_UNCHECKED);
  808.  
  809.     // Check the new one
  810.     CheckMenuItem(hmenuOptions,idItem,MF_CHECKED);
  811.  
  812.     // Set the new mode
  813.     nMode = OptionValues[idItem];
  814. }
  815.  
  816.  
  817. int _cdecl main(int argc, char *argv[])
  818. {
  819.     int    i;
  820.  
  821.     if (OFFSETOF((LPVOID)&entry) != 0x20) {
  822.         printf("Internal error: OFFSETOF(&entry) = 0x%02x (must be 0x20!)",
  823.             OFFSETOF((LPVOID)&entry));
  824.             return(1);
  825.     }
  826.  
  827.     // Add a "New" item to the File menu
  828.     InsertMenu(winio_hmenufile(__hMainWnd),0,MF_STRING|MF_BYPOSITION,
  829.         FILE_NEW,"&New (Clears buffer)");
  830.     winio_setmenufunc(__hMainWnd,FILE_NEW,FileNew);
  831.  
  832.     // Add an "Open" item to the File menu
  833.     InsertMenu(winio_hmenufile(__hMainWnd),1,MF_STRING|MF_BYPOSITION,
  834.         FILE_OPEN,"&Open...");
  835.     winio_setmenufunc(__hMainWnd,FILE_OPEN,FileOpen);
  836.  
  837.     // Add an "Options" menu
  838.     hmenuOptions = CreateMenu();
  839.     InsertMenu(winio_hmenumain(__hMainWnd),1,
  840.         MF_STRING|MF_POPUP|MF_BYPOSITION,
  841.         (UINT)hmenuOptions,"&Options");
  842.  
  843.     // Create menu items to select the VB version
  844.     AppendMenu(hmenuOptions,MF_STRING|MF_ENABLED,OPTION_VB1,"VB &1.0");
  845.     winio_setmenufunc(__hMainWnd,OPTION_VB1,SetVersion);
  846.     AppendMenu(hmenuOptions,MF_STRING|MF_ENABLED,OPTION_VB2,"VB &2.0");
  847.     winio_setmenufunc(__hMainWnd,OPTION_VB2,SetVersion);
  848.     AppendMenu(hmenuOptions,MF_STRING|MF_ENABLED,OPTION_VB3,"VB &3.0");
  849.     winio_setmenufunc(__hMainWnd,OPTION_VB3,SetVersion);
  850.  
  851.     // Separator
  852.     AppendMenu(hmenuOptions,MF_STRING|MF_ENABLED|MF_SEPARATOR,0,NULL);
  853.  
  854.     // Menu items to select the "mode"
  855.     AppendMenu(hmenuOptions,MF_STRING|MF_ENABLED,OPTION_DESIGN,"&Design Mode");
  856.     winio_setmenufunc(__hMainWnd,OPTION_DESIGN,SetMode);
  857.     AppendMenu(hmenuOptions,MF_STRING|MF_ENABLED,OPTION_RUN,"&Run Mode");
  858.     winio_setmenufunc(__hMainWnd,OPTION_RUN,SetMode);
  859.  
  860.     // Check the default options
  861.     CheckMenuItem(hmenuOptions,FindId(nVersion),MF_CHECKED);
  862.     CheckMenuItem(hmenuOptions,FindId(nMode),MF_CHECKED);
  863.  
  864.     // Refresh the menu onscreen
  865.     DrawMenuBar(__hMainWnd);
  866.  
  867.     // Open each VBX named on the command-line
  868.     // usage: VBXDECL [vbxfile] ...
  869.     for (i = 1; i < argc; i++) {
  870.         if (LoadControl(argv[i])) {
  871.             // Error, stop here
  872.             return(1);
  873.         }
  874.     }
  875.  
  876.     return(0);
  877. }
  878.  
  879. // Stubs for unsupported VB API functions
  880. LPVOID    VBAPIFUN VBDerefControl(HCTL hctl){return(NULL);}
  881. LONG    VBAPIFUN VBDefControlProc(HCTL hctl, HWND hwnd, USHORT msg, USHORT wp, LONG lp){return(0);}
  882. HWND    VBAPIFUN VBGetControlHwnd(HCTL hctl){return(NULL);}
  883. LPMODEL VBAPIFUN VBGetControlModel(HCTL hctl){return(NULL);}
  884. LPSTR    VBAPIFUN VBGetControlName(HCTL hctl, LPSTR lpszName){*lpszName = '\0'; return(NULL);}
  885. HCTL    VBAPIFUN VBGetHwndControl(HWND hwnd){return(NULL);}
  886. LONG    VBAPIFUN VBSendControlMsg(HCTL hctl, USHORT msg, USHORT wp, LONG lp){return(0);}
  887. LONG    VBAPIFUN VBSuperControlProc(HCTL hctl, USHORT msg, USHORT wp, LONG lp){return(0);}
  888. ERR    VBAPIFUN VBRecreateControlHwnd(HCTL hctl){return(ERR_INTERNAL);}
  889. VOID    VBAPIFUN VBDirtyForm(HCTL hctl){return;}
  890. ERR    VBAPIFUN VBSetErrorMessage(ERR err, LPSTR lpstr){return(ERR_INTERNAL);}
  891. VOID    VBAPIFUN VBGetAppTitle(LPSTR lpstr, USHORT cbMax){*lpstr = '\0'; return;}
  892. int    VBAPIFUN VBDialogBoxParam(HANDLE hinst, LPSTR pszTemplateName, FARPROC lpDialogFunc, LONG lp){return(-1);}
  893. ULONG    VBAPIFUN VBSetControlFlags(HCTL hctl, ULONG mask, ULONG value){return(0);}
  894. HCTL    VBAPIFUN VBGetCapture(VOID){return(NULL);}
  895. VOID    VBAPIFUN VBSetCapture(HCTL hctl){return;}
  896. VOID    VBAPIFUN VBReleaseCapture(VOID){return;}
  897. VOID    VBAPIFUN VBMoveControl(HCTL hctl, LPRECT lprect, BOOL fRepaint){return;}
  898. VOID    VBAPIFUN VBGetControlRect(HCTL hctl, LPRECT lprect){return;}
  899. VOID    VBAPIFUN VBGetRectInContainer(HCTL hctl, LPRECT lprect){return;}
  900. VOID    VBAPIFUN VBGetClientRect(HCTL hctl, LPRECT lprect){return;}
  901. VOID    VBAPIFUN VBClientToScreen(HCTL hctl, LPPOINT lppt){return;}
  902. VOID    VBAPIFUN VBScreenToClient(HCTL hctl, LPPOINT lppt){return;}
  903. BOOL    VBAPIFUN VBIsControlVisible(HCTL hctl){return(FALSE);}
  904. BOOL    VBAPIFUN VBIsControlEnabled(HCTL hctl){return(FALSE);}
  905. VOID    VBAPIFUN VBInvalidateRect(HCTL hctl, LPRECT lprect, BOOL fEraseBkGnd){return;}
  906. VOID    VBAPIFUN VBUpdateControl(HCTL hctl){return;}
  907. HCTL    VBAPIFUN VBGetControl(HCTL hctl, WORD gc){return(NULL);}
  908. VOID    VBAPIFUN VBZOrder(HCTL hctl, WORD zorder){return;}
  909. HSZ    VBAPIFUN VBCreateHsz(HANDLE seg, LPSTR lpszString){return(NULL);}
  910. HSZ    VBAPIFUN VBDestroyHsz(HSZ hsz){return(NULL);}
  911. LPSTR    VBAPIFUN VBDerefHsz(HSZ hsz){return(NULL);}
  912. LPSTR    VBAPIFUN VBLockHsz(HSZ hsz){return(NULL);}
  913. VOID    VBAPIFUN VBUnlockHsz(HSZ hsz){return;}
  914. HLSTR    VBAPIFUN VBCreateHlstr(LPVOID pb, USHORT cbLen){return(NULL);}
  915. HLSTR    VBAPIFUN VBCreateTempHlstr(LPVOID pb, USHORT cbLen){return(NULL);}
  916. VOID    VBAPIFUN VBDestroyHlstr(HLSTR hlstr){return;}
  917. LPSTR    VBAPIFUN VBDerefHlstr(HLSTR hlstr){return(NULL);}
  918. LPSTR    VBAPIFUN VBDerefHlstrLen(HLSTR hlstr, LPUSHORT lpcbLen){return(NULL);}
  919. LPSTR    VBAPIFUN VBDerefZeroTermHlstr(HLSTR hlstr){return(NULL);}
  920. USHORT    VBAPIFUN VBGetHlstr(HLSTR hlstr, LPVOID pb, USHORT cbLen){*(LPSTR)pb = '\0'; return(NULL);}
  921. USHORT    VBAPIFUN VBGetHlstrLen(HLSTR hlstr){return(0);}
  922. ERR    VBAPIFUN VBSetHlstr(LPHLSTR lphlstr, LPVOID pb, USHORT cbLen){return(ERR_INTERNAL);}
  923. ERR    VBAPIFUN VBResizeHlstr(HLSTR hlstr, USHORT newCbLen){return(ERR_INTERNAL);}
  924. ERR    VBAPIFUN VBCoerceVariant(LPVAR lpVar, SHORT vtype, LPVOID lpData){return(ERR_INTERNAL);}
  925. SHORT    VBAPIFUN VBGetVariantType(LPVAR lpVar){return(ERR_INTERNAL);}
  926. SHORT    VBAPIFUN VBGetVariantValue(LPVAR lpVar, LPVAL lpVal){return(ERR_INTERNAL);}
  927. ERR    VBAPIFUN VBSetVariantValue(LPVAR lpVar, SHORT vtype, LPVOID lpData){return(ERR_INTERNAL);}
  928. LPVOID    VBAPIFUN VBArrayElement(HAD hAD, SHORT cIndex, LPSHORT lpi){return(NULL);}
  929. LONG    VBAPIFUN VBArrayBounds(HAD hAD, SHORT index){return(AB_INVALIDINDEX);}
  930. USHORT    VBAPIFUN VBArrayElemSize(HAD hAD){return(0);}
  931. LPVOID    VBAPIFUN VBArrayFirstElem(HAD hAD){return(NULL);}
  932. SHORT    VBAPIFUN VBArrayIndexCount(HAD hAD){return(0);}
  933. VOID    VBAPIFUN VBRuntimeError(ERR err){return;}
  934. USHORT    VBAPIFUN VBCbSaveFPState(LPVOID pb, USHORT cb){return(0);}
  935. VOID    VBAPIFUN VBRestoreFPState(LPVOID pb){return;}
  936. ERR    VBAPIFUN VBFireEvent(HCTL hctl, USHORT idEvent, LPVOID lpparams){return(ERR_INTERNAL);}
  937. ERR    VBAPIFUN VBGetControlProperty(HCTL hctl, USHORT idProp, LPVOID pdata){return(ERR_INTERNAL);}
  938. ERR    VBAPIFUN VBSetControlProperty(HCTL hctl, USHORT idProp, LONG data){return(ERR_INTERNAL);}
  939. HPIC    VBAPIFUN VBAllocPic(LPPIC lppic){return(NULL);}
  940. HPIC    VBAPIFUN VBAllocPicEx(LPPIC lppic, USHORT usVersion){return(NULL);}
  941. VOID    VBAPIFUN VBFreePic(HPIC hpic){return;}
  942. HPIC    VBAPIFUN VBGetPic(HPIC hpic, LPPIC lppic){return(NULL);}
  943. HPIC    VBAPIFUN VBGetPicEx(HPIC hpic, LPPIC lppic, USHORT usVersion){return(NULL);}
  944. ERR    VBAPIFUN VBPicFromCF(LPHPIC lphpic, HANDLE hData, WORD wFormat){return(ERR_INTERNAL);}
  945. HPIC    VBAPIFUN VBRefPic(HPIC hpic){return(NULL);}
  946. VOID    VBAPIFUN VBPaletteChanged(HCTL hctl){return;}
  947. COLOR    VBAPIFUN VBTranslateColor(HCTL hctl, COLOR clr){return(0);}
  948. ERR    VBAPIFUN VBReadFormFile(HFORMFILE hformfile, LPVOID pb, WORD cb){return(ERR_INTERNAL);}
  949. ERR    VBAPIFUN VBWriteFormFile(HFORMFILE hformfile, LPVOID pb, WORD cb){return(ERR_INTERNAL);}
  950. LONG    VBAPIFUN VBSeekFormFile(HFORMFILE hformfile, LONG offset){return(-1);}
  951. LONG    VBAPIFUN VBRelSeekFormFile(HFORMFILE hformfile, LONG offset){return(-1);}
  952. ERR    VBAPIFUN VBReadBasicFile(USHORT usFileNo, LPVOID pb, WORD cb){return(ERR_INTERNAL);}
  953. ERR    VBAPIFUN VBWriteBasicFile(USHORT usFileNo, LPVOID pb, WORD cb){return(ERR_INTERNAL);}
  954. LONG    VBAPIFUN VBSeekBasicFile(USHORT usFileNo, LONG offset){return(-1);}
  955. LONG    VBAPIFUN VBRelSeekBasicFile(USHORT usFileNo, LONG offset){return(-1);}
  956. LONG    VBAPIFUN VBYPixelsToTwips(SHORT Pixels){return(0);}
  957. LONG    VBAPIFUN VBXPixelsToTwips(SHORT Pixels){return(0);}
  958. SHORT    VBAPIFUN VBYTwipsToPixels(LONG Twips){return(0);}
  959. SHORT    VBAPIFUN VBXTwipsToPixels(LONG Twips){return(0);}
  960. ERR    VBAPIFUN VBLinkPostAdvise(HCTL hctl){return(ERR_INTERNAL);}
  961. BOOL    VBAPIFUN VBPasteLinkOk(HANDLE FAR *phTriplet, HCTL hctl){return(FALSE);}
  962. VOID    VBAPIFUN VBLinkMakeItemName(HCTL hctl, LPSTR lpszBuf){return;}
  963. HCTL    VBAPIFUN VBGetDataSourceControl(HCTL hctl,BOOL FAR *bIsRegistered){return(NULL);}
  964. SHORT    VBAPIFUN VBFormat(SHORT vtype, LPVOID lpData, LPSTR lpszFmt, LPVOID pb, USHORT cb){return(-1);}
  965.  
  966. FARPROC VBFunctions[] = {
  967.     (FARPROC)VBRegisterModel,
  968.     (FARPROC)VBDerefControl,
  969.     (FARPROC)VBDefControlProc,
  970.     (FARPROC)VBFireEvent,
  971.     (FARPROC)VBSetControlProperty,
  972.     (FARPROC)VBGetControlProperty,
  973.     (FARPROC)VBCreateHsz,
  974.     (FARPROC)VBDestroyHsz,
  975.     (FARPROC)VBDerefHsz,
  976.     (FARPROC)VBLockHsz,
  977.     (FARPROC)VBUnlockHsz,
  978.     (FARPROC)VBGetControlHwnd,
  979.     (FARPROC)VBRecreateControlHwnd,
  980.     (FARPROC)VBGetControlModel,
  981.     (FARPROC)VBSendControlMsg,
  982.     (FARPROC)VBReadFormFile,
  983.     (FARPROC)VBWriteFormFile,
  984.     (FARPROC)VBSuperControlProc,
  985.     (FARPROC)VBGetMode,
  986.     (FARPROC)VBGetHInstance,
  987.     (FARPROC)VBCreateHlstr,
  988.     (FARPROC)VBSetHlstr,
  989.     (FARPROC)VBDestroyHlstr,
  990.     (FARPROC)VBDerefHlstr,
  991.     (FARPROC)VBGetHlstrLen,
  992.     (FARPROC)VBGetHwndControl,
  993.     (FARPROC)VBXPixelsToTwips,
  994.     (FARPROC)VBYPixelsToTwips,
  995.     (FARPROC)VBXTwipsToPixels,
  996.     (FARPROC)VBYTwipsToPixels,
  997.     (FARPROC)VBReadBasicFile,
  998.     (FARPROC)VBWriteBasicFile,
  999.     (FARPROC)VBAllocPic,
  1000.     (FARPROC)VBFreePic,
  1001.     (FARPROC)VBGetPic,
  1002.     (FARPROC)VBRefPic,
  1003.     (FARPROC)VBPicFromCF,
  1004.     (FARPROC)VBSetErrorMessage,
  1005.     (FARPROC)VBGetAppTitle,
  1006.     (FARPROC)VBDialogBoxParam,
  1007.     (FARPROC)VBSeekFormFile,
  1008.     (FARPROC)VBRelSeekFormFile,
  1009.     (FARPROC)VBGetControlName,
  1010.     (FARPROC)VBUnknownFunction,
  1011.     (FARPROC)VBUnknownFunction,
  1012.     (FARPROC)VBUnknownFunction,
  1013.     (FARPROC)VBUnknownFunction,
  1014.     (FARPROC)VBGetVersion,
  1015.     (FARPROC)VBLinkPostAdvise,
  1016.     (FARPROC)VBPasteLinkOk,
  1017.     (FARPROC)VBDirtyForm,
  1018.     (FARPROC)VBSetControlFlags,
  1019.     (FARPROC)VBPaletteChanged,
  1020.     (FARPROC)VBAllocPicEx,
  1021.     (FARPROC)VBGetPicEx,
  1022.     (FARPROC)VBTranslateColor,
  1023.     (FARPROC)VBGetCapture,
  1024.     (FARPROC)VBSetCapture,
  1025.     (FARPROC)VBReleaseCapture,
  1026.     (FARPROC)VBGetControl,
  1027.     (FARPROC)VBZOrder,
  1028.     (FARPROC)VBMoveControl,
  1029.     (FARPROC)VBGetControlRect,
  1030.     (FARPROC)VBGetRectInContainer,
  1031.     (FARPROC)VBGetClientRect,
  1032.     (FARPROC)VBClientToScreen,
  1033.     (FARPROC)VBScreenToClient,
  1034.     (FARPROC)VBIsControlVisible,
  1035.     (FARPROC)VBIsControlEnabled,
  1036.     (FARPROC)VBInvalidateRect,
  1037.     (FARPROC)VBUpdateControl,
  1038.     (FARPROC)VBCoerceVariant,
  1039.     (FARPROC)VBGetVariantType,
  1040.     (FARPROC)VBGetVariantValue,
  1041.     (FARPROC)VBSetVariantValue,
  1042.     (FARPROC)VBGetHlstr,
  1043.     (FARPROC)VBResizeHlstr,
  1044.     (FARPROC)VBDerefHlstrLen,
  1045.     (FARPROC)VBDerefZeroTermHlstr,
  1046.     (FARPROC)VBCreateTempHlstr,
  1047.     (FARPROC)VBArrayElement,
  1048.     (FARPROC)VBArrayBounds,
  1049.     (FARPROC)VBArrayElemSize,
  1050.     (FARPROC)VBArrayFirstElem,
  1051.     (FARPROC)VBArrayIndexCount,
  1052.     (FARPROC)VBRuntimeError,
  1053.     (FARPROC)VBFormat,
  1054.     (FARPROC)VBCbSaveFPState,
  1055.     (FARPROC)VBRestoreFPState,
  1056.     (FARPROC)VBLinkMakeItemName,
  1057. };
  1058. static int nFunctions = sizeof(VBFunctions) / sizeof(VBFunctions[0]);
  1059.  
  1060.  
  1061. #pragma check_stack ( off )
  1062. void FAR PASCAL Dispatch(void)
  1063. {
  1064.     __asm {
  1065.         // Duplicate function epilog
  1066.         // This is to undo the function prolog
  1067.         pop    di
  1068.         pop    si
  1069.         leave
  1070.  
  1071.         // Make sure we have a function for
  1072.         // this value
  1073.         cmp    bx, ss:nFunctions
  1074.         ja    unknown
  1075.  
  1076.         // Jump to the appropriate function
  1077.         jmp    dword ptr ss:VBFunctions[bx]
  1078.  
  1079.     unknown:
  1080.         // Unknown function
  1081.         jmp    VBUnknownFunction
  1082.     }
  1083. }
  1084. #pragma check_stack ( on )
  1085.