home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / com / oleaut / tibrowse / tibrowse.cpp < prev    next >
C/C++ Source or Header  |  1997-08-01  |  27KB  |  1,162 lines

  1. /*** 
  2. *tibrowse.cpp
  3. *
  4. *  This is a part of the Microsoft Source Code Samples.
  5. *
  6. *  Copyright (C) 1992-1997 Microsoft Corporation. All rights reserved.
  7. *
  8. *  This source code is only intended as a supplement to Microsoft Development
  9. *  Tools and/or WinHelp documentation.  See these sources for detailed
  10. *  information regarding the Microsoft samples programs.
  11. *
  12. *Purpose:
  13. *  Type Information Browser
  14. *
  15. *
  16. *Implementation Notes:
  17. *
  18. *****************************************************************************/
  19.  
  20. #if defined(_MAC)
  21.  
  22. #if defined(_PPCMAC)
  23. #pragma data_seg("_FAR_DATA")
  24. #pragma data_seg( )
  25. #define MAXLONG 0x7fffffff
  26. #define EventHandlerProcPtr AEEventHandlerUPP
  27. #else //_PPCMAC
  28. #define  GetMenuItemText(mApple,menuItem,daName)  GetItem(mApple,menuItem,daName)
  29. #endif //_PPCMAC
  30.  
  31. #endif //_MAC
  32.  
  33. #include <stdio.h>
  34. #include <stdlib.h>
  35. #include <string.h>
  36.  
  37. #include "tibrowse.h"
  38.  
  39. #ifdef WIN32 
  40.   #define SPRINTF    swprintf
  41. #else
  42.   #define SPRINTF    sprintf
  43. #endif
  44.  
  45. #if defined(UNICODE)
  46.   #define TCHAR        WCHAR
  47.   #define TSTR(str)    L##str
  48. #else
  49.   #define TCHAR        char
  50.   #define TSTR(str)    str    
  51.   #ifndef LPTSTR
  52.     #define LPTSTR LPSTR
  53.   #endif
  54. #endif
  55.  
  56. #ifdef _MAC
  57. DECLARE_ROUTINE_DESC(UserItemUPP,DrawListbox);
  58. #endif
  59.  
  60. #ifdef _MAC
  61. DialogPtr g_pdlg = NULL;
  62. ListHandle g_rghlist[IDC_PARAMLIST+1] = {NULL};
  63. #else
  64. HWND g_hwnd;
  65. TCHAR g_szAppName[] = TSTR("TiBrowse");
  66. #endif
  67.  
  68. ITypeLib  FAR *g_ptlib = NULL;
  69. ITypeInfo FAR *g_ptinfoCur = NULL;
  70. TYPEATTR  FAR *g_ptattrCur = NULL;
  71.  
  72. OLECHAR * g_rgszTKind[] = {
  73.     OLESTR("Enum"),        /* TKIND_ENUM */
  74.     OLESTR("Struct"),        /* TKIND_RECORD */
  75.     OLESTR("Module"),        /* TKIND_MODULE */
  76.     OLESTR("Interface"),    /* TKIND_INTERFACE */
  77.     OLESTR("Dispinterface"),    /* TKIND_DISPATCH */
  78.     OLESTR("Coclass"),        /* TKIND_COCLASS */
  79.     OLESTR("Typedef"),        /* TKIND_ALIAS */
  80.     OLESTR("Union"),        /* TKIND_UNION */
  81. };
  82.  
  83.  
  84. // Set the text of the control identified by the given control id
  85. void
  86. XSetDlgItemText(int ctlid, OLECHAR FAR* psz)
  87. {
  88. #ifdef _MAC
  89.     Rect rc;
  90.     Handle h;
  91.     short kind;
  92.     char buf[255];
  93.  
  94.     strcpy(buf, psz);
  95.     GetDItem(g_pdlg, ctlid, &kind, &h, &rc);
  96.     SetIText(h, c2pstr(buf));
  97. #else
  98. #if defined(WIN32) && !defined(UNICODE)
  99.     char bufA[256];
  100.     WideCharToMultiByte(CP_ACP, NULL, psz, -1, bufA, 256, NULL, NULL);
  101.     SendDlgItemMessage(g_hwnd, ctlid, WM_SETTEXT, 0, (LPARAM)&bufA);
  102. #else
  103.     SendDlgItemMessage(g_hwnd, ctlid, WM_SETTEXT, 0, (LPARAM)psz);
  104. #endif
  105. #endif
  106. }
  107.  
  108. // Clear the listbox identified by the given control id
  109. void
  110. XClrDlgItemList(int ctlid)
  111. {
  112. #ifdef _MAC
  113.     LDelRow(0, 0, g_rghlist[ctlid]); // delete everything
  114. #else
  115.     SendMessage(GetDlgItem(g_hwnd, ctlid), LB_RESETCONTENT, 0, 0L); 
  116. #endif
  117. }
  118.  
  119. // Add the given string to the listbox identified by the given control id
  120. void
  121. XAddDlgItemList(int ctlid, OLECHAR FAR* psz)
  122. {
  123. #ifdef _MAC
  124.     int row;
  125.     Point pt;
  126.     ListHandle hlist;
  127.  
  128.     hlist = g_rghlist[ctlid];
  129.     row = LAddRow(1, -1, hlist);
  130.     pt.v = row, pt.h = 0;
  131.     LSetCell(psz, strlen(psz), pt, hlist);
  132. #else
  133. #if defined(WIN32) && !defined(UNICODE)
  134.     char bufA[256];
  135.     WideCharToMultiByte(CP_ACP, NULL, psz, -1, bufA, 256, NULL, NULL);
  136.     SendDlgItemMessage(g_hwnd, ctlid, LB_ADDSTRING, 0, (LPARAM)&bufA);
  137. #else
  138.     SendDlgItemMessage(g_hwnd, ctlid, LB_ADDSTRING, 0, (LPARAM)psz);
  139. #endif
  140. #endif
  141. }
  142.  
  143. void Cleanup()
  144. {
  145.     if(g_ptinfoCur != NULL){
  146.       if(g_ptattrCur != NULL)
  147.         g_ptinfoCur->ReleaseTypeAttr(g_ptattrCur);
  148.       g_ptinfoCur->Release();
  149.       g_ptinfoCur = NULL;
  150.     }
  151.     if(g_ptlib != NULL){
  152.       g_ptlib->Release();
  153.       g_ptlib = NULL;
  154.     }
  155. }
  156.  
  157. void Uninit()
  158. {
  159.     OleUninitialize();     
  160. #ifdef _MAC
  161. #ifndef _PPCMAC
  162.     UninitOleManager();            // clean up applet
  163. #endif
  164. #endif
  165. }
  166.  
  167.  
  168. void
  169. OpenTypeLib(OLECHAR FAR *sztlib)
  170. {                                     
  171.     unsigned int utypeinfoCount, i;
  172.     BSTR bstrName;
  173.     TLIBATTR FAR* ptlibattr;
  174.  
  175.     /* clear out globals */
  176.     Cleanup();
  177.  
  178.     /* clear out listboxes */
  179.     XClrDlgItemList(IDC_TYPELIST);
  180.     XClrDlgItemList(IDC_MEMBERLIST);
  181.     XClrDlgItemList(IDC_PARAMLIST);
  182.     
  183.     /* load the type library */
  184.     CHECKRESULT(LoadTypeLib(sztlib, &g_ptlib));
  185.  
  186.     /* get library attributes for the fun of it */
  187.     CHECKRESULT(g_ptlib->GetLibAttr(&ptlibattr));
  188.  
  189.     /* release library attributes */
  190.     g_ptlib->ReleaseTLibAttr(ptlibattr);
  191.  
  192.     /* Now add each of the names to the type list */
  193.     utypeinfoCount = g_ptlib->GetTypeInfoCount();
  194.     for(i = 0; i < utypeinfoCount; i++){
  195.       CHECKRESULT(g_ptlib->GetDocumentation(i, &bstrName, NULL, NULL, NULL));  
  196.       ASSERT(bstrName);
  197.       XAddDlgItemList(IDC_TYPELIST, bstrName);
  198.       SysFreeString(bstrName);
  199.     }
  200. }
  201.  
  202. #ifdef WIN32
  203. void
  204. OpenTypeLib(char FAR *sztlib)
  205. {                                     
  206.   OLECHAR buf[MAX_PATH];
  207.  
  208.   MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, 
  209.                   sztlib, -1, buf, MAX_PATH);
  210.   OpenTypeLib(buf);
  211. }
  212. #endif
  213.  
  214.  
  215. /***
  216. *void SetSelectedType
  217. *Purpose:
  218. *  When the user changes the selection of a type, this function updates the
  219. *  dialog by changing the member list and the help for the type. It also sets
  220. *  g_ptinfoCur to refer to the typeinfo.
  221. *
  222. *Entry:
  223. *  dwIndex =
  224. *
  225. *Exit:
  226. *  return value = None
  227. *
  228. ***********************************************************************/
  229. void
  230. SetSelectedType(unsigned long dwIndex)
  231. {
  232.     HRESULT hr;
  233.     BSTR bstrDoc;
  234.     OLECHAR FAR* psz;
  235.     OLECHAR szBuf[40];
  236.     unsigned long dwHelpContext;
  237.     TYPEKIND tkind;
  238.  
  239.     if(g_ptinfoCur != NULL){
  240.       g_ptinfoCur->ReleaseTypeAttr(g_ptattrCur);
  241.       g_ptinfoCur->Release();
  242.     }
  243.  
  244.     /* Clear out the member list */
  245.     XClrDlgItemList(IDC_MEMBERLIST);
  246.  
  247.     if(g_ptlib == NULL)
  248.       return;
  249.  
  250.     // Note: the index in the list box is conveniently the same as the
  251.     // one to pass to GetTypeInfo/GetTypeInfoType
  252.  
  253.     // typeinfo type can be obtained without actually loading the typeinfo
  254.     CHECKRESULT(g_ptlib->GetTypeInfoType((unsigned int)dwIndex, &tkind));
  255.     XSetDlgItemText(IDC_TYPEKIND, g_rgszTKind[tkind]);
  256.  
  257.     CHECKRESULT(g_ptlib->GetTypeInfo((unsigned int)dwIndex, &g_ptinfoCur));
  258.     CHECKRESULT(g_ptinfoCur->GetTypeAttr(&g_ptattrCur));
  259.  
  260.     // GUID
  261.     hr = StringFromCLSID(g_ptattrCur->guid, &psz);
  262.     ASSERT(hr == NOERROR);
  263.     XSetDlgItemText(IDC_GUID, psz);
  264.     MemFree(psz);
  265.  
  266.     // Version
  267.     SPRINTF(szBuf, OLESTR("%u.%02u"),
  268.       g_ptattrCur->wMajorVerNum, g_ptattrCur->wMinorVerNum);
  269.     XSetDlgItemText(IDC_VERSION, szBuf);
  270.     
  271.     CHECKRESULT(
  272.       g_ptlib->GetDocumentation(
  273.         (unsigned int)dwIndex, NULL, &bstrDoc, &dwHelpContext, NULL));
  274.  
  275.     // Help Context
  276.     SPRINTF(szBuf, OLESTR("%ld"), dwHelpContext);
  277.     XSetDlgItemText(IDC_HELPCONTEXT, szBuf);
  278.  
  279.     // Documentation string
  280.     psz = (bstrDoc != NULL) ? bstrDoc : OLESTR("<none>");
  281.     XSetDlgItemText(IDC_HELPSTRING, psz);
  282.     SysFreeString(bstrDoc);
  283.    
  284.     FillMemberList(g_ptinfoCur, g_ptattrCur, IDC_MEMBERLIST); 
  285.  
  286.     XClrDlgItemList(IDC_PARAMLIST);
  287. }
  288.  
  289. /***
  290. *void FillMemberList
  291. *Purpose:
  292. * Sets the current typeinfo to the typeinfo indexed by dwIndex, and
  293. * then fills in the list box with the members of the type.
  294. *
  295. *Entry:
  296. *  ptinfo = 
  297. *  ptypeattr =
  298. *
  299. *Exit:
  300. *  return value = None
  301. *
  302. ***********************************************************************/
  303. void
  304. FillMemberList(
  305.     ITypeInfo FAR *ptinfo,
  306.     TYPEATTR FAR *ptypeattr,
  307.     int ctlid)
  308. {
  309.     MEMBERID memid; 
  310.     BSTR bstrName;
  311.     unsigned int i;
  312.     FUNCDESC FAR *pfuncdesc;
  313.     VARDESC  FAR *pvardesc;
  314.     
  315.     /* Now add all of the functions and all of the vars.
  316.      * This is somewhat roundabout.
  317.      * For each one, we need to get the funcdesc, or the vardesc.
  318.      * From that we get the MEMBERID, and finally can get to the name.
  319.      */
  320.     for(i = 0; i < ptypeattr->cFuncs; i++){
  321.       CHECKRESULT(ptinfo->GetFuncDesc(i, &pfuncdesc));
  322.       memid = pfuncdesc->memid;
  323.       CHECKRESULT(ptinfo->GetDocumentation(memid, &bstrName, NULL, NULL, NULL));
  324.       ptinfo->ReleaseFuncDesc(pfuncdesc);
  325.       pfuncdesc = NULL;
  326.         
  327.       ASSERT(bstrName);                
  328.       XAddDlgItemList(ctlid, bstrName);
  329.       SysFreeString(bstrName);
  330.     }
  331.                     
  332.     for(i = 0; i < ptypeattr->cVars; i++)
  333.     {
  334.       CHECKRESULT(ptinfo->GetVarDesc(i, &pvardesc));
  335.       memid = pvardesc->memid;
  336.       CHECKRESULT(ptinfo->GetDocumentation(memid, &bstrName, NULL, NULL, NULL));
  337.       ptinfo->ReleaseVarDesc(pvardesc);
  338.       pvardesc = NULL;
  339.                     
  340.       ASSERT(bstrName);
  341.       XAddDlgItemList(ctlid, bstrName);
  342.       SysFreeString(bstrName);
  343.     }
  344. }
  345.  
  346. /***
  347. *void SetSelectedMember
  348. *Purpose:
  349. *  When a member of a type is selected, update the help to be the help
  350. *  of the member, and if the member is a function update the parameter
  351. *  list to reflect that it is a function.
  352. *
  353. *Entry:
  354. *  dwIndex =
  355. *
  356. *Exit:
  357. *  return value = None
  358. *
  359. ***********************************************************************/
  360. void
  361. SetSelectedMember(unsigned long dwIndex)
  362. {
  363.     MEMBERID memid;
  364.  
  365.     /* In any case, we'll need to clear out the parameter list. */
  366.     XClrDlgItemList(IDC_PARAMLIST);
  367.  
  368.     if(g_ptattrCur == NULL)
  369.       return;
  370.     
  371.     /* if this is a function, fill the param list, otherwise just fill
  372.      * in the item info.
  373.      */
  374.     if(dwIndex < g_ptattrCur->cFuncs){
  375.       unsigned short i;
  376.       unsigned int cNames;
  377.       FUNCDESC FAR *pfuncdesc;
  378.       const unsigned int MAX_NAMES = 40;
  379.       BSTR rgNames[MAX_NAMES];
  380.  
  381.       CHECKRESULT(g_ptinfoCur->GetFuncDesc((unsigned int) dwIndex, &pfuncdesc));
  382.       memid = pfuncdesc->memid;
  383.       UpdateMemberInfo(memid);
  384.     
  385.       CHECKRESULT(g_ptinfoCur->GetNames(memid, rgNames, MAX_NAMES,&cNames));
  386.       for(i = 1; i < cNames; i++){
  387.     ASSERT(rgNames[i])
  388.     XAddDlgItemList(IDC_PARAMLIST, rgNames[i]);
  389.     SysFreeString(rgNames[i]);
  390.       }
  391.       ASSERT(rgNames[0]);              
  392.       SysFreeString(rgNames[0]);
  393.       g_ptinfoCur->ReleaseFuncDesc(pfuncdesc);
  394.     }
  395.     else
  396.     {
  397.       VARDESC FAR *pvardesc;
  398.  
  399.       CHECKRESULT(
  400.         g_ptinfoCur->GetVarDesc(
  401.       (unsigned int)(dwIndex - g_ptattrCur->cFuncs), &pvardesc));
  402.       memid = pvardesc->memid;
  403.       UpdateMemberInfo(memid);
  404.       g_ptinfoCur->ReleaseVarDesc(pvardesc);
  405.     }
  406. }
  407.  
  408. /***
  409. *void UpdateMemberInfo
  410. *Purpose:
  411. *  sets fields on the dialog (such as help string and help context) from
  412. *  the type information.
  413. *
  414. *Entry:
  415. *  memid =
  416. *
  417. *Exit:
  418. *  return value = None
  419. *
  420. ***********************************************************************/
  421. void
  422. UpdateMemberInfo(MEMBERID memid)                   
  423. {
  424.     BSTR bstrDoc;
  425.     OLECHAR buf[40];                    
  426.     unsigned long dwHelpContext;
  427.  
  428.     /* get the member information */
  429.     CHECKRESULT(g_ptinfoCur->GetDocumentation(
  430.       memid, NULL, &bstrDoc, &dwHelpContext, NULL));
  431.  
  432.     /* update the help string displayed in the dialog */
  433.     XSetDlgItemText(IDC_HELPSTRING, (bstrDoc != NULL) ? 
  434.                                  bstrDoc : OLESTR("<none>"));
  435.     SysFreeString(bstrDoc);
  436.         
  437.     /* update the help context displayed in the dialog */
  438.     SPRINTF(buf, OLESTR("%ld"), dwHelpContext);
  439.     XSetDlgItemText(IDC_HELPCONTEXT, buf);
  440. }
  441.  
  442. /***
  443. *void SetSelectedParam
  444. *Purpose:
  445. *  CONSIDER: Enhance to show parameter type information here.
  446. *
  447. *Entry:
  448. *  dwIndex =
  449. *
  450. *Exit:
  451. *  return value = None
  452. *
  453. ***********************************************************************/
  454. void
  455. SetSelectedParam(unsigned long dwIndex)
  456. {
  457. }
  458.  
  459.  
  460. HRESULT
  461. GetFileName(BSTR FAR* pbstrFileName)
  462. {
  463.     OLECHAR buf[1024];
  464.     BSTR bstrFileName;
  465.  
  466. #ifdef _MAC
  467.  
  468.     int i;
  469.     Point pt;
  470.     long dirID;
  471.     char *p, *q;
  472.     SFReply sfr;
  473.     SFTypeList sftl;
  474.     short sRefNumReal;
  475.  
  476.     SetPt(&pt, 100, 100);
  477.     //sftl[0] = 'OTLB';
  478.     sftl[0] = 0; // currently allow all file types
  479.     SFGetFile(pt, NULL, NULL, -1, sftl, NULL, &sfr);
  480.  
  481.     if(!sfr.good)
  482.       return E_FAIL;
  483.  
  484.     // translate sfr.vRefNum into a dirID
  485.     {
  486.     WDPBRec wdpbr;
  487.  
  488.     wdpbr.ioWDIndex   = 0;
  489.     wdpbr.ioVRefNum   = sfr.vRefNum;
  490.     wdpbr.ioWDVRefNum = 0;
  491.     wdpbr.ioWDIndex   = 0;
  492.     wdpbr.ioWDProcID  = 0;
  493.     wdpbr.ioNamePtr   = (StringPtr)buf;
  494.  
  495.     if(PBGetWDInfoSync (&wdpbr) != noErr)
  496.       return E_FAIL;
  497.  
  498.     sRefNumReal = wdpbr.ioWDVRefNum;
  499.     dirID = wdpbr.ioWDDirID;
  500.     }
  501.  
  502.     {
  503.     Str255 stDir;
  504.     CInfoPBRec pb;
  505.     DirInfo *pdirinfo = (DirInfo*)&pb;
  506.     char rgchTemp[256]; // REVIEW: what should the size be?
  507.  
  508.     pdirinfo->ioNamePtr = stDir;
  509.     pdirinfo->ioVRefNum = sRefNumReal;
  510.     pdirinfo->ioDrParID = dirID;
  511.     pdirinfo->ioFDirIndex = -1;  // get info on a dir
  512.  
  513.     buf[0] = '\0';
  514.  
  515.     // loop until we hit the root dir
  516.     do{
  517.       pdirinfo->ioDrDirID = pdirinfo->ioDrParID;
  518.       if(PBGetCatInfoSync (&pb) != noErr)
  519.         return E_FAIL;
  520.       strncpy(rgchTemp, (char*)stDir, 64);
  521.       p2cstr((StringPtr)rgchTemp);
  522.       strcat(rgchTemp, ":");
  523.       strcat(rgchTemp, buf);
  524.       strcpy(buf, rgchTemp);
  525.     }while(pdirinfo->ioDrDirID != fsRtDirID);
  526.  
  527.     }
  528.  
  529.     q = (char*)sfr.fName;
  530.     i = (int)*q++;
  531.     p = &buf[strlen(buf)];
  532.     while(i-->0)
  533.       *p++ = *q++;
  534.     *p = '\0';
  535.  
  536.     if((bstrFileName = SysAllocString(buf)) == NULL)
  537.       return E_OUTOFMEMORY;
  538.  
  539. #else
  540.  
  541.     OPENFILENAME ofn;                         
  542.  
  543.     memset(&ofn, 0, sizeof(OPENFILENAME));
  544.     ofn.lStructSize  = sizeof(OPENFILENAME);
  545.     ofn.hwndOwner    = g_hwnd;
  546.     ofn.lpstrFile    = (LPTSTR) &buf;
  547.     ofn.nMaxFile     = sizeof(buf);
  548.     *buf = OLESTR('\0');
  549.     ofn.lpstrFilter  = TSTR("Type Libraries\0*.tlb\0\0");
  550.     ofn.nFilterIndex = 1; 
  551.     ofn.Flags        = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_SHAREAWARE;
  552.     if(GetOpenFileName(&ofn) == 0){ 
  553.       // REVIEW: we can probably do something smarter with this error
  554.       DWORD dwerr = CommDlgExtendedError();
  555.       return E_FAIL;
  556.     }
  557. #if defined(WIN32) && !defined(UNICODE)
  558.     OLECHAR szFileW[_MAX_PATH];
  559.     MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,
  560.             ofn.lpstrFile, -1, szFileW, _MAX_PATH);
  561.     if((bstrFileName = SysAllocString(szFileW)) == NULL)
  562.       return E_OUTOFMEMORY;
  563. #else
  564.     if((bstrFileName = SysAllocString(ofn.lpstrFile)) == NULL)
  565.       return E_OUTOFMEMORY;
  566. #endif
  567.  
  568. #endif
  569.  
  570.     *pbstrFileName = bstrFileName;
  571.     return NOERROR;
  572. }
  573.  
  574. void
  575. AssertFail(char FAR* file, int line)
  576. {    
  577.     // Ansi Output for Assertion
  578.     #ifdef UNICODE
  579.       #define OUTPUTDEBUGSTRING    OutputDebugStringA
  580.       #define MESSAGEBOX    MessageBoxA
  581.     #else
  582.       #define OUTPUTDEBUGSTRING    OutputDebugString
  583.       #define MESSAGEBOX    MessageBox
  584.     #endif      
  585.     
  586.     char buf[128];
  587.  
  588.     sprintf(buf, "Assertion failed: %s(%d)", file, line);
  589.  
  590. #ifdef _MAC
  591.     DebugStr(c2pstr(buf));
  592. #else
  593.     OUTPUTDEBUGSTRING(buf);
  594.     if(MESSAGEBOX(NULL, buf, 
  595.       "TiBrowse Assertion.  OK to continue, CANCEL to quit.",
  596.       MB_OKCANCEL | MB_TASKMODAL) == IDCANCEL)
  597.       exit(1);
  598.     DebugBreak();
  599. #endif
  600. }
  601.  
  602. #ifdef _MAC /* { */
  603.  
  604. void Init(void);
  605. void EventLoop(void);
  606.  
  607. void AdjustMenus(void);
  608. void DoEvent(EventRecord *pevent);
  609. void DoMenuCommand(long menuResult);
  610. void Quit(void);
  611. #ifndef _MSC_VER
  612. #ifndef ConstStr255Param
  613. #define ConstStr255Param StringPtr
  614. #endif
  615. #endif
  616. void Fatal(ConstStr255Param);
  617.  
  618. Boolean
  619. IsAppWindow(WindowPtr window)
  620. {
  621.     return (window == NULL)
  622.       ? false : ((WindowPeek)window)->windowKind == userKind;
  623. }
  624.  
  625. Boolean
  626. IsDAWindow(WindowPtr window)
  627. {
  628.     return (window == NULL)
  629.       ? false : (((WindowPeek)window)->windowKind < 0);
  630. }
  631.  
  632. void
  633. main()
  634. {
  635.     Init();
  636. //    ShowWindow(g_pdlg); // REVIEW: necessarry?
  637.     EventLoop();
  638. }
  639.  
  640. void
  641. DoDialogEvent(EventRecord *pevent, short sItem)
  642. {
  643.     Point pt;
  644.     GrafPtr pport;
  645.     ListHandle hlist;
  646.  
  647.     switch(sItem){
  648.     case IDC_TYPELIST:
  649.     case IDC_MEMBERLIST:
  650.     case IDC_PARAMLIST:
  651.       if(pevent->what == mouseDown){
  652.     GetPort(&pport);
  653.     SetPort(g_pdlg);
  654.         GlobalToLocal(&pevent->where);
  655.     hlist = g_rghlist[sItem];
  656.         LClick(pevent->where, pevent->modifiers, hlist);
  657.     SetPt(&pt, 0, 0);
  658.     if(LGetSelect(true, &pt, hlist)){
  659.       switch(sItem){
  660.       case IDC_TYPELIST:
  661.         SetSelectedType(pt.v);
  662.         break;
  663.       case IDC_MEMBERLIST:
  664.         SetSelectedMember(pt.v);
  665.         break;
  666.       case IDC_PARAMLIST:
  667.         SetSelectedParam(pt.v);
  668.         break;
  669.       }
  670.     }
  671.     SetPort(pport);
  672.       }
  673.       break;
  674.     }
  675. }
  676.  
  677. void
  678. EventLoop()
  679. {
  680.     short sItem;
  681.     DialogPtr pdlg;
  682.     EventRecord    event;
  683.     RgnHandle cursorRgn;
  684.  
  685.     cursorRgn = NewRgn();
  686.     while(1){
  687.       if(WaitNextEvent(everyEvent, &event, MAXLONG, cursorRgn)){
  688.     if (FrontWindow() != NULL
  689.      && event.what != diskEvt
  690.      && (event.what != keyDown || (event.modifiers & cmdKey) == 0)
  691.      && IsDialogEvent(&event))
  692.     {
  693.       if(DialogSelect(&event, &pdlg, &sItem)){
  694.         ASSERT(pdlg == g_pdlg);
  695.         DoDialogEvent(&event, sItem);
  696.       }
  697.     }else{
  698.       DoEvent(&event);
  699.     }
  700.       }
  701.     }
  702. }
  703.  
  704. void
  705. DoEvent(EventRecord *pevent)
  706. {
  707.     char key;
  708.     short part;
  709.     WindowPtr window;
  710.  
  711.     switch(pevent->what){
  712.     case mouseDown:
  713.       part = FindWindow(pevent->where, &window);
  714.       switch(part){
  715.       case inMenuBar:
  716.     AdjustMenus();
  717.     DoMenuCommand(MenuSelect(pevent->where));
  718.     break;
  719.  
  720.       case inSysWindow:    /* let the system handle the mouseDown */
  721.     SystemClick(pevent, window);
  722.     break;
  723.  
  724.       case inContent:
  725.     if(window != FrontWindow()){
  726.       SelectWindow(window);
  727.     }
  728.     break;
  729.  
  730.       case inDrag:
  731.     DragWindow(window, pevent->where, &qd.screenBits.bounds);
  732.     break;
  733.       }
  734.       break;
  735.  
  736.     case keyDown:
  737.     case autoKey:            /* check for menukey equivalents */
  738.       key = (char)(pevent->message & charCodeMask);
  739.       if(pevent->modifiers & cmdKey){    /* Command key down */
  740.     if(pevent->what == keyDown){
  741.       /* enable/disable/check menu items properly */
  742.       AdjustMenus();
  743.       DoMenuCommand(MenuKey(key));
  744.     }
  745.       }
  746.       break;
  747.     }
  748. }
  749.  
  750. void
  751. Enable(MenuHandle hmenu, short sItem, Boolean fEnable)
  752. {
  753.     if(fEnable)
  754.       EnableItem(hmenu, sItem);
  755.     else
  756.       DisableItem(hmenu, sItem);
  757. }
  758.  
  759. void
  760. AdjustMenus()
  761. {
  762.     Boolean fIsDA;
  763.     MenuHandle hmenu;
  764.  
  765.     fIsDA = IsDAWindow(FrontWindow());
  766.  
  767.     /* we can allow desk accessories to be closed from the menu */
  768.     hmenu = GetMHandle(mFile);
  769.     Enable(hmenu, iClose, fIsDA);
  770.  
  771.     hmenu = GetMHandle(mEdit);
  772.     Enable(hmenu, iUndo,  fIsDA);
  773.     Enable(hmenu, iCut,   fIsDA);
  774.     Enable(hmenu, iCopy,  fIsDA);
  775.     Enable(hmenu, iPaste, fIsDA);
  776.     Enable(hmenu, iClear, fIsDA);
  777. }
  778.  
  779. void
  780. DoMenuCommand(long menuResult)
  781. {
  782.     short menuID;        /* the resource ID of the selected menu */
  783.     short menuItem;        /* the item number of the selected menu */
  784.     Str255 daName;
  785.  
  786.     menuID = HiWord(menuResult);
  787.     menuItem = LoWord(menuResult);
  788.  
  789.     switch(menuID){
  790.     case mApple:
  791.       switch(menuItem){
  792.       case iAbout:        /* bring up alert for About */
  793.     Alert(rAboutAlert, NULL);
  794.     break;
  795.       default:
  796.     GetMenuItemText(GetMHandle(mApple), menuItem, daName);
  797.     OpenDeskAcc(daName);
  798.     break;
  799.       }
  800.       break;
  801.  
  802.     case mFile:
  803.       switch(menuItem){
  804.       case iOpen:
  805.     {
  806.         BSTR bstrFileName;
  807.         if(GetFileName(&bstrFileName) != NOERROR)
  808.     {
  809.       // REVIEW: shouldnt just bag out here
  810.       Fatal((ConstStr255Param)"\pUnable to open Type Library");
  811.         }
  812.         OpenTypeLib(bstrFileName);
  813.     }
  814.     break;
  815.  
  816.       case iQuit:
  817.     Quit();
  818.     break;
  819.       }
  820.       break;
  821.  
  822.     case mEdit:
  823.       SystemEdit(menuItem-1);
  824.       break;
  825.     }
  826.  
  827.     HiliteMenu(0);
  828. }
  829.  
  830. extern "C" {
  831.  
  832. #if defined(_MSC_VER)
  833. void pascal
  834. #else
  835. pascal void
  836. #endif
  837. DrawListbox(DialogPtr pdlg, short sItem)
  838. {
  839.     Rect rc;
  840.     Handle h;
  841.     short kind;
  842.     GrafPtr port;
  843.     ListHandle hlist;
  844.  
  845.     ASSERT(sItem == IDC_TYPELIST
  846.     || sItem == IDC_MEMBERLIST
  847.     || sItem == IDC_PARAMLIST);
  848.  
  849.     GetPort(&port);
  850.     SetPort(pdlg);
  851.     hlist = g_rghlist[sItem];
  852.     LUpdate(pdlg->visRgn, hlist);
  853.     GetDItem(pdlg, sItem, &kind, &h, &rc);
  854.     InsetRect(&rc, -1, -1);
  855.     FrameRect(&rc);
  856.     SetPort(port);
  857. }
  858.  
  859. }
  860.  
  861.  
  862. /***
  863. *ListHandle CreateListBox(DialogPtr, int)
  864. *Purpose:
  865. *  Create a listbox on the given dialog, associated with the given
  866. *  control id.
  867. *
  868. *Entry:
  869. *  pdlg =
  870. *  ctlid =
  871. *
  872. *Exit:
  873. *  return value = ListHandle
  874. *
  875. ***********************************************************************/
  876. ListHandle
  877. CreateListbox(DialogPtr pdlg, int ctlid)
  878. {
  879.     Handle h;
  880.     short kind;
  881.     Point ptCell;
  882.     ListHandle hlist;
  883.     Rect rcView, rcBounds;
  884.  
  885.     INIT_ROUTINE_DESC(NewUserItemProc,DrawListbox);
  886.  
  887.     GetDItem(pdlg, ctlid, &kind, &h, &rcView);
  888.     SetDItem(pdlg, ctlid, kind, (Handle) ROUTINE_DESC(DrawListbox), &rcView);
  889.  
  890.     // make room for scroll bars
  891.     rcView.right -= 15;
  892.  
  893.     // list is 1 wide
  894.     SetRect(&rcBounds, 0, 0, 1, 0);
  895.  
  896.     SetPt(&ptCell, 0, 0);
  897.  
  898.     hlist = LNew(
  899.       &rcView,
  900.       &rcBounds,
  901.       ptCell,
  902.       0, (WindowPtr)pdlg, true, false, false, true);
  903.  
  904.     ASSERT(hlist != NULL);
  905.  
  906.     (*hlist)->selFlags = lUseSense | lNoRect | lNoExtend | lOnlyOne;
  907.  
  908.     return hlist;
  909. }
  910.  
  911. /***
  912. *DialogPtr CreateDialog(void)
  913. *Purpose:
  914. *  Create the TiBrowse dialog
  915. *
  916. *Entry:
  917. *  None
  918. *
  919. *Exit:
  920. *  return value = DialogPtr
  921. *
  922. ***********************************************************************/
  923. DialogPtr
  924. CreateDialog()
  925. {
  926.     int i;
  927.     Point pt;
  928.     DialogPtr pdlg;
  929.     ListHandle hlist;
  930. static short rgctl[] = {IDC_TYPELIST, IDC_MEMBERLIST, IDC_PARAMLIST};
  931.  
  932.     if((pdlg = GetNewDialog(rDlg, NULL, (WindowPtr)-1)) == NULL)
  933.       return NULL;
  934.  
  935.     for(i = 0; i < DIM(rgctl); ++i){
  936.       g_rghlist[rgctl[i]]  = CreateListbox(pdlg, rgctl[i]);
  937.     }
  938.  
  939.     SetPt(&pt, 0, 0);
  940.     for(i = 0; i < DIM(rgctl); ++i){
  941.       hlist = g_rghlist[rgctl[i]];
  942.       LSetSelect(true, pt, hlist);
  943.       LDoDraw(true, hlist);
  944.     }
  945.  
  946.     return pdlg;
  947. }
  948.  
  949.  
  950. void
  951. Init()
  952. {
  953.     Handle menuBar;
  954.  
  955.     MaxApplZone();
  956.  
  957.     InitGraf((Ptr)&qd.thePort);
  958.     InitFonts();
  959.     InitWindows();
  960.     InitMenus();
  961.     TEInit();
  962.     InitDialogs(NULL);
  963.     InitCursor();
  964.     FlushEvents(everyEvent, 0);
  965.  
  966. #ifndef _PPCMAC
  967.     if (InitOleManager(0) != NOERROR)
  968.       Fatal((ConstStr255Param)"\pCould not initialize OLE Applet");
  969. #endif
  970.  
  971.     if(OleInitialize(NULL) != NOERROR)
  972.       Fatal((ConstStr255Param)"\pUnable to Initialize Ole");
  973.  
  974.     if((menuBar = GetNewMBar(rMenuBar)) == NULL)
  975.       Fatal((ConstStr255Param)"\pUnable to load menu bar");
  976.     SetMenuBar(menuBar);
  977.     DisposHandle(menuBar);
  978.     AddResMenu(GetMHandle(mApple), 'DRVR');
  979.     DrawMenuBar();
  980.  
  981.     if((g_pdlg = CreateDialog()) == NULL)
  982.       Fatal((ConstStr255Param)"\pUnable to create dialog");
  983. }
  984.  
  985. void
  986. Quit()
  987. {
  988.     Cleanup();
  989.     Uninit();
  990.     ExitToShell();
  991. }
  992.  
  993. /* display fatal error alert, and exit */
  994. void
  995. Fatal(ConstStr255Param msg)
  996. {
  997.     SetCursor(&qd.arrow);
  998.     ParamText(msg, (ConstStr255Param)"\p", (ConstStr255Param)"\p", (ConstStr255Param)"\p");
  999.     Alert(rUserAlert, nil);
  1000.     Quit();
  1001. }
  1002.  
  1003. #else /* }{ */
  1004.  
  1005. long FAR PASCAL EXPORT WndProc (HWND, UINT, WPARAM, LPARAM) ;
  1006.  
  1007. int PASCAL
  1008. WinMain(
  1009.     HINSTANCE hinst,
  1010.     HINSTANCE hinstPrev,
  1011.     LPSTR lpszCmdLine,
  1012.     int nCmdShow)
  1013. {
  1014.     MSG msg;
  1015.     WNDCLASS wndclass;
  1016.  
  1017.     if(!hinstPrev){
  1018.       wndclass.style          = CS_HREDRAW | CS_VREDRAW;
  1019.       wndclass.lpfnWndProc    = WndProc ;
  1020.       wndclass.cbClsExtra     = 0 ;
  1021.       wndclass.cbWndExtra     = DLGWINDOWEXTRA ;
  1022.       wndclass.hInstance      = hinst ;
  1023.       wndclass.hIcon          = LoadIcon (hinst, g_szAppName) ;
  1024.       wndclass.hCursor        = LoadCursor (NULL, IDC_ARROW) ;
  1025.       wndclass.hbrBackground  = (HBRUSH) (COLOR_WINDOW + 1) ;
  1026.       wndclass.lpszMenuName   = NULL ;
  1027.       wndclass.lpszClassName  = g_szAppName ;
  1028.  
  1029.       RegisterClass (&wndclass) ;
  1030.     }
  1031.        
  1032.     if(OleInitialize(NULL) != NOERROR){
  1033.       MessageBox(NULL, TSTR("unable to initialize Ole"),
  1034.              g_szAppName, MB_OK);
  1035.       return 0;
  1036.     }
  1037.      
  1038.     g_hwnd = CreateDialog(hinst, g_szAppName, 0, NULL);
  1039.  
  1040.     if(*lpszCmdLine == '\0'){
  1041.       BSTR bstrFileName;
  1042.       if(GetFileName(&bstrFileName) != NOERROR){
  1043.     Cleanup();
  1044.     Uninit();
  1045.     exit(-1);
  1046.       }
  1047.       OpenTypeLib(bstrFileName);
  1048.       SysFreeString(bstrFileName);
  1049.     }else{
  1050.       OpenTypeLib(lpszCmdLine);
  1051.     }
  1052.       
  1053.     ShowWindow(g_hwnd, nCmdShow);
  1054.  
  1055.     while(GetMessage (&msg, NULL, 0, 0)){
  1056.       TranslateMessage (&msg);
  1057.       DispatchMessage (&msg);
  1058.     }
  1059.     Cleanup();
  1060.     Uninit();
  1061.     return msg.wParam;
  1062. }
  1063.  
  1064. long FAR PASCAL EXPORT
  1065. WndProc(
  1066.     HWND hwnd,
  1067.     UINT message,
  1068.     WPARAM wParam,
  1069.     LPARAM lParam)
  1070. {
  1071.     unsigned long dwIndex;
  1072.  
  1073.     switch(message){
  1074.     case WM_COMMAND: 
  1075.       /* We deal with the following events:
  1076.        * The selection changes on the type list and we have
  1077.        *  to update the member list & type info.
  1078.        * The selection changes on the member list and we have
  1079.        *  to update the param list & member info.
  1080.        * Selection changes on a parameter and we have to
  1081.        *  update the param info.
  1082.        */
  1083. #ifdef WIN32
  1084. # define wParamX LOWORD(wParam)
  1085. # define notifyMsg HIWORD(wParam)
  1086. #else
  1087. # define wParamX wParam
  1088. # define notifyMsg HIWORD(lParam)
  1089. #endif
  1090.       switch(wParamX){
  1091.       case IDC_TYPELIST:
  1092.         if(notifyMsg == LBN_SELCHANGE){
  1093.           dwIndex = SendDlgItemMessage(hwnd, IDC_TYPELIST, LB_GETCURSEL, 0, 0L);
  1094.       if(dwIndex != LB_ERR)
  1095.         SetSelectedType(dwIndex);
  1096.     }
  1097.     break;
  1098.       case IDC_MEMBERLIST:
  1099.         if(notifyMsg == LBN_SELCHANGE){
  1100.           dwIndex = SendDlgItemMessage(hwnd, IDC_MEMBERLIST, LB_GETCURSEL,0,0L);
  1101.       if(dwIndex != LB_ERR)
  1102.         SetSelectedMember(dwIndex);
  1103.     }
  1104.         break;
  1105.       case IDC_PARAMLIST:
  1106.         if(notifyMsg == LBN_SELCHANGE){
  1107.           dwIndex = SendDlgItemMessage(hwnd, IDC_PARAMLIST, LB_GETCURSEL, 0,0L);
  1108.       if(dwIndex != LB_ERR)
  1109.         SetSelectedParam(dwIndex);
  1110.     }
  1111.     break;
  1112.       }
  1113.       return 0;
  1114.  
  1115.     case WM_DESTROY:
  1116.       PostQuitMessage(0);
  1117.       return 0 ;
  1118.     }
  1119.     return DefWindowProc (hwnd, message, wParam, lParam) ;
  1120. }
  1121.  
  1122. #endif /* } */
  1123.  
  1124. void
  1125. MethodError(HRESULT hresult)
  1126. {
  1127.     /* CONSIDER: add code to figure out what specific error this is */
  1128.     UNUSED(hresult);
  1129.  
  1130. #ifdef _MAC
  1131.     Fatal((ConstStr255Param)"\pType Library");
  1132. #else
  1133.     MessageBox(NULL, TSTR("Error returned from TYPELIB.DLL"),
  1134.            g_szAppName, MB_OK);
  1135.     exit(1);
  1136. #endif
  1137. }
  1138.  
  1139. /* free using the task allocator */
  1140. void
  1141. MemFree(void FAR* pv)
  1142. {
  1143.     HRESULT hresult;
  1144.     IMalloc FAR* pmalloc;
  1145.  
  1146.     hresult = CoGetMalloc(MEMCTX_TASK, &pmalloc);
  1147.  
  1148.     if(hresult != NOERROR){
  1149. #ifdef _MAC
  1150.       Fatal((ConstStr255Param)"\pError accessing task allocator");
  1151. #else
  1152.       MessageBox(NULL, TSTR("Error accessing task allocator"),
  1153.              g_szAppName, MB_OK);
  1154. #endif
  1155.       return;
  1156.     }
  1157.  
  1158.     pmalloc->Free(pv);
  1159.     pmalloc->Release();
  1160. }
  1161.  
  1162.