/*** *tibrowse.cpp * * Copyright (C) 1992-1994, Microsoft Corporation. All Rights Reserved. * Information Contained Herein Is Proprietary and Confidential. * *Purpose: * Type Information Browser * * *Implementation Notes: * *****************************************************************************/ #if defined(_MAC) #if defined(_PPCMAC) #pragma data_seg("_FAR_DATA") #pragma data_seg( ) #define MAXLONG 0x7fffffff #define EventHandlerProcPtr AEEventHandlerUPP #else //_PPCMAC #define GetMenuItemText(mApple,menuItem,daName) GetItem(mApple,menuItem,daName) #endif //_PPCMAC #endif //_MAC #include #include #include #include "tibrowse.h" #ifdef WIN32 #define SPRINTF swprintf #else #define SPRINTF sprintf #endif #if defined(UNICODE) #define TCHAR WCHAR #define TSTR(str) L##str #else #define TCHAR char #define TSTR(str) str #ifndef LPTSTR #define LPTSTR LPSTR #endif #endif #ifdef _MAC DECLARE_ROUTINE_DESC(UserItemUPP,DrawListbox); #endif #ifdef _MAC DialogPtr g_pdlg = NULL; ListHandle g_rghlist[IDC_PARAMLIST+1] = {NULL}; #else HWND g_hwnd; TCHAR g_szAppName[] = TSTR("TiBrowse"); #endif ITypeLib FAR *g_ptlib = NULL; ITypeInfo FAR *g_ptinfoCur = NULL; TYPEATTR FAR *g_ptattrCur = NULL; OLECHAR * g_rgszTKind[] = { OLESTR("Enum"), /* TKIND_ENUM */ OLESTR("Struct"), /* TKIND_RECORD */ OLESTR("Module"), /* TKIND_MODULE */ OLESTR("Interface"), /* TKIND_INTERFACE */ OLESTR("Dispinterface"), /* TKIND_DISPATCH */ OLESTR("Coclass"), /* TKIND_COCLASS */ OLESTR("Typedef"), /* TKIND_ALIAS */ OLESTR("Union"), /* TKIND_UNION */ }; // Set the text of the control identified by the given control id void XSetDlgItemText(int ctlid, OLECHAR FAR* psz) { #ifdef _MAC Rect rc; Handle h; short kind; char buf[255]; strcpy(buf, psz); GetDItem(g_pdlg, ctlid, &kind, &h, &rc); SetIText(h, c2pstr(buf)); #else #if defined(WIN32) && !defined(UNICODE) char bufA[256]; WideCharToMultiByte(CP_ACP, NULL, psz, -1, bufA, 256, NULL, NULL); SendDlgItemMessage(g_hwnd, ctlid, WM_SETTEXT, 0, (LPARAM)&bufA); #else SendDlgItemMessage(g_hwnd, ctlid, WM_SETTEXT, 0, (LPARAM)psz); #endif #endif } // Clear the listbox identified by the given control id void XClrDlgItemList(int ctlid) { #ifdef _MAC LDelRow(0, 0, g_rghlist[ctlid]); // delete everything #else SendMessage(GetDlgItem(g_hwnd, ctlid), LB_RESETCONTENT, 0, 0L); #endif } // Add the given string to the listbox identified by the given control id void XAddDlgItemList(int ctlid, OLECHAR FAR* psz) { #ifdef _MAC int row; Point pt; ListHandle hlist; hlist = g_rghlist[ctlid]; row = LAddRow(1, -1, hlist); pt.v = row, pt.h = 0; LSetCell(psz, strlen(psz), pt, hlist); #else #if defined(WIN32) && !defined(UNICODE) char bufA[256]; WideCharToMultiByte(CP_ACP, NULL, psz, -1, bufA, 256, NULL, NULL); SendDlgItemMessage(g_hwnd, ctlid, LB_ADDSTRING, 0, (LPARAM)&bufA); #else SendDlgItemMessage(g_hwnd, ctlid, LB_ADDSTRING, 0, (LPARAM)psz); #endif #endif } void Cleanup() { if(g_ptinfoCur != NULL){ if(g_ptattrCur != NULL) g_ptinfoCur->ReleaseTypeAttr(g_ptattrCur); g_ptinfoCur->Release(); g_ptinfoCur = NULL; } if(g_ptlib != NULL){ g_ptlib->Release(); g_ptlib = NULL; } } void Uninit() { OleUninitialize(); #ifdef _MAC #ifndef _PPCMAC UninitOleManager(); // clean up applet #endif #endif } void OpenTypeLib(OLECHAR FAR *sztlib) { unsigned int utypeinfoCount, i; BSTR bstrName; TLIBATTR FAR* ptlibattr; /* clear out globals */ Cleanup(); /* clear out listboxes */ XClrDlgItemList(IDC_TYPELIST); XClrDlgItemList(IDC_MEMBERLIST); XClrDlgItemList(IDC_PARAMLIST); /* load the type library */ CHECKRESULT(LoadTypeLib(sztlib, &g_ptlib)); /* get library attributes for the fun of it */ CHECKRESULT(g_ptlib->GetLibAttr(&ptlibattr)); /* release library attributes */ g_ptlib->ReleaseTLibAttr(ptlibattr); /* Now add each of the names to the type list */ utypeinfoCount = g_ptlib->GetTypeInfoCount(); for(i = 0; i < utypeinfoCount; i++){ CHECKRESULT(g_ptlib->GetDocumentation(i, &bstrName, NULL, NULL, NULL)); ASSERT(bstrName); XAddDlgItemList(IDC_TYPELIST, bstrName); SysFreeString(bstrName); } } #ifdef WIN32 void OpenTypeLib(char FAR *sztlib) { OLECHAR buf[MAX_PATH]; MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, sztlib, -1, buf, MAX_PATH); OpenTypeLib(buf); } #endif /*** *void SetSelectedType *Purpose: * When the user changes the selection of a type, this function updates the * dialog by changing the member list and the help for the type. It also sets * g_ptinfoCur to refer to the typeinfo. * *Entry: * dwIndex = * *Exit: * return value = None * ***********************************************************************/ void SetSelectedType(unsigned long dwIndex) { HRESULT hr; BSTR bstrDoc; OLECHAR FAR* psz; OLECHAR szBuf[40]; unsigned long dwHelpContext; TYPEKIND tkind; if(g_ptinfoCur != NULL){ g_ptinfoCur->ReleaseTypeAttr(g_ptattrCur); g_ptinfoCur->Release(); } /* Clear out the member list */ XClrDlgItemList(IDC_MEMBERLIST); if(g_ptlib == NULL) return; // Note: the index in the list box is conveniently the same as the // one to pass to GetTypeInfo/GetTypeInfoType // typeinfo type can be obtained without actually loading the typeinfo CHECKRESULT(g_ptlib->GetTypeInfoType((unsigned int)dwIndex, &tkind)); XSetDlgItemText(IDC_TYPEKIND, g_rgszTKind[tkind]); CHECKRESULT(g_ptlib->GetTypeInfo((unsigned int)dwIndex, &g_ptinfoCur)); CHECKRESULT(g_ptinfoCur->GetTypeAttr(&g_ptattrCur)); // GUID hr = StringFromCLSID(g_ptattrCur->guid, &psz); ASSERT(hr == NOERROR); XSetDlgItemText(IDC_GUID, psz); MemFree(psz); // Version SPRINTF(szBuf, OLESTR("%u.%02u"), g_ptattrCur->wMajorVerNum, g_ptattrCur->wMinorVerNum); XSetDlgItemText(IDC_VERSION, szBuf); CHECKRESULT( g_ptlib->GetDocumentation( (unsigned int)dwIndex, NULL, &bstrDoc, &dwHelpContext, NULL)); // Help Context SPRINTF(szBuf, OLESTR("%ld"), dwHelpContext); XSetDlgItemText(IDC_HELPCONTEXT, szBuf); // Documentation string psz = (bstrDoc != NULL) ? bstrDoc : OLESTR(""); XSetDlgItemText(IDC_HELPSTRING, psz); SysFreeString(bstrDoc); FillMemberList(g_ptinfoCur, g_ptattrCur, IDC_MEMBERLIST); XClrDlgItemList(IDC_PARAMLIST); } /*** *void FillMemberList *Purpose: * Sets the current typeinfo to the typeinfo indexed by dwIndex, and * then fills in the list box with the members of the type. * *Entry: * ptinfo = * ptypeattr = * *Exit: * return value = None * ***********************************************************************/ void FillMemberList( ITypeInfo FAR *ptinfo, TYPEATTR FAR *ptypeattr, int ctlid) { MEMBERID memid; BSTR bstrName; unsigned int i; FUNCDESC FAR *pfuncdesc; VARDESC FAR *pvardesc; /* Now add all of the functions and all of the vars. * This is somewhat roundabout. * For each one, we need to get the funcdesc, or the vardesc. * From that we get the MEMBERID, and finally can get to the name. */ for(i = 0; i < ptypeattr->cFuncs; i++){ CHECKRESULT(ptinfo->GetFuncDesc(i, &pfuncdesc)); memid = pfuncdesc->memid; CHECKRESULT(ptinfo->GetDocumentation(memid, &bstrName, NULL, NULL, NULL)); ptinfo->ReleaseFuncDesc(pfuncdesc); pfuncdesc = NULL; ASSERT(bstrName); XAddDlgItemList(ctlid, bstrName); SysFreeString(bstrName); } for(i = 0; i < ptypeattr->cVars; i++) { CHECKRESULT(ptinfo->GetVarDesc(i, &pvardesc)); memid = pvardesc->memid; CHECKRESULT(ptinfo->GetDocumentation(memid, &bstrName, NULL, NULL, NULL)); ptinfo->ReleaseVarDesc(pvardesc); pvardesc = NULL; ASSERT(bstrName); XAddDlgItemList(ctlid, bstrName); SysFreeString(bstrName); } } /*** *void SetSelectedMember *Purpose: * When a member of a type is selected, update the help to be the help * of the member, and if the member is a function update the parameter * list to reflect that it is a function. * *Entry: * dwIndex = * *Exit: * return value = None * ***********************************************************************/ void SetSelectedMember(unsigned long dwIndex) { MEMBERID memid; /* In any case, we'll need to clear out the parameter list. */ XClrDlgItemList(IDC_PARAMLIST); if(g_ptattrCur == NULL) return; /* if this is a function, fill the param list, otherwise just fill * in the item info. */ if(dwIndex < g_ptattrCur->cFuncs){ unsigned short i; unsigned int cNames; FUNCDESC FAR *pfuncdesc; const unsigned int MAX_NAMES = 40; BSTR rgNames[MAX_NAMES]; CHECKRESULT(g_ptinfoCur->GetFuncDesc((unsigned int) dwIndex, &pfuncdesc)); memid = pfuncdesc->memid; UpdateMemberInfo(memid); CHECKRESULT(g_ptinfoCur->GetNames(memid, rgNames, MAX_NAMES,&cNames)); for(i = 1; i < cNames; i++){ ASSERT(rgNames[i]) XAddDlgItemList(IDC_PARAMLIST, rgNames[i]); SysFreeString(rgNames[i]); } ASSERT(rgNames[0]); SysFreeString(rgNames[0]); g_ptinfoCur->ReleaseFuncDesc(pfuncdesc); } else { VARDESC FAR *pvardesc; CHECKRESULT( g_ptinfoCur->GetVarDesc( (unsigned int)(dwIndex - g_ptattrCur->cFuncs), &pvardesc)); memid = pvardesc->memid; UpdateMemberInfo(memid); g_ptinfoCur->ReleaseVarDesc(pvardesc); } } /*** *void UpdateMemberInfo *Purpose: * sets fields on the dialog (such as help string and help context) from * the type information. * *Entry: * memid = * *Exit: * return value = None * ***********************************************************************/ void UpdateMemberInfo(MEMBERID memid) { BSTR bstrDoc; OLECHAR buf[40]; unsigned long dwHelpContext; /* get the member information */ CHECKRESULT(g_ptinfoCur->GetDocumentation( memid, NULL, &bstrDoc, &dwHelpContext, NULL)); /* update the help string displayed in the dialog */ XSetDlgItemText(IDC_HELPSTRING, (bstrDoc != NULL) ? bstrDoc : OLESTR("")); SysFreeString(bstrDoc); /* update the help context displayed in the dialog */ SPRINTF(buf, OLESTR("%ld"), dwHelpContext); XSetDlgItemText(IDC_HELPCONTEXT, buf); } /*** *void SetSelectedParam *Purpose: * CONSIDER: Enhance to show parameter type information here. * *Entry: * dwIndex = * *Exit: * return value = None * ***********************************************************************/ void SetSelectedParam(unsigned long dwIndex) { } HRESULT GetFileName(BSTR FAR* pbstrFileName) { OLECHAR buf[1024]; BSTR bstrFileName; #ifdef _MAC int i; Point pt; long dirID; char *p, *q; SFReply sfr; SFTypeList sftl; short sRefNumReal; SetPt(&pt, 100, 100); //sftl[0] = 'OTLB'; sftl[0] = 0; // currently allow all file types SFGetFile(pt, NULL, NULL, -1, sftl, NULL, &sfr); if(!sfr.good) return ResultFromScode(E_FAIL); // translate sfr.vRefNum into a dirID { WDPBRec wdpbr; wdpbr.ioWDIndex = 0; wdpbr.ioVRefNum = sfr.vRefNum; wdpbr.ioWDVRefNum = 0; wdpbr.ioWDIndex = 0; wdpbr.ioWDProcID = 0; wdpbr.ioNamePtr = (StringPtr)buf; if(PBGetWDInfoSync (&wdpbr) != noErr) return ResultFromScode(E_FAIL); sRefNumReal = wdpbr.ioWDVRefNum; dirID = wdpbr.ioWDDirID; } { Str255 stDir; CInfoPBRec pb; DirInfo *pdirinfo = (DirInfo*)&pb; char rgchTemp[256]; // REVIEW: what should the size be? pdirinfo->ioNamePtr = stDir; pdirinfo->ioVRefNum = sRefNumReal; pdirinfo->ioDrParID = dirID; pdirinfo->ioFDirIndex = -1; // get info on a dir buf[0] = '\0'; // loop until we hit the root dir do{ pdirinfo->ioDrDirID = pdirinfo->ioDrParID; if(PBGetCatInfoSync (&pb) != noErr) return ResultFromScode(E_FAIL); strncpy(rgchTemp, (char*)stDir, 64); p2cstr((StringPtr)rgchTemp); strcat(rgchTemp, ":"); strcat(rgchTemp, buf); strcpy(buf, rgchTemp); }while(pdirinfo->ioDrDirID != fsRtDirID); } q = (char*)sfr.fName; i = (int)*q++; p = &buf[strlen(buf)]; while(i-->0) *p++ = *q++; *p = '\0'; if((bstrFileName = SysAllocString(buf)) == NULL) return ResultFromScode(E_OUTOFMEMORY); #else OPENFILENAME ofn; memset(&ofn, 0, sizeof(OPENFILENAME)); ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = g_hwnd; ofn.lpstrFile = (LPTSTR) &buf; ofn.nMaxFile = sizeof(buf); *buf = OLESTR('\0'); ofn.lpstrFilter = TSTR("Type Libraries\0*.tlb\0\0"); ofn.nFilterIndex = 1; ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_SHAREAWARE; if(GetOpenFileName(&ofn) == 0){ // REVIEW: we can probably do something smarter with this error DWORD dwerr = CommDlgExtendedError(); return ResultFromScode(E_FAIL); } #if defined(WIN32) && !defined(UNICODE) OLECHAR szFileW[_MAX_PATH]; MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, ofn.lpstrFile, -1, szFileW, _MAX_PATH); if((bstrFileName = SysAllocString(szFileW)) == NULL) return ResultFromScode(E_OUTOFMEMORY); #else if((bstrFileName = SysAllocString(ofn.lpstrFile)) == NULL) return ResultFromScode(E_OUTOFMEMORY); #endif #endif *pbstrFileName = bstrFileName; return NOERROR; } void AssertFail(char FAR* file, int line) { // Ansi Output for Assertion #ifdef UNICODE #define OUTPUTDEBUGSTRING OutputDebugStringA #define MESSAGEBOX MessageBoxA #else #define OUTPUTDEBUGSTRING OutputDebugString #define MESSAGEBOX MessageBox #endif char buf[128]; sprintf(buf, "Assertion failed: %s(%d)", file, line); #ifdef _MAC DebugStr(c2pstr(buf)); #else OUTPUTDEBUGSTRING(buf); if(MESSAGEBOX(NULL, buf, "TiBrowse Assertion. OK to continue, CANCEL to quit.", MB_OKCANCEL | MB_TASKMODAL) == IDCANCEL) exit(1); DebugBreak(); #endif } #ifdef _MAC /* { */ void Init(void); void EventLoop(void); void AdjustMenus(void); void DoEvent(EventRecord *pevent); void DoMenuCommand(long menuResult); void Quit(void); #ifndef _MSC_VER #ifndef ConstStr255Param #define ConstStr255Param StringPtr #endif #endif void Fatal(ConstStr255Param); Boolean IsAppWindow(WindowPtr window) { return (window == NULL) ? false : ((WindowPeek)window)->windowKind == userKind; } Boolean IsDAWindow(WindowPtr window) { return (window == NULL) ? false : (((WindowPeek)window)->windowKind < 0); } void main() { Init(); // ShowWindow(g_pdlg); // REVIEW: necessarry? EventLoop(); } void DoDialogEvent(EventRecord *pevent, short sItem) { Point pt; GrafPtr pport; ListHandle hlist; switch(sItem){ case IDC_TYPELIST: case IDC_MEMBERLIST: case IDC_PARAMLIST: if(pevent->what == mouseDown){ GetPort(&pport); SetPort(g_pdlg); GlobalToLocal(&pevent->where); hlist = g_rghlist[sItem]; LClick(pevent->where, pevent->modifiers, hlist); SetPt(&pt, 0, 0); if(LGetSelect(true, &pt, hlist)){ switch(sItem){ case IDC_TYPELIST: SetSelectedType(pt.v); break; case IDC_MEMBERLIST: SetSelectedMember(pt.v); break; case IDC_PARAMLIST: SetSelectedParam(pt.v); break; } } SetPort(pport); } break; } } void EventLoop() { short sItem; DialogPtr pdlg; EventRecord event; RgnHandle cursorRgn; cursorRgn = NewRgn(); while(1){ if(WaitNextEvent(everyEvent, &event, MAXLONG, cursorRgn)){ if (FrontWindow() != NULL && event.what != diskEvt && (event.what != keyDown || (event.modifiers & cmdKey) == 0) && IsDialogEvent(&event)) { if(DialogSelect(&event, &pdlg, &sItem)){ ASSERT(pdlg == g_pdlg); DoDialogEvent(&event, sItem); } }else{ DoEvent(&event); } } } } void DoEvent(EventRecord *pevent) { char key; short part; WindowPtr window; switch(pevent->what){ case mouseDown: part = FindWindow(pevent->where, &window); switch(part){ case inMenuBar: AdjustMenus(); DoMenuCommand(MenuSelect(pevent->where)); break; case inSysWindow: /* let the system handle the mouseDown */ SystemClick(pevent, window); break; case inContent: if(window != FrontWindow()){ SelectWindow(window); } break; case inDrag: DragWindow(window, pevent->where, &qd.screenBits.bounds); break; } break; case keyDown: case autoKey: /* check for menukey equivalents */ key = (char)(pevent->message & charCodeMask); if(pevent->modifiers & cmdKey){ /* Command key down */ if(pevent->what == keyDown){ /* enable/disable/check menu items properly */ AdjustMenus(); DoMenuCommand(MenuKey(key)); } } break; } } void Enable(MenuHandle hmenu, short sItem, Boolean fEnable) { if(fEnable) EnableItem(hmenu, sItem); else DisableItem(hmenu, sItem); } void AdjustMenus() { Boolean fIsDA; MenuHandle hmenu; fIsDA = IsDAWindow(FrontWindow()); /* we can allow desk accessories to be closed from the menu */ hmenu = GetMHandle(mFile); Enable(hmenu, iClose, fIsDA); hmenu = GetMHandle(mEdit); Enable(hmenu, iUndo, fIsDA); Enable(hmenu, iCut, fIsDA); Enable(hmenu, iCopy, fIsDA); Enable(hmenu, iPaste, fIsDA); Enable(hmenu, iClear, fIsDA); } void DoMenuCommand(long menuResult) { short menuID; /* the resource ID of the selected menu */ short menuItem; /* the item number of the selected menu */ Str255 daName; menuID = HiWord(menuResult); menuItem = LoWord(menuResult); switch(menuID){ case mApple: switch(menuItem){ case iAbout: /* bring up alert for About */ Alert(rAboutAlert, NULL); break; default: GetMenuItemText(GetMHandle(mApple), menuItem, daName); OpenDeskAcc(daName); break; } break; case mFile: switch(menuItem){ case iOpen: { BSTR bstrFileName; if(GetFileName(&bstrFileName) != NOERROR) { // REVIEW: shouldnt just bag out here Fatal((ConstStr255Param)"\pUnable to open Type Library"); } OpenTypeLib(bstrFileName); } break; case iQuit: Quit(); break; } break; case mEdit: SystemEdit(menuItem-1); break; } HiliteMenu(0); } extern "C" { #if defined(_MSC_VER) void pascal #else pascal void #endif DrawListbox(DialogPtr pdlg, short sItem) { Rect rc; Handle h; short kind; GrafPtr port; ListHandle hlist; ASSERT(sItem == IDC_TYPELIST || sItem == IDC_MEMBERLIST || sItem == IDC_PARAMLIST); GetPort(&port); SetPort(pdlg); hlist = g_rghlist[sItem]; LUpdate(pdlg->visRgn, hlist); GetDItem(pdlg, sItem, &kind, &h, &rc); InsetRect(&rc, -1, -1); FrameRect(&rc); SetPort(port); } } /*** *ListHandle CreateListBox(DialogPtr, int) *Purpose: * Create a listbox on the given dialog, associated with the given * control id. * *Entry: * pdlg = * ctlid = * *Exit: * return value = ListHandle * ***********************************************************************/ ListHandle CreateListbox(DialogPtr pdlg, int ctlid) { Handle h; short kind; Point ptCell; ListHandle hlist; Rect rcView, rcBounds; INIT_ROUTINE_DESC(NewUserItemProc,DrawListbox); GetDItem(pdlg, ctlid, &kind, &h, &rcView); SetDItem(pdlg, ctlid, kind, (Handle) ROUTINE_DESC(DrawListbox), &rcView); // make room for scroll bars rcView.right -= 15; // list is 1 wide SetRect(&rcBounds, 0, 0, 1, 0); SetPt(&ptCell, 0, 0); hlist = LNew( &rcView, &rcBounds, ptCell, 0, (WindowPtr)pdlg, true, false, false, true); ASSERT(hlist != NULL); (*hlist)->selFlags = lUseSense | lNoRect | lNoExtend | lOnlyOne; return hlist; } /*** *DialogPtr CreateDialog(void) *Purpose: * Create the TiBrowse dialog * *Entry: * None * *Exit: * return value = DialogPtr * ***********************************************************************/ DialogPtr CreateDialog() { int i; Point pt; DialogPtr pdlg; ListHandle hlist; static short rgctl[] = {IDC_TYPELIST, IDC_MEMBERLIST, IDC_PARAMLIST}; if((pdlg = GetNewDialog(rDlg, NULL, (WindowPtr)-1)) == NULL) return NULL; for(i = 0; i < DIM(rgctl); ++i){ g_rghlist[rgctl[i]] = CreateListbox(pdlg, rgctl[i]); } SetPt(&pt, 0, 0); for(i = 0; i < DIM(rgctl); ++i){ hlist = g_rghlist[rgctl[i]]; LSetSelect(true, pt, hlist); LDoDraw(true, hlist); } return pdlg; } void Init() { Handle menuBar; MaxApplZone(); InitGraf((Ptr)&qd.thePort); InitFonts(); InitWindows(); InitMenus(); TEInit(); InitDialogs(NULL); InitCursor(); FlushEvents(everyEvent, 0); #ifndef _PPCMAC if (InitOleManager(0) != NOERROR) Fatal((ConstStr255Param)"\pCould not initialize OLE Applet"); #endif if(OleInitialize(NULL) != NOERROR) Fatal((ConstStr255Param)"\pUnable to Initialize Ole"); if((menuBar = GetNewMBar(rMenuBar)) == NULL) Fatal((ConstStr255Param)"\pUnable to load menu bar"); SetMenuBar(menuBar); DisposHandle(menuBar); AddResMenu(GetMHandle(mApple), 'DRVR'); DrawMenuBar(); if((g_pdlg = CreateDialog()) == NULL) Fatal((ConstStr255Param)"\pUnable to create dialog"); } void Quit() { Cleanup(); Uninit(); ExitToShell(); } /* display fatal error alert, and exit */ void Fatal(ConstStr255Param msg) { SetCursor(&qd.arrow); ParamText(msg, (ConstStr255Param)"\p", (ConstStr255Param)"\p", (ConstStr255Param)"\p"); Alert(rUserAlert, nil); Quit(); } #else /* }{ */ long FAR PASCAL EXPORT WndProc (HWND, UINT, WPARAM, LPARAM) ; int PASCAL WinMain( HINSTANCE hinst, HINSTANCE hinstPrev, LPSTR lpszCmdLine, int nCmdShow) { MSG msg; WNDCLASS wndclass; if(!hinstPrev){ wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = DLGWINDOWEXTRA ; wndclass.hInstance = hinst ; wndclass.hIcon = LoadIcon (hinst, g_szAppName) ; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1) ; wndclass.lpszMenuName = NULL ; wndclass.lpszClassName = g_szAppName ; RegisterClass (&wndclass) ; } if(OleInitialize(NULL) != NOERROR){ MessageBox(NULL, TSTR("unable to initialize Ole"), g_szAppName, MB_OK); return 0; } g_hwnd = CreateDialog(hinst, g_szAppName, 0, NULL); if(*lpszCmdLine == '\0'){ BSTR bstrFileName; if(GetFileName(&bstrFileName) != NOERROR){ Cleanup(); Uninit(); exit(-1); } OpenTypeLib(bstrFileName); SysFreeString(bstrFileName); }else{ OpenTypeLib(lpszCmdLine); } ShowWindow(g_hwnd, nCmdShow); while(GetMessage (&msg, NULL, 0, 0)){ TranslateMessage (&msg); DispatchMessage (&msg); } Cleanup(); Uninit(); return msg.wParam; } long FAR PASCAL EXPORT WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { unsigned long dwIndex; switch(message){ case WM_COMMAND: /* We deal with the following events: * The selection changes on the type list and we have * to update the member list & type info. * The selection changes on the member list and we have * to update the param list & member info. * Selection changes on a parameter and we have to * update the param info. */ #ifdef WIN32 # define wParamX LOWORD(wParam) # define notifyMsg HIWORD(wParam) #else # define wParamX wParam # define notifyMsg HIWORD(lParam) #endif switch(wParamX){ case IDC_TYPELIST: if(notifyMsg == LBN_SELCHANGE){ dwIndex = SendDlgItemMessage(hwnd, IDC_TYPELIST, LB_GETCURSEL, 0, 0L); if(dwIndex != LB_ERR) SetSelectedType(dwIndex); } break; case IDC_MEMBERLIST: if(notifyMsg == LBN_SELCHANGE){ dwIndex = SendDlgItemMessage(hwnd, IDC_MEMBERLIST, LB_GETCURSEL,0,0L); if(dwIndex != LB_ERR) SetSelectedMember(dwIndex); } break; case IDC_PARAMLIST: if(notifyMsg == LBN_SELCHANGE){ dwIndex = SendDlgItemMessage(hwnd, IDC_PARAMLIST, LB_GETCURSEL, 0,0L); if(dwIndex != LB_ERR) SetSelectedParam(dwIndex); } break; } return 0; case WM_DESTROY: PostQuitMessage(0); return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; } #endif /* } */ void MethodError(HRESULT hresult) { /* CONSIDER: add code to figure out what specific error this is */ UNUSED(hresult); #ifdef _MAC Fatal((ConstStr255Param)"\pType Library"); #else MessageBox(NULL, TSTR("Error returned from TYPELIB.DLL"), g_szAppName, MB_OK); exit(1); #endif } /* free using the task allocator */ void MemFree(void FAR* pv) { HRESULT hresult; IMalloc FAR* pmalloc; hresult = CoGetMalloc(MEMCTX_TASK, &pmalloc); if(hresult != NOERROR){ #ifdef _MAC Fatal((ConstStr255Param)"\pError accessing task allocator"); #else MessageBox(NULL, TSTR("Error accessing task allocator"), g_szAppName, MB_OK); #endif return; } pmalloc->Free(pv); pmalloc->Release(); }