Annotation of mstools/ole20/samples/tibrowse/tibrowse.cpp, revision 1.1.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.