Annotation of mstools/ole20/samples/tibrowse/tibrowse.cpp, revision 1.1

1.1     ! root        1: /*** 
        !             2: *tibrowse.cpp
        !             3: *
        !             4: *  Copyright (C) 1992, Microsoft Corporation.  All Rights Reserved.
        !             5: *  Information Contained Herein Is Proprietary and Confidential.
        !             6: *
        !             7: *Purpose:
        !             8: *  Type Information Browser
        !             9: *
        !            10: *
        !            11: *Implementation Notes:
        !            12: *
        !            13: *****************************************************************************/
        !            14: 
        !            15: #include <windows.h>
        !            16: #include <ole2.h>
        !            17: #include <dispatch.h>
        !            18: 
        !            19: #include <stdlib.h>
        !            20: #include <string.h>
        !            21: #include <malloc.h>
        !            22: #include <commdlg.h>
        !            23: 
        !            24: #include "resource.h"
        !            25: 
        !            26: void OpenTypeLib(char FAR*);
        !            27: void SetSelectedType(DWORD);
        !            28: void FillMemberList(ITypeInfo FAR *, TYPEATTR FAR *, HWND);
        !            29: void SetSelectedMember(DWORD); 
        !            30: void SetSelectedParam(DWORD dwIndex);
        !            31: void UpdateMemberInfo(MEMBERID memid);                   
        !            32: void AssertFail(char FAR*, WORD);
        !            33: void MethodError(HRESULT hresult);                   
        !            34: void Cleanup(void);                   
        !            35: void MemFree(void FAR*);
        !            36: 
        !            37: #define        CHECKRESULT(X) \
        !            38:   {HRESULT hresult = (X); \
        !            39:     if(hresult != NOERROR && FAILED(GetScode(hresult))) MethodError(hresult); }
        !            40: 
        !            41: #ifdef _DEBUG
        !            42: # define Assert(expr) if (!(expr)) AssertFail(__FILE__, __LINE__);
        !            43: # define SideAssert(expr) Assert(expr)
        !            44: #else
        !            45: # define Assert(expr)
        !            46: # define SideAssert(expr) (expr)
        !            47: #endif
        !            48: 
        !            49: #ifdef WIN32
        !            50: #define EXPORT
        !            51: #else
        !            52: #define EXPORT _export
        !            53: #endif
        !            54: 
        !            55: static HWND g_hwndMain;
        !            56: static char g_szAppName[] = "TiBrowse" ;
        !            57: 
        !            58: static ITypeLib  FAR *g_ptlib;
        !            59: static ITypeInfo FAR *g_ptinfoCur;
        !            60: static TYPEATTR  FAR *g_ptypeattrCur;
        !            61: 
        !            62: static char * g_rgszTKind[] = {
        !            63:     "Enum",            /* TKIND_ENUM */
        !            64:     "Struct",          /* TKIND_RECORD */
        !            65:     "Module",          /* TKIND_MODULE */
        !            66:     "Interface",       /* TKIND_INTERFACE */
        !            67:     "Dispinterface",   /* TKIND_DISPATCH */
        !            68:     "Coclass",         /* TKIND_COCLASS */
        !            69:     "Typedef",         /* TKIND_ALIAS */
        !            70: 
        !            71:     /* NOTE: the following aren't supported in typeinfo yet */
        !            72:     "Union",           /* TKIND_UNION */
        !            73:     "Encap Union"      /* TKIND_ENCUNION */
        !            74: };
        !            75: 
        !            76: long FAR PASCAL EXPORT WndProc (HWND, UINT, WPARAM, LPARAM) ;
        !            77: 
        !            78: int PASCAL
        !            79: WinMain(
        !            80:     HANDLE hInstance,
        !            81:     HANDLE hPrevInstance,
        !            82:     LPSTR lpszCmdLine,
        !            83:     int nCmdShow)
        !            84: {
        !            85:     MSG msg;
        !            86:     WNDCLASS wndclass;
        !            87:     OPENFILENAME ofn;                         
        !            88:  
        !            89:     if(!hPrevInstance){
        !            90:       wndclass.style          = CS_HREDRAW | CS_VREDRAW;
        !            91:       wndclass.lpfnWndProc    = WndProc ;
        !            92:       wndclass.cbClsExtra     = 0 ;
        !            93:       wndclass.cbWndExtra     = DLGWINDOWEXTRA ;
        !            94:       wndclass.hInstance      = hInstance ;
        !            95:       wndclass.hIcon          = LoadIcon (hInstance, g_szAppName) ;
        !            96:       wndclass.hCursor        = LoadCursor (NULL, IDC_ARROW) ;
        !            97:       wndclass.hbrBackground  = (HBRUSH) (COLOR_WINDOW + 1) ;
        !            98:       wndclass.lpszMenuName   = NULL ;
        !            99:       wndclass.lpszClassName  = g_szAppName ;
        !           100: 
        !           101:       RegisterClass (&wndclass) ;
        !           102:     }
        !           103:        
        !           104:     if(OleInitialize(NULL) != NOERROR){
        !           105:       MessageBox(NULL, "unable to initialize Ole", g_szAppName, MB_OK);
        !           106:       return 0;
        !           107:     }
        !           108:      
        !           109:     g_hwndMain = CreateDialog(hInstance, g_szAppName, 0, NULL);
        !           110: 
        !           111:     /* Open up the type library, and add the names of all the types to
        !           112:      * the list box.  If command line parameter given, assume it is a
        !           113:      * valid file name.  Otherwise, use COMMDLG.DLL to put up a file open
        !           114:      * dialog and query the user for a filename.
        !           115:      */
        !           116:     if(!lstrcmp(lpszCmdLine, "")){
        !           117:       char FileBuf[128];
        !           118:             
        !           119:       memset(&ofn, 0, sizeof(OPENFILENAME));
        !           120:       ofn.lStructSize = sizeof(OPENFILENAME);
        !           121:       ofn.hwndOwner = g_hwndMain;
        !           122:       ofn.lpstrFile = (LPSTR)&FileBuf;
        !           123:       ofn.nMaxFile = sizeof(FileBuf);
        !           124:       *FileBuf = '\0';
        !           125:       ofn.lpstrFilter = "Type Libraries\0*.tlb\0\0";
        !           126:       ofn.nFilterIndex = 1; 
        !           127:       ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
        !           128:       if(GetOpenFileName(&ofn) == 0){ 
        !           129:        DWORD dwerr;
        !           130: 
        !           131:        dwerr = CommDlgExtendedError();
        !           132:         /* CONSIDER: do something with this error code */
        !           133:         Cleanup();
        !           134:         exit(1);
        !           135:       }
        !           136:       lpszCmdLine = ofn.lpstrFile;     /* get file user selected */
        !           137:     }
        !           138: 
        !           139:     OpenTypeLib(lpszCmdLine);
        !           140:      
        !           141:     ShowWindow(g_hwndMain, nCmdShow);
        !           142: 
        !           143:     while(GetMessage (&msg, NULL, 0, 0)){
        !           144:       TranslateMessage (&msg);
        !           145:       DispatchMessage (&msg);
        !           146:     }
        !           147:         
        !           148:     Cleanup();
        !           149: 
        !           150:     return msg.wParam;
        !           151: }
        !           152: 
        !           153: 
        !           154: void Cleanup()
        !           155: {
        !           156:     if(g_ptinfoCur != NULL)
        !           157:       g_ptinfoCur->Release();
        !           158:     if(g_ptlib != NULL)
        !           159:       g_ptlib->Release();
        !           160:     OleUninitialize();  
        !           161: }
        !           162: 
        !           163: 
        !           164: long FAR PASCAL EXPORT
        !           165: WndProc(
        !           166:     HWND hwnd,
        !           167:     UINT message,
        !           168:     WPARAM wParam,
        !           169:     LPARAM lParam)
        !           170: {
        !           171:     DWORD dwIndex;
        !           172: 
        !           173:     switch(message){
        !           174:     case WM_COMMAND: 
        !           175:       /* We deal with the following events:
        !           176:        * The selection changes on the type list and we have
        !           177:        *  to update the member list & type info.
        !           178:        * The selection changes on the member list and we have
        !           179:        *  to update the param list & member info.
        !           180:        * Selection changes on a parameter and we have to
        !           181:        *  update the param info.
        !           182:        */
        !           183: #ifdef WIN32
        !           184:   #define wParamX LOWORD(wParam)
        !           185:   #define notifyMsg HIWORD(wParam)
        !           186: #else
        !           187:   #define wParamX wParam
        !           188:   #define notifyMsg HIWORD(lParam)
        !           189: #endif
        !           190:       switch(wParamX){
        !           191:       case IDC_TYPELIST:
        !           192:         if(notifyMsg == LBN_SELCHANGE){
        !           193:           dwIndex = SendDlgItemMessage(hwnd, IDC_TYPELIST, LB_GETCURSEL, 0, 0L);
        !           194:          SetSelectedType(dwIndex);
        !           195:        }
        !           196:        break;
        !           197:       case IDC_MEMBERLIST:
        !           198:         if(notifyMsg == LBN_SELCHANGE){
        !           199:           dwIndex = SendDlgItemMessage(hwnd, IDC_MEMBERLIST, LB_GETCURSEL,0,0L);
        !           200:          SetSelectedMember(dwIndex);
        !           201:        }
        !           202:         break;
        !           203:       case IDC_PARAMLIST:
        !           204:         if(notifyMsg == LBN_SELCHANGE){
        !           205:           dwIndex = SendDlgItemMessage(hwnd, IDC_PARAMLIST, LB_GETCURSEL, 0,0L);
        !           206:          SetSelectedParam(dwIndex);
        !           207:        }
        !           208:        break;
        !           209:       }
        !           210:       return 0;
        !           211: 
        !           212:     case WM_DESTROY:
        !           213:       PostQuitMessage(0);
        !           214:       return 0 ;
        !           215:     }
        !           216:     return DefWindowProc (hwnd, message, wParam, lParam) ;
        !           217: }
        !           218: 
        !           219: 
        !           220: void OpenTypeLib (char FAR *sztlib)
        !           221: {                                     
        !           222:     UINT utypeinfoCount, i;
        !           223:     BSTR bstrName;
        !           224:     TLIBATTR FAR* ptlibattr;
        !           225:        
        !           226:     /* load the type library */
        !           227:     CHECKRESULT(LoadTypeLib(sztlib, &g_ptlib));
        !           228: 
        !           229:     /* get library attributes for the fun of it */
        !           230:     CHECKRESULT(g_ptlib->GetLibAttr(&ptlibattr));
        !           231: 
        !           232:     /* release library attributes */
        !           233:     g_ptlib->ReleaseTLibAttr(ptlibattr);
        !           234: 
        !           235:     /* Now add each of the names to the type list */
        !           236:     utypeinfoCount = g_ptlib->GetTypeInfoCount();
        !           237:     for(i = 0; i < utypeinfoCount; i++){
        !           238:       CHECKRESULT(g_ptlib->GetDocumentation(i, &bstrName, NULL, NULL, NULL));  
        !           239:       Assert(bstrName);
        !           240:       SendDlgItemMessage(g_hwndMain, IDC_TYPELIST, LB_ADDSTRING, 0, (LPARAM)bstrName);
        !           241:       SysFreeString(bstrName);
        !           242:     }
        !           243: }
        !           244: 
        !           245: /*
        !           246:  * SetSelectedType
        !           247:  * 
        !           248:  * When the user changes the selection of a type, this function updates the
        !           249:  * dialog by changing the member list and the help for the type. It also sets
        !           250:  * g_ptinfoCur to refer to the typeinfo.
        !           251:  */
        !           252: void SetSelectedType (DWORD dwIndex)
        !           253: {
        !           254:     BSTR bstrDoc;
        !           255:     LPSTR szData;
        !           256:     char szBuf[40];
        !           257:     HRESULT hresult;
        !           258:     DWORD dwHelpContext;
        !           259: 
        !           260:     if(g_ptinfoCur != NULL){
        !           261:       g_ptinfoCur->ReleaseTypeAttr(g_ptypeattrCur);
        !           262:       g_ptinfoCur->Release();
        !           263:     }
        !           264: 
        !           265:     /* Clear out the member list */
        !           266:     SendDlgItemMessage(g_hwndMain, IDC_MEMBERLIST, LB_RESETCONTENT,0,0L);
        !           267:     if(dwIndex != LB_ERR)
        !           268:     {
        !           269:       /* Note that the index in the list box is conveniently the
        !           270:        * same as the one to pass to GetTypeInfo.
        !           271:        */
        !           272:            
        !           273:       CHECKRESULT(g_ptlib->GetTypeInfo((UINT) dwIndex, &g_ptinfoCur));
        !           274:       CHECKRESULT(g_ptinfoCur->GetTypeAttr(&g_ptypeattrCur));
        !           275:                                  
        !           276:       // TypeKind
        !           277:       szData = g_rgszTKind[g_ptypeattrCur->typekind];
        !           278:       SendDlgItemMessage(g_hwndMain, IDC_TYPEKIND, WM_SETTEXT, 0, (LPARAM)szData);
        !           279: 
        !           280:       // GUID
        !           281:       hresult = StringFromCLSID(g_ptypeattrCur->guid, &szData);
        !           282:       if(hresult != NOERROR)
        !           283:        szData = "error!";
        !           284:       SendDlgItemMessage(g_hwndMain, IDC_GUID, WM_SETTEXT, 0, (LPARAM)szData);
        !           285:       MemFree(szData);
        !           286: 
        !           287:       // Version
        !           288:       wsprintf(szBuf, "%u.%02u",
        !           289:        g_ptypeattrCur->wMajorVerNum, g_ptypeattrCur->wMinorVerNum);
        !           290:       SendDlgItemMessage(
        !           291:        g_hwndMain, IDC_VERSION, WM_SETTEXT, 0, (LPARAM)(LPSTR)szBuf);
        !           292:     
        !           293:     
        !           294:       CHECKRESULT(
        !           295:        g_ptlib->GetDocumentation(
        !           296:          (UINT)dwIndex, NULL, &bstrDoc, &dwHelpContext, NULL));
        !           297: 
        !           298:       // Help Context
        !           299:       _ltoa((long)dwHelpContext, szBuf, 10);
        !           300:       SendDlgItemMessage(
        !           301:        g_hwndMain, IDC_HELPCONTEXT, WM_SETTEXT, 0, (LPARAM)(LPSTR)szBuf);
        !           302: 
        !           303:       // Documentation string
        !           304:       szData = (bstrDoc != NULL) ? (LPSTR)bstrDoc : "<none>";
        !           305:       SendDlgItemMessage(g_hwndMain, IDC_HELP, WM_SETTEXT, 0, (LPARAM)szData);
        !           306:       SysFreeString(bstrDoc);
        !           307:     
        !           308:       FillMemberList(g_ptinfoCur, g_ptypeattrCur, GetDlgItem(g_hwndMain, IDC_MEMBERLIST)); 
        !           309:     }
        !           310:     else /* no item is selected -- NULL out the pointers */
        !           311:     {
        !           312:       g_ptinfoCur = NULL;
        !           313:       g_ptypeattrCur = NULL;
        !           314:     }
        !           315: 
        !           316:     SendDlgItemMessage(g_hwndMain, IDC_PARAMLIST, LB_RESETCONTENT, 0, 0L);
        !           317: }
        !           318: 
        !           319: /*
        !           320:  * FillMemberList.
        !           321:  *
        !           322:  * Sets the current typeinfo to the typeinfo indexed by dwIndex, and then
        !           323:  * fills in the list box with the members of the type.
        !           324:  */
        !           325:  
        !           326: void
        !           327: FillMemberList(
        !           328:     ITypeInfo FAR *ptypeinfo,
        !           329:     TYPEATTR FAR *ptypeattr,
        !           330:     HWND hwndMemberList)
        !           331: {
        !           332:     MEMBERID memid; 
        !           333:     BSTR bstrName;
        !           334:     UINT i;
        !           335:     FUNCDESC FAR *pfuncdesc;
        !           336:     VARDESC  FAR *pvardesc;
        !           337:        
        !           338:     /* Now add all of the functions and all of the vars.
        !           339:      * This is somewhat roundabout.
        !           340:      * For each one, we need to get the funcdesc, or the vardesc.
        !           341:      * From that we get the MEMBERID, and finally can get to the name.
        !           342:      */
        !           343:     for(i = 0; i < ptypeattr->cFuncs; i++){
        !           344:       CHECKRESULT(ptypeinfo->GetFuncDesc(i, &pfuncdesc));
        !           345:       memid = pfuncdesc->memid;
        !           346:       CHECKRESULT(ptypeinfo->GetDocumentation(memid, &bstrName, NULL, NULL, NULL));
        !           347:       ptypeinfo->ReleaseFuncDesc(pfuncdesc);
        !           348:       pfuncdesc = NULL;
        !           349:            
        !           350:       Assert(bstrName);                                
        !           351:       SendMessage(hwndMemberList, LB_ADDSTRING, 0, (LPARAM) bstrName);
        !           352:       SysFreeString(bstrName);
        !           353:     }
        !           354:                                    
        !           355:     for(i = 0; i < ptypeattr->cVars; i++)
        !           356:     {
        !           357:       CHECKRESULT(ptypeinfo->GetVarDesc(i, &pvardesc));
        !           358:       memid = pvardesc->memid;
        !           359:       CHECKRESULT(ptypeinfo->GetDocumentation(memid, &bstrName, NULL, NULL, NULL));
        !           360:       ptypeinfo->ReleaseVarDesc(pvardesc);
        !           361:       pvardesc = NULL;
        !           362:                                        
        !           363:       Assert(bstrName);
        !           364:       SendMessage(hwndMemberList, LB_ADDSTRING, 0, (LPARAM) bstrName);
        !           365:       SysFreeString(bstrName);
        !           366:     }
        !           367: }
        !           368: 
        !           369: /*
        !           370:  * SetSelectedMember
        !           371:  *
        !           372:  * When a member of a type is selected, update the help to be the help of the member, and
        !           373:  * if the member is a function update the parameter list to reflect that it is a function.
        !           374:  *
        !           375:  */
        !           376:  
        !           377: void SetSelectedMember(DWORD dwIndex)
        !           378: {
        !           379:     MEMBERID memid;
        !           380:     HWND hwndParamList;
        !           381: 
        !           382:     /* In any case, we'll need to clear out the parameter list. */
        !           383:     hwndParamList = GetDlgItem(g_hwndMain, IDC_PARAMLIST);
        !           384:     SendMessage(hwndParamList, LB_RESETCONTENT, 0, 0L); 
        !           385:        
        !           386:     if (dwIndex == LB_ERR)
        !           387:        return;
        !           388:                
        !           389:     /* if this is a function, fill the param list, otherwise just fill
        !           390:      * in the item info.
        !           391:      */
        !           392:     if(dwIndex < g_ptypeattrCur->cFuncs){
        !           393:       FUNCDESC FAR *pfuncdesc;
        !           394:       USHORT i;
        !           395:       UINT cNames;
        !           396:       const UINT MAX_NAMES = 40;
        !           397:       BSTR rgNames[MAX_NAMES];
        !           398: 
        !           399:       CHECKRESULT(g_ptinfoCur->GetFuncDesc((UINT) dwIndex, &pfuncdesc));
        !           400:       memid = pfuncdesc->memid;
        !           401:       UpdateMemberInfo(memid);
        !           402:     
        !           403:       CHECKRESULT(g_ptinfoCur->GetNames(memid, rgNames, MAX_NAMES,&cNames));
        !           404:       for(i = 1; i < cNames; i++){
        !           405:        Assert(rgNames[i])
        !           406:        SendMessage(hwndParamList, LB_ADDSTRING, 0, (LPARAM) rgNames[i]);
        !           407:        SysFreeString(rgNames[i]);
        !           408:       }
        !           409:       Assert(rgNames[0]);                
        !           410:       SysFreeString(rgNames[0]);
        !           411:       g_ptinfoCur->ReleaseFuncDesc(pfuncdesc);
        !           412:     }
        !           413:     else
        !           414:     {
        !           415:       VARDESC FAR *pvardesc;
        !           416: 
        !           417:       CHECKRESULT(
        !           418:         g_ptinfoCur->GetVarDesc(
        !           419:          (UINT)(dwIndex - g_ptypeattrCur->cFuncs), &pvardesc));
        !           420:       memid = pvardesc->memid;
        !           421:       UpdateMemberInfo(memid);
        !           422:       g_ptinfoCur->ReleaseVarDesc(pvardesc);
        !           423:     }
        !           424: 
        !           425: }
        !           426: 
        !           427: 
        !           428: /* sets fields on the dialog (such as help string and help context) from
        !           429:    the type information.
        !           430: */
        !           431: void
        !           432: UpdateMemberInfo(MEMBERID memid)                   
        !           433: {
        !           434:     BSTR bstrDoc;
        !           435:     LPSTR szData;
        !           436:     DWORD dwHelpContext;
        !           437:     char szBuf[40];                    
        !           438: 
        !           439:     /* get the member information */
        !           440:     CHECKRESULT(g_ptinfoCur->GetDocumentation(memid, NULL, &bstrDoc, &dwHelpContext, NULL));
        !           441: 
        !           442:     /* update the help string displayed in the dialog */
        !           443:     if (bstrDoc)
        !           444:       szData = (LPSTR)bstrDoc;
        !           445:     else /* no help string for this item */
        !           446:       szData = "<none>";
        !           447: 
        !           448:     SendDlgItemMessage(g_hwndMain, IDC_HELP, WM_SETTEXT, 0, (LPARAM)szData);
        !           449:     SysFreeString(bstrDoc);
        !           450:         
        !           451:     /* update the help context displayed in the dialog */
        !           452:     _ltoa((long)dwHelpContext, szBuf, 10);
        !           453:     SendDlgItemMessage(g_hwndMain, IDC_HELPCONTEXT, WM_SETTEXT, 0, (LPARAM)((LPSTR)szBuf));
        !           454:  }
        !           455: 
        !           456: /*
        !           457:  * SetSelectedParam
        !           458:  * 
        !           459:  * CONSIDER: Enhance to show parameter type information here.
        !           460:  */
        !           461: void SetSelectedParam(DWORD dwIndex)
        !           462: {
        !           463: }
        !           464: 
        !           465: void
        !           466: AssertFail(char FAR * szFile, WORD  lineNo)
        !           467: {
        !           468:     char szAssert[255];
        !           469:     int id;
        !           470: 
        !           471:     wsprintf(szAssert, "Assertion failed.  File %s, line %d.", szFile, lineNo);
        !           472: 
        !           473:     id = MessageBox(NULL, szAssert, "TiBrowse Assertion.  OK to continue, CANCEL to quit.", MB_OKCANCEL | MB_TASKMODAL);
        !           474:     if (id == IDCANCEL)
        !           475:         exit(1);
        !           476: }
        !           477: 
        !           478: void
        !           479: MethodError(HRESULT hresult)
        !           480: {
        !           481: 
        !           482:     /* CONSIDER: add code to figure out what specific error this is */
        !           483: 
        !           484:     MessageBox(NULL, "Error returned from TYPELIB.DLL", g_szAppName, MB_OK);
        !           485: 
        !           486:     Cleanup();
        !           487: 
        !           488:     exit(1);
        !           489: }
        !           490: 
        !           491: /* free using the task allocator */
        !           492: void
        !           493: MemFree(void FAR* pv)
        !           494: {
        !           495:     HRESULT hresult;
        !           496:     IMalloc FAR* pmalloc;
        !           497: 
        !           498:     hresult = CoGetMalloc(MEMCTX_TASK, &pmalloc);
        !           499: 
        !           500:     if(hresult != NOERROR){
        !           501:       MessageBox(NULL, "error accessing task allocator", g_szAppName, MB_OK);
        !           502:       return;
        !           503:     }
        !           504: 
        !           505:     pmalloc->Free(pv);
        !           506:     pmalloc->Release();
        !           507: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.