123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243 |
- import win32ui
- import win32con
- import win32api
- import commctrl
- import pythoncom
- from pywin.mfc import dialog
- class TLBrowserException(Exception):
- "TypeLib browser internal error"
- error = TLBrowserException
- FRAMEDLG_STD = win32con.WS_CAPTION | win32con.WS_SYSMENU
- SS_STD = win32con.WS_CHILD | win32con.WS_VISIBLE
- BS_STD = SS_STD | win32con.WS_TABSTOP
- ES_STD = BS_STD | win32con.WS_BORDER
- LBS_STD = ES_STD | win32con.LBS_NOTIFY | win32con.LBS_NOINTEGRALHEIGHT | win32con.WS_VSCROLL
- CBS_STD = ES_STD | win32con.CBS_NOINTEGRALHEIGHT | win32con.WS_VSCROLL
- typekindmap = {
- pythoncom.TKIND_ENUM : 'Enumeration',
- pythoncom.TKIND_RECORD : 'Record',
- pythoncom.TKIND_MODULE : 'Module',
- pythoncom.TKIND_INTERFACE : 'Interface',
- pythoncom.TKIND_DISPATCH : 'Dispatch',
- pythoncom.TKIND_COCLASS : 'CoClass',
- pythoncom.TKIND_ALIAS : 'Alias',
- pythoncom.TKIND_UNION : 'Union'
- }
- TypeBrowseDialog_Parent=dialog.Dialog
- class TypeBrowseDialog(TypeBrowseDialog_Parent):
- "Browse a type library"
- IDC_TYPELIST = 1000
- IDC_MEMBERLIST = 1001
- IDC_PARAMLIST = 1002
- IDC_LISTVIEW = 1003
- def __init__(self, typefile = None):
- TypeBrowseDialog_Parent.__init__(self, self.GetTemplate())
- try:
- if typefile:
- self.tlb = pythoncom.LoadTypeLib(typefile)
- else:
- self.tlb = None
- except pythoncom.ole_error:
- self.MessageBox("The file does not contain type information")
- self.tlb = None
- self.HookCommand(self.CmdTypeListbox, self.IDC_TYPELIST)
- self.HookCommand(self.CmdMemberListbox, self.IDC_MEMBERLIST)
- def OnAttachedObjectDeath(self):
- self.tlb = None
- self.typeinfo = None
- self.attr = None
- return TypeBrowseDialog_Parent.OnAttachedObjectDeath(self)
- def _SetupMenu(self):
- menu = win32ui.CreateMenu()
- flags=win32con.MF_STRING|win32con.MF_ENABLED
- menu.AppendMenu(flags, win32ui.ID_FILE_OPEN, "&Open...")
- menu.AppendMenu(flags, win32con.IDCANCEL, "&Close")
- mainMenu = win32ui.CreateMenu()
- mainMenu.AppendMenu(flags|win32con.MF_POPUP, menu.GetHandle(), "&File")
- self.SetMenu(mainMenu)
- self.HookCommand(self.OnFileOpen,win32ui.ID_FILE_OPEN)
- def OnFileOpen(self, id, code):
- openFlags = win32con.OFN_OVERWRITEPROMPT | win32con.OFN_FILEMUSTEXIST
- fspec = "Type Libraries (*.tlb, *.olb)|*.tlb;*.olb|OCX Files (*.ocx)|*.ocx|DLL's (*.dll)|*.dll|All Files (*.*)|*.*||"
- dlg = win32ui.CreateFileDialog(1, None, None, openFlags, fspec)
- if dlg.DoModal() == win32con.IDOK:
- try:
- self.tlb = pythoncom.LoadTypeLib(dlg.GetPathName())
- except pythoncom.ole_error:
- self.MessageBox("The file does not contain type information")
- self.tlb = None
- self._SetupTLB()
- def OnInitDialog(self):
- self._SetupMenu()
- self.typelb = self.GetDlgItem(self.IDC_TYPELIST)
- self.memberlb = self.GetDlgItem(self.IDC_MEMBERLIST)
- self.paramlb = self.GetDlgItem(self.IDC_PARAMLIST)
- self.listview = self.GetDlgItem(self.IDC_LISTVIEW)
- # Setup the listview columns
- itemDetails = (commctrl.LVCFMT_LEFT, 100, "Item", 0)
- self.listview.InsertColumn(0, itemDetails)
- itemDetails = (commctrl.LVCFMT_LEFT, 1024, "Details", 0)
- self.listview.InsertColumn(1, itemDetails)
- if self.tlb is None:
- self.OnFileOpen(None,None)
- else:
- self._SetupTLB()
- return TypeBrowseDialog_Parent.OnInitDialog(self)
- def _SetupTLB(self):
- self.typelb.ResetContent()
- self.memberlb.ResetContent()
- self.paramlb.ResetContent()
- self.typeinfo = None
- self.attr = None
- if self.tlb is None: return
- n = self.tlb.GetTypeInfoCount()
- for i in range(n):
- self.typelb.AddString(self.tlb.GetDocumentation(i)[0])
- def _SetListviewTextItems(self, items):
- self.listview.DeleteAllItems()
- index = -1
- for item in items:
- index = self.listview.InsertItem(index+1,item[0])
- data = item[1]
- if data is None: data = ""
- self.listview.SetItemText(index, 1, data)
- def SetupAllInfoTypes(self):
- infos = self._GetMainInfoTypes() + self._GetMethodInfoTypes()
- self._SetListviewTextItems(infos)
- def _GetMainInfoTypes(self):
- pos = self.typelb.GetCurSel()
- if pos<0: return []
- docinfo = self.tlb.GetDocumentation(pos)
- infos = [('GUID', str(self.attr[0]))]
- infos.append(('Help File', docinfo[3]))
- infos.append(('Help Context', str(docinfo[2])))
- try:
- infos.append(('Type Kind', typekindmap[self.tlb.GetTypeInfoType(pos)]))
- except:
- pass
- info = self.tlb.GetTypeInfo(pos)
- attr = info.GetTypeAttr()
- infos.append(('Attributes', str(attr)))
- for j in range(attr[8]):
- flags = info.GetImplTypeFlags(j)
- refInfo = info.GetRefTypeInfo(info.GetRefTypeOfImplType(j))
- doc = refInfo.GetDocumentation(-1)
- attr = refInfo.GetTypeAttr()
- typeKind = attr[5]
- typeFlags = attr[11]
- desc = doc[0]
- desc = desc + ", Flags=0x%x, typeKind=0x%x, typeFlags=0x%x" % (flags, typeKind, typeFlags)
- if flags & pythoncom.IMPLTYPEFLAG_FSOURCE:
- desc = desc + "(Source)"
- infos.append( ('Implements', desc))
- return infos
- def _GetMethodInfoTypes(self):
- pos = self.memberlb.GetCurSel()
- if pos<0: return []
- realPos, isMethod = self._GetRealMemberPos(pos)
- ret = []
- if isMethod:
- funcDesc = self.typeinfo.GetFuncDesc(realPos)
- id = funcDesc[0]
- ret.append(("Func Desc", str(funcDesc)))
- else:
- id = self.typeinfo.GetVarDesc(realPos)[0]
- docinfo = self.typeinfo.GetDocumentation(id)
- ret.append(('Help String', docinfo[1]))
- ret.append(('Help Context', str(docinfo[2])))
- return ret
- def CmdTypeListbox(self, id, code):
- if code == win32con.LBN_SELCHANGE:
- pos = self.typelb.GetCurSel()
- if pos >= 0:
- self.memberlb.ResetContent()
- self.typeinfo = self.tlb.GetTypeInfo(pos)
- self.attr = self.typeinfo.GetTypeAttr()
- for i in range(self.attr[7]):
- id = self.typeinfo.GetVarDesc(i)[0]
- self.memberlb.AddString(self.typeinfo.GetNames(id)[0])
- for i in range(self.attr[6]):
- id = self.typeinfo.GetFuncDesc(i)[0]
- self.memberlb.AddString(self.typeinfo.GetNames(id)[0])
- self.SetupAllInfoTypes()
- return 1
- def _GetRealMemberPos(self, pos):
- pos = self.memberlb.GetCurSel()
- if pos >= self.attr[7]:
- return pos - self.attr[7], 1
- elif pos >= 0:
- return pos, 0
- else:
- raise error("The position is not valid")
- def CmdMemberListbox(self, id, code):
- if code == win32con.LBN_SELCHANGE:
- self.paramlb.ResetContent()
- pos = self.memberlb.GetCurSel()
- realPos, isMethod = self._GetRealMemberPos(pos)
- if isMethod:
- id = self.typeinfo.GetFuncDesc(realPos)[0]
- names = self.typeinfo.GetNames(id)
- for i in range(len(names)):
- if i > 0:
- self.paramlb.AddString(names[i])
- self.SetupAllInfoTypes()
- return 1
- def GetTemplate(self):
- "Return the template used to create this dialog"
- w = 272 # Dialog width
- h = 192 # Dialog height
- style = FRAMEDLG_STD | win32con.WS_VISIBLE | win32con.DS_SETFONT | win32con.WS_MINIMIZEBOX
- template = [['Type Library Browser', (0, 0, w, h), style, None, (8, 'Helv')], ]
- template.append([130, "&Type", -1, (10, 10, 62, 9), SS_STD | win32con.SS_LEFT])
- template.append([131, None, self.IDC_TYPELIST, (10, 20, 80, 80), LBS_STD])
- template.append([130, "&Members", -1, (100, 10, 62, 9), SS_STD | win32con.SS_LEFT])
- template.append([131, None, self.IDC_MEMBERLIST, (100, 20, 80, 80), LBS_STD])
- template.append([130, "&Parameters", -1, (190, 10, 62, 9), SS_STD | win32con.SS_LEFT])
- template.append([131, None, self.IDC_PARAMLIST, (190, 20, 75, 80), LBS_STD])
- lvStyle = SS_STD | commctrl.LVS_REPORT | commctrl.LVS_AUTOARRANGE | commctrl.LVS_ALIGNLEFT | win32con.WS_BORDER | win32con.WS_TABSTOP
- template.append(["SysListView32", "", self.IDC_LISTVIEW, (10, 110, 255, 65), lvStyle])
- return template
- if __name__=='__main__':
- import sys
- fname = None
- try:
- fname = sys.argv[1]
- except:
- pass
- dlg = TypeBrowseDialog(fname)
- try:
- win32api.GetConsoleTitle()
- dlg.DoModal()
- except:
- dlg.CreateWindow(win32ui.GetMainFrame())
|