Mega Code Archive

 
Categories / Delphi / Examples
 

How to develop a TLB Browser

Title: How to develop a TLB Browser? Question: How to see the interfaces and methods supported by a COM Dll? Answer: {************************************************************************} { } { TLB Viewer } { Author: Tomy Chacko } { } {************************************************************************} // Here's the sample code as it is... No optimization is done on this // code. unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Buttons, ActiveX, ComCtrls; type TForm1 = class(TForm) BitBtn1: TBitBtn; tvObjectBrowser: TTreeView; lvParams: TListView; procedure tvObjectBrowserChange(Sender: TObject; Node: TTreeNode); procedure BitBtn1Click(Sender: TObject); procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); private { Private declarations } public { Public declarations } TypeLib: ITypeLib; TypeInfo: ITypeInfo; m_sTLBFileName: WideString; slFunc_Params: TStringList; procedure LoadTLBDetails; procedure LoadFuncParams; end; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.LoadTLBDetails; var iCtr, iOutNames: Integer; iFuncCnt, iParamCnt: Integer; sName, sDocStr, sHelpFile: WideString; iHelpCont: LongInt; wType: DWord; trServer, trObject, trMethod: TTreeNode; sFileName: WideString; strNames: TBStrList; strParamType, strDefVal: String; sObjName, sFuncName: String; ptrFuncDesc: PFuncDesc; ptrVarDesc: PVarDesc; ptrTypeAttr: PTypeAttr; function GetDLLFile: String; var dlgOpen: TOpenDialog; begin try dlgOpen := TOpenDialog.Create(Self); dlgOpen.Filter := 'Type Library|*.DLL'; dlgOpen.InitialDir := 'C:\Tomy'; if dlgOpen.Execute then Result := dlgOpen.FileName; finally FreeAndNil(dlgOpen); end; end; begin try try tvObjectBrowser.OnChange := nil; tvObjectBrowser.Items.Clear; m_sTLBFileName := GetDLLFile; sFileName := ExtractFileName(m_sTLBFileName); sFileName := Copy(sFileName, 1, Pos('.', sFileName) - 1); LoadTypeLibEx(PWideChar(m_sTLBFileName), REGKIND_REGISTER, TypeLib); trServer := tvObjectBrowser.Items.AddChild(nil, sFileName); trServer.ImageIndex := 0; trServer.SelectedIndex := 0; for iCtr := 0 to TypeLib.GetTypeInfoCount - 1 do begin TypeLib.GetTypeInfoType(iCtr, wType); TypeLib.GetDocumentation(iCtr, @sName, @sDocStr, @iHelpCont, @sHelpFile); TypeLib.GetTypeInfo(iCtr, TypeInfo); TypeInfo.GetTypeAttr(ptrTypeAttr); trObject := tvObjectBrowser.Items.AddChild(trServer, sName); sObjName := sName; if wType = TKIND_DISPATCH then begin trObject.ImageIndex := 1; trObject.SelectedIndex := 1; end else if wType = TKIND_COCLASS then begin trObject.ImageIndex := 2; trObject.SelectedIndex := 2; end else if wType = TKIND_RECORD then begin trObject.ImageIndex := 3; trObject.SelectedIndex := 3; end else if wType = TKIND_ENUM then begin trObject.ImageIndex := 21; trObject.SelectedIndex := 21; end; if wType = TKIND_RECORD then begin for iFuncCnt := 0 to ptrTypeAttr.cVars - 1 do begin TypeInfo.GetVarDesc(iFuncCnt, ptrVarDesc); TypeInfo.GetDocumentation(ptrVarDesc.memid, @sName, @sDocStr, @iHelpCont, @sHelpFile); sFuncName := sName; trMethod := tvObjectBrowser.Items.AddChild(trObject, sFuncName); trMethod.ImageIndex := 17; trMethod.SelectedIndex := 17; end; end; if wType = TKIND_ENUM then begin for iFuncCnt := 0 to ptrTypeAttr.cVars - 1 do begin TypeInfo.GetVarDesc(iFuncCnt, ptrVarDesc); TypeInfo.GetDocumentation(ptrVarDesc.memid, @sName, @sDocStr, @iHelpCont, @sHelpFile); sFuncName := sName; trMethod := tvObjectBrowser.Items.AddChild(trObject, sFuncName); trMethod.ImageIndex := 17; trMethod.SelectedIndex := 17; end; end; if wType = TKIND_DISPATCH then begin for iFuncCnt := 0 to ptrTypeAttr.cFuncs - 1 do begin TypeInfo.GetFuncDesc(iFuncCnt, ptrFuncDesc); TypeInfo.GetDocumentation(ptrFuncDesc.memid, @sName, @sDocStr, @iHelpCont, @sHelpFile); sFuncName := sName; trMethod := tvObjectBrowser.Items.AddChild(trObject, sFuncName); trMethod.ImageIndex := 7; trMethod.SelectedIndex := 8; if ptrFuncDesc.wFuncFlags = FUNC_VIRTUAL then begin TypeInfo.GetNames(ptrFuncDesc.memid, @strNames, ptrFuncDesc.cParams + 1, iOutNames); sFuncName := strNames[0]; for iParamCnt := 0 to ptrFuncDesc.cParams + 1 do begin sName := strNames[iParamCnt]; if (iParamCnt 0) and (iParamCnt begin slFunc_Params.Add(Format('%-50s%-50s%-50s%-25s%-25s', [sObjName, sFuncName, sName, strParamType, strDefVal])); end else if iParamCnt ptrFuncDesc.cParams then begin slFunc_Params.Add(Format('%-50s%-50s%-50s%-25s', [sObjName, sFuncName, 'Result', strParamType])); end; strNames[iParamCnt] := nil; end; end; TypeInfo.ReleaseFuncDesc(ptrFuncDesc); end; end; TypeInfo.ReleaseTypeAttr(ptrTypeAttr); end; tvObjectBrowser.OnChange := tvObjectBrowserChange; finally end; except on E: Exception do begin Showmessage(E.Message); end; end; end; procedure TForm1.tvObjectBrowserChange(Sender: TObject; Node: TTreeNode); begin LoadFuncParams; end; procedure TForm1.LoadFuncParams; var iCtr: Integer; sObjName, sFuncName: String; sObjName1, sFuncName1: String; begin lvParams.Items.Clear; if tvObjectBrowser.Selected.HasChildren then Exit; sObjName := tvObjectBrowser.Selected.Parent.Text; sFuncName := tvObjectBrowser.Selected.Text; for iCtr := 0 to slFunc_Params.Count - 1 do begin sObjName1 := Trim(Copy(slFunc_Params.Strings[iCtr], 1, 50)); sFuncName1 := Trim(Copy(slFunc_Params.Strings[iCtr], 51, 50)); if (sObjName = sObjName1) and (sFuncName = sFuncName1) then begin lvParams.Items.Add; lvParams.Items[lvParams.Items.Count - 1].Caption := Trim(Copy(slFunc_Params.Strings[iCtr], 101, 50)); lvParams.Items[lvParams.Items.Count - 1].SubItems.Add(Trim(Copy(slFunc_Params.Strings[iCtr], 151, 25))); lvParams.Items[lvParams.Items.Count - 1].SubItems.Add(Trim(Copy(slFunc_Params.Strings[iCtr], 176, 25))); end; end; end; procedure TForm1.BitBtn1Click(Sender: TObject); begin LoadTLBDetails; end; procedure TForm1.FormCreate(Sender: TObject); begin slFunc_Params := TStringList.Create; end; procedure TForm1.FormDestroy(Sender: TObject); begin if Assigned(slFunc_Params) then FreeAndNil(slFunc_Params); end; end.