home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C Programming Starter Kit 2.0
/
SamsPublishing-CProgrammingStarterKit-v2.0-Win31.iso
/
bc45
/
oct_auto.pak
/
AUTOGEN.CPP
next >
Wrap
C/C++ Source or Header
|
1997-07-23
|
51KB
|
1,405 lines
//----------------------------------------------------------------------------
// ObjectConnections - (C) Copyright 1994 by Borland International
//
// This program reads type libraries (*.OLB; *.TLB) and emits C++ source files
// A typelib filename on the command line forces non-interactive operation.
// Normally generates .HXX and .CXX files for use by OCF automation controller
// A C++ compatible .HPP file can be generated using the entire type library
// by selecting the dialog box option, or by use of the command line options.
//----------------------------------------------------------------------------
#include <ocf/ocdefs.h> // TComRef
#include <osl/except.h> // TXBase
#include <olenls.h> // LANGIDFROMCLSID
#include <iostream.h>
#include <commdlg.h> // GetFileTitle
#include "autogen.rh"
//____________________________________________________________________________
//
// ITypeInfo and ITypeLib encapsulations
//____________________________________________________________________________
class TComRef<ITypeInfo> : public TComRefBase<ITypeInfo> {
public:
TComRef();
TComRef(ITypeInfo* iface);
TComRef(const TComRef<ITypeInfo>& i);
~TComRef();
ITypeInfo* operator =(ITypeInfo* iface);
TComRef<ITypeInfo>& operator =(const TComRef<ITypeInfo>& i);
ITypeInfo* operator->() {return I;}
operator ITypeInfo* far*();
void GetAttr();
void GetFuncDesc(unsigned int index);
void GetVarDesc( unsigned int index);
void GetDocumentation(MEMBERID memberid = MEMBERID_NIL);
TYPEATTR far* Attr;
FUNCDESC far* FuncDesc;
VARDESC far* VarDesc;
BSTR Name;
BSTR Doc;
private:
void ClearData();
};
inline void TComRef<ITypeInfo>::ClearData()
{
memset((char*)this + sizeof(TComRefBase<ITypeInfo>), 0,
sizeof(*this) - sizeof(TComRefBase<ITypeInfo>) );
};
TComRef<ITypeInfo>::TComRef() : TComRefBase<ITypeInfo>()
{
ClearData();
}
TComRef<ITypeInfo>::TComRef(ITypeInfo* i) : TComRefBase<ITypeInfo>(i)
{
ClearData();
}
TComRef<ITypeInfo>::TComRef(const TComRef<ITypeInfo>& i)
: TComRefBase<ITypeInfo>(i)
{
ClearData();
}
TComRef<ITypeInfo>::~TComRef()
{
if (Attr) I->ReleaseTypeAttr(Attr);
if (FuncDesc) I->ReleaseFuncDesc(FuncDesc);
if (VarDesc) I->ReleaseVarDesc(VarDesc);
::SysFreeString(Name);
::SysFreeString(Doc);
}
inline ITypeInfo*
TComRef<ITypeInfo>::operator =(ITypeInfo* iface)
{
TComRef<ITypeInfo>::~TComRef();
ClearData();
return I = iface;
}
inline TComRef<ITypeInfo>&
TComRef<ITypeInfo>::operator =(const TComRef<ITypeInfo>& i)
{
TComRef<ITypeInfo>::~TComRef();
ClearData();
I = i.I;
return *this;
}
inline
TComRef<ITypeInfo>::operator ITypeInfo* far*()
{
TComRef<ITypeInfo>::~TComRef();
ClearData();
return &I;
}
void TComRef<ITypeInfo>::GetDocumentation(MEMBERID memberid)
{
::SysFreeString(Name);
::SysFreeString(Doc);
OLECALL(I->GetDocumentation(memberid, &Name, &Doc, 0, 0),"TypeInfo::GetDoc");
}
void TComRef<ITypeInfo>::GetAttr()
{
if (Attr) I->ReleaseTypeAttr(Attr);
OLECALL(I->GetTypeAttr(&Attr),"TypeInfo::GetTypeAttr");
}
void TComRef<ITypeInfo>::GetFuncDesc(unsigned int index)
{
if (FuncDesc) I->ReleaseFuncDesc(FuncDesc);
OLECALL(I->GetFuncDesc(index, &FuncDesc),"TypeInfo::GetFuncDesc");
}
void TComRef<ITypeInfo>::GetVarDesc( unsigned int index)
{
if (VarDesc) I->ReleaseVarDesc(VarDesc);
OLECALL(I->GetVarDesc(index, &VarDesc),"TypeInfo::GetVarDesc");
}
class TComRef<ITypeLib> : public TComRefBase<ITypeLib> {
public:
TComRef();
TComRef(ITypeLib* iface);
TComRef(const TComRef<ITypeLib>& i);
~TComRef();
ITypeLib* operator =(ITypeLib* iface) {if(I)I->Release(); return I = iface;}
ITypeLib* operator =(const TComRef<ITypeLib>& i){if(I)I->Release(); return I=i.I;}
ITypeLib* operator->() {return I;}
void GetAttr();
void GetDocumentation(int index = -1);
TLIBATTR far* Attr;
BSTR Name;
BSTR Doc;
};
TComRef<ITypeLib>::TComRef() : TComRefBase<ITypeLib>(),
Name(0), Doc(0), Attr(0){}
TComRef<ITypeLib>::TComRef(ITypeLib* i) : TComRefBase<ITypeLib>(i),
Name(0), Doc(0), Attr(0){}
TComRef<ITypeLib>::TComRef(const TComRef<ITypeLib>& i) : TComRefBase<ITypeLib>(i),
Name(0), Doc(0), Attr(0){}
TComRef<ITypeLib>::~TComRef()
{
if (Attr) I->ReleaseTLibAttr(Attr);
::SysFreeString(Name);
::SysFreeString(Doc);
}
void TComRef<ITypeLib>::GetDocumentation(int index)
{
::SysFreeString(Name);
::SysFreeString(Doc);
OLECALL(I->GetDocumentation(index, &Name, &Doc, 0, 0),"TypeLib::GetDoc");
}
void TComRef<ITypeLib>::GetAttr()
{
if (Attr) I->ReleaseTLibAttr(Attr);
OLECALL(I->GetLibAttr(&Attr),"TypeLib::GetAttr");
}
//____________________________________________________________________________
//
// Error handling facility using local exception object
//____________________________________________________________________________
struct TLocalError { // local exception object for this program
TLocalError(const char* title, const char* message)
: Title(title), Message(message) {}
const char* Title;
const char* Message;
};
static void Error(const char* title, const char* message)
{
throw TLocalError(title,message);
}
static inline void ErrorIf(int error, const char* title, int resId)
{
if (error)
Error(title, (char*)resId);
}
static inline void ErrorIf(int error, int resId, const char* message)
{
if (error)
Error((char*)resId, message);
}
static inline void ErrorIf(int error, const char* title, const char* message)
{
if (error)
Error(title,message);
}
//____________________________________________________________________________
//
// ITypeInfo iterator, emits C++ code
//____________________________________________________________________________
// TypeInfo/TypeLib processing flags
const int tfEnum = 1<<TKIND_ENUM;
const int tfRecord = 1<<TKIND_RECORD;
const int tfModule = 1<<TKIND_MODULE;
const int tfInterface = 1<<TKIND_INTERFACE;
const int tfDispatch = 1<<TKIND_DISPATCH;
const int tfCoClass = 1<<TKIND_COCLASS;
const int tfAlias = 1<<TKIND_ALIAS;
const int tfUnion = 1<<TKIND_UNION;
const int tfAllKinds =(1<<TKIND_MAX)-1;
const int tfScanOnly = 1<<15;
const int tfLibHeader = 1<<14;
const int tfDispHeader= 1<<13;
const int tfDispImpl = 1<<12;
const int tfBoolType = 1<<11; // OR into libMode[1] if compiler bool support
char* infoKind[] =
{"ENUM","RECORD","MODULE","INTERFACE","DISPATCH","COCLASS","ALIAS","UNION"};
char* typeFlagText[] = {
"appobject", // 1 TYPEFLAG_FAPPOBJECT
"cancreate", // 2 TYPEFLAG_FCANCREATE
"licensed", // 4 TYPEFLAG_FLICENSED
"predeclid", // 8 TYPEFLAG_FPREDECLID
"hidden", // 16 TYPEFLAG_FHIDDEN
"control", // 32 TYPEFLAG_FCONTROL
"dual", // 64 TYPEFLAG_FDUAL
"nonextensible", // 128 TYPEFLAG_FNONEXTENSIBLE
"oleautomation", // 256 TYPEFLAG_FOLEAUTOMATION
"TYPEFLAG256",
"TYPEFLAG512",
};
const int typeFlagCount = sizeof(typeFlagText)/sizeof(char*);
char* implFlagText[] = {
"default", // 1 IMPLTYPEFLAG_FDEFAULT
"source", // 2 IMPLTYPEFLAG_FSOURCE
"restricted", // 4 IMPLTYPEFLAG_FRESTRICTED
"IMPLTYPEFLAG8",
"IMPLTYPEFLAG16",
"IMPLTYPEFLAG32",
};
const int implFlagCount = sizeof(implFlagText)/sizeof(char*);
char* memberFlagText[] = {
"restricted", // 1 FUNCFLAG_FRESTRICTED (VARFLAG_FREADONLY->invokeKind)
"source", // 2 FUNCFLAG_FSOURCE VARFLAG_FSOURCE
"bindable", // 4 FUNCFLAG_FBINDABLE VARFLAG_FBINDABLE
"requestedit", // 8 FUNCFLAG_FREQUESTEDIT VARFLAG_FREQUESTEDIT
"displaybind", // 16 FUNCFLAG_FDISPLAYBIND VARFLAG_FDISPLAYBIND
"defaultbind", // 32 FUNCFLAG_FDEFAULTBIND VARFLAG_FDEFAULTBIND
"hidden", // 64 FUNCFLAG_FHIDDEN VARFLAG_FHIDDEN
"FUNCFLAG128",
"FUNCFLAG256",
};
const int memberFlagCount = sizeof(memberFlagText)/sizeof(char*);
char* infoCpp[] = // add delimiting space after identifier as needed
{"enum ","struct ","","class _ICLASS ","class ","//","typedef ","union "};
char* invokeKind[] = {
"", // 0 no INVOKEKIND flags
"method", // 1 INVOKE_FUNC
"propget", // 2 INVOKE_PROPERTYGET
"prop r/o", // 3 VAR_DISPATH + VARFLAG_FREADONLY
"propset", // 4 INVOKE_PROPERTYPUT
"?" , // 5
"propgetset", // 6
"prop r/w", // 7 VAR_DISPATCH
"propputref", // 8 INVOKE_PROPERTYPUTREF
"?", // 9
"?" // 10
};
char* dataType[] = {
"void", // 0 void
"NULL", // 1 SQL NULL
"short", // 2 signed short
"long", // 3 signed long
"float", // 4 IEEE 4-byte
"double", // 5 IEEE 8-byte
"CY", // 6 currency
"DATE", // 7 datetime as double
"BSTR", // 8 char far* global mem with int size before
"IDispatch*", // 9 dispatch interface
"SCODE", // 10 OLE return status
"bool", // 11 boolean
"VARIANT far*", // 12 pointer to VARIANT union
"IUnknown*", // 13 unspecified COM interface
"<14>",
"<15>",
"signed char", // 17 unsigned char, byte
"unsigned char",
"unsigned short",
"unsigned long",
"LARGE_INTEGER",
"ULARGE_INTEGER",
"signed int",
"unsigned int",
"void",
"HRESULT",
"<ptr>",
"<27>",
"<array>",
"<userdef>",
"char far*",
"wchar far*",
};
const int dataTypeCount = sizeof(dataType)/sizeof(char*);
char* autoType[] = {
"void", // 0 void
"NULL", // 1 SQL NULL
"short", // 2 signed short
"long", // 3 signed long
"float", // 4 IEEE 4-byte
"double", // 5 IEEE 8-byte
"TAutoCurrency", // 6 currency
"TAutoDate", // 7 datetime as double
"TAutoString", // 8 char far* global mem with int size before
};
const int autoTypeCount = sizeof(autoType)/sizeof(char*);
char foldName[256+1] = {
"_\0_\0_\0f\0_\0_\0_\0_\0_\0_\0S\0_\0OE_\0_\0_\0"
"_\0_\0_\0_\0_\0_\0_\0_\0_\0TMs\0_\0oe_\0_\0Y\0"
"_\0_\0c\0L\0_\0Y\0_\0_\0_\0c\0a\0_\0_\0_\0r\0_\0"
"0\0_\0\062\0\063\0_\0u\0_\0_\0_\0\061\0o\0_\0_\0_\0_\0_\0"
"A\0A\0A\0A\0AEA\0AEC\0E\0E\0E\0E\0I\0I\0I\0I\0"
"D\0N\0O\0O\0O\0O\0OEx\0O\0U\0U\0U\0UEY\0_\0ss"
"a\0a\0a\0a\0aea\0aec\0e\0e\0e\0e\0i\0i\0i\0i\0"
"o\0n\0o\0o\0o\0o\0oe_\0o\0u\0u\0u\0uey\0_\0y\0"
};
const int fnObjectByRef = 1; // generate code passing proxy object by ref
const int fnPrefixGet = 2; // prefix identifier name with "Get"
const int fnPrefixSet = 4; // prefix identifier name with "Set"
const int fnClassName = 8; // add classname:: before identifier
const int fnAutoTypes = 16; // translate types to wrappered TAuto...
const int fnIterator = 32; // emit TAutoIterator<type>&
bool IsDispObject(ITypeInfo* typeInfo, TYPEDESC far& typeDesc)
{
if (typeDesc.vt != VT_USERDEFINED)
return false;
TComRef<ITypeInfo> refTypeInfo;
OLECALL(typeInfo->GetRefTypeInfo(typeDesc.hreftype,refTypeInfo),"TypeInfo::GetRefTypeInfo");
refTypeInfo.GetAttr();
return refTypeInfo.Attr->typekind==TKIND_DISPATCH;
}
char* ClassName = 0; // will become member variable
bool FormatTypeName(ITypeInfo* typeInfo, TYPEDESC far& typeDescRef,
char far* name, ostream& out, int flags = 0)
{
bool isDispObject = false;
TYPEDESC far* typeDesc = &typeDescRef;
ARRAYDESC far* arrayDesc = 0;
if (flags & fnIterator)
out << "TAutoEnumerator<";
for (int derefCount = 0; typeDesc->vt == VT_PTR; derefCount++)
typeDesc = typeDesc->lptdesc;
if (typeDesc->vt == VT_USERDEFINED) {
TComRef<ITypeInfo> refTypeInfo;
OLECALL(typeInfo->GetRefTypeInfo(typeDesc->hreftype,refTypeInfo),"TypeInfo::GetRefTypeInfo");
refTypeInfo.GetDocumentation();
out << refTypeInfo.Name;
refTypeInfo.GetAttr();
if (flags & fnObjectByRef && refTypeInfo.Attr->typekind==TKIND_DISPATCH &&
!(flags & fnIterator)){
out << '&'; // need reference for automation proxy class
} isDispObject = true;
} else if (typeDesc->vt == VT_CARRAY) {
arrayDesc = typeDesc->lpadesc;
FormatTypeName(typeInfo, arrayDesc->tdescElem, 0, out);
} else {
if ((flags & fnAutoTypes) && (typeDesc->vt & 31) < autoTypeCount)
out << autoType[typeDesc->vt & 31];
else
out << dataType[typeDesc->vt & 31];
}
if (typeDesc->vt & VT_BYREF) // should never happen
derefCount++;
while (derefCount--)
out << " far*";
if (flags & fnIterator)
out << ">&";
if (name) {
char* buf;
int len = lstrlen(name);
int nonascii = 0;
for (unsigned char far* pc = (unsigned char far*)name; *pc; pc++)
if (*pc >= 128)
nonascii++;
if (nonascii) {
unsigned char far* pn = (unsigned char far*)name;
buf = new char[nonascii + len + 1];
name = buf;
unsigned char c;
do {
c = *pn++;
if (c < 128) {
*buf++ = c;
} else {
char* px = foldName + (c-128)*2;
*buf++ = *px++;
if (*px)
*buf++ = *px;
}
} while (c);
}
out << ' ';
if (ClassName && (flags & fnClassName))
out << ClassName << "::";
if (flags & fnPrefixGet)
out << "Get";
if (flags & fnPrefixSet)
out << "Set";
out << name;
if (nonascii)
delete name;
}
if (arrayDesc)
for (int dim = 0; dim < arrayDesc->cDims; dim++)
out << '[' << arrayDesc->rgbounds[dim].cElements << ']';
return isDispObject;
}
void FormatGuidLang(GUID far& guid, LCID locale, ostream& out)
{
char guidBuf[38+1] = "{NULL}";
int notNull = 0;
int far* pg = (int far*)&guid;
for (int i = sizeof(GUID)/sizeof(int); i--; pg++)
notNull |= *pg;
if (notNull)
wsprintf(guidBuf, "{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
guid.Data1, guid.Data2, guid.Data3,
guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3],
guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
out << ' ' << guidBuf << '\\' << hex << LANGIDFROMLCID(locale) << dec;
}
void FormatVers(int major, int minor, ostream& out)
{
if (major)
out << ' ' << major << '.' << minor;
}
void FormatDispId(DISPID id, int invKind, uint16 flags, ostream& out)
{
out << "[id(";
if ((long)id > 9999 || (long)id < -9999)
out << "0x" << hex << id << dec;
else
out << id;
out << ')';
if (invKind)
out << ", " << invokeKind[invKind];
for (int i = 0; flags; i++, flags >>= 1) {
if (flags & 1)
out << ", " << memberFlagText[i];
}
out << ']';
}
// assumed that caller of this function called GetDocumenation() on typeInfo
void FormatTypeInfo(TComRef<ITypeInfo>& typeInfo, int mode, ostream& out)
{
//typeInfo.GetDocumentation();
typeInfo.GetAttr();
int kind = typeInfo.Attr->typekind;
if (typeInfo.Attr->typekind != TKIND_ALIAS) {
out << "\n// TKIND_" << infoKind[kind] << ": " << typeInfo.Name;
FormatVers(typeInfo.Attr->wMajorVerNum,typeInfo.Attr->wMinorVerNum,out);
FormatGuidLang(typeInfo.Attr->guid, typeInfo.Attr->lcid, out);
out << ' ' << typeInfo.Doc << '\n';
int typeFlags = typeInfo.Attr->wTypeFlags;
if (typeFlags && !(mode & (tfDispHeader | tfDispImpl))) {
char* delim = "// [";
for (int tflag = 0; tflag < implFlagCount; tflag++, typeFlags >>= 1)
if (typeFlags & 1) {
out << delim << typeFlagText[tflag];
delim = ", ";
}
out << "]\n";
}
out << '\n';
if (!(mode & tfDispImpl))
out << infoCpp[kind];
}
switch (kind) {
case TKIND_MODULE: {
for (int varIndex = 0; varIndex < typeInfo.Attr->cVars; varIndex++) {
typeInfo.GetVarDesc(varIndex);
typeInfo.GetDocumentation(typeInfo.VarDesc->memid);
out << " ";
FormatTypeName(typeInfo, typeInfo.VarDesc->elemdescVar.tdesc, typeInfo.Name, out);
out << "; // ";
int invKind = typeInfo.VarDesc->wVarFlags & VARFLAG_FREADONLY ? 3 : 7;
FormatDispId(typeInfo.VarDesc->memid, invKind,
typeInfo.VarDesc->wVarFlags & ~VARFLAG_FREADONLY, out);
out << '\n';
}
for (int funcIndex = 0; funcIndex < typeInfo.Attr->cFuncs; funcIndex++) {
typeInfo.GetFuncDesc(funcIndex);
typeInfo.GetDocumentation(typeInfo.FuncDesc->memid);
int argCount = typeInfo.FuncDesc->cParams;
int argIndex;
TBSTR argName[35]; // max. arg count + 1, minimum 35 for MSWord6
unsigned int nameCount;
OLECALL(typeInfo->GetNames(typeInfo.FuncDesc->memid, argName[0],
sizeof(argName)/sizeof(TBSTR), &nameCount),"TKIND_INTERFACE GetNames");
if (typeInfo.Doc)
out << " // " << typeInfo.Doc << '\n';
out << " ";
for (argIndex = 0; argIndex <= argCount; argIndex++) {
ELEMDESC far* elemDesc = argIndex==0 ?
&typeInfo.FuncDesc->elemdescFunc :
typeInfo.FuncDesc->lprgelemdescParam + (argIndex-1);
FormatTypeName(typeInfo, elemDesc->tdesc, argIndex < nameCount ?
(char far*)argName[argIndex] : (char far*)0, out);
if (argIndex == 0)
out << '(';
else if (argIndex != argCount)
out << ", ";
}
out << "); // ";
FormatDispId(typeInfo.FuncDesc->memid, 0,
typeInfo.FuncDesc->wFuncFlags, out);
out << '\n';
}
out << "\n";
break;
}
case TKIND_UNION:
case TKIND_RECORD: {
out << typeInfo.Name << " {\n"; /*}*/
for (int membIndex = 0; membIndex < typeInfo.Attr->cVars; membIndex++) {
typeInfo.GetVarDesc(membIndex);
typeInfo.GetDocumentation(typeInfo.VarDesc->memid);
out << " ";
FormatTypeName(typeInfo, typeInfo.VarDesc->elemdescVar.tdesc, typeInfo.Name, out);
out << ";\n";
}
/*{*/ out << "};\n";
break;
}
case TKIND_ALIAS: {
out << infoCpp[kind] << ' ';
FormatTypeName(typeInfo, typeInfo.Attr->tdescAlias, typeInfo.Name, out);
out << ";\n";
break;
}
case TKIND_ENUM: {
out << typeInfo.Name << " {\n"; /*}*/
for (int enumIndex = 0; enumIndex < typeInfo.Attr->cVars; enumIndex++) {
typeInfo.GetVarDesc(enumIndex);
typeInfo.GetDocumentation(typeInfo.VarDesc->memid);
out << " " << typeInfo.Name;
if (typeInfo.VarDesc->varkind == VAR_CONST
&& typeInfo.VarDesc->lpvarValue->vt == VT_I2)
out << " = " << typeInfo.VarDesc->lpvarValue->iVal;
out << ",\n";
}
/*{*/ out << "};\n";
break;
}
case TKIND_INTERFACE: {
out << typeInfo.Name;
int baseCount = typeInfo.Attr->cImplTypes;
for (int baseIndex = 0; baseIndex < baseCount; baseIndex++) {
out << (baseIndex ==0 ? " : public " : ", public ");
HREFTYPE hrefType;
OLECALL(typeInfo->GetRefTypeOfImplType(baseIndex, &hrefType),"TKIND_INTERFACE GetRefTypeofImplType");
TComRef<ITypeInfo> refTypeInfo;
OLECALL(typeInfo->GetRefTypeInfo(hrefType, refTypeInfo),"TKIND_INTERFACE GetRefTypeInfo");
refTypeInfo.GetDocumentation();
out << refTypeInfo.Name;
}
out << " {\n public:\n"; /*}*/
for (int funcIndex = 0; funcIndex < typeInfo.Attr->cFuncs; funcIndex++) {
typeInfo.GetFuncDesc(funcIndex);
typeInfo.GetDocumentation(typeInfo.FuncDesc->memid);
int argCount = typeInfo.FuncDesc->cParams;
int argIndex;
TBSTR argName[35]; // max. arg count + 1, minimum 35 for MSWord6
unsigned int nameCount;
OLECALL(typeInfo->GetNames(typeInfo.FuncDesc->memid, argName[0],
sizeof(argName)/sizeof(TBSTR), &nameCount),"TKIND_INTERFACE GetNames");
if (typeInfo.Doc)
out << " // " << typeInfo.Doc << '\n';
if (typeInfo.FuncDesc->wFuncFlags & FUNCFLAG_FRESTRICTED)
out << "// "; // not accessible from dispatch controller
else
out << " ";
for (argIndex = 0; argIndex <= argCount; argIndex++) {
ELEMDESC far* elemDesc = argIndex==0 ?
&typeInfo.FuncDesc->elemdescFunc :
typeInfo.FuncDesc->lprgelemdescParam + (argIndex-1);
FormatTypeName(typeInfo, elemDesc->tdesc, argIndex < nameCount ?
(char far*)argName[argIndex] : (char far*)0, out);
if (argIndex == 0)
out << '(';
else if (argIndex != argCount)
out << ", ";
}
out << ") = 0; // ";
FormatDispId(typeInfo.FuncDesc->memid, 0,
typeInfo.FuncDesc->wFuncFlags, out);
out << '\n';
}
/*{*/ out << "};\n";
break;
}
case TKIND_DISPATCH: {
TYPEDESC typeDescVoid;
typeDescVoid.vt = VT_VOID;
char semi;
if (mode & tfDispImpl) {
ClassName = new char[lstrlen(typeInfo.Name)+1];
lstrcpy(ClassName, typeInfo.Name);
semi = ' ';
} else {
semi = ';';
out << typeInfo.Name;
if (mode & tfDispHeader)
out << " : public TAutoProxy";
out << " {\n public:\n"; /*}*/
if (mode & tfDispHeader)
out << " " << typeInfo.Name << "() : TAutoProxy(0x"
<< hex << LANGIDFROMLCID(typeInfo.Attr->lcid) << dec << ") {}\n";
}
for (int varIndex = 0; varIndex < typeInfo.Attr->cVars; varIndex++) {
int formatFlags = 0;
if (mode & tfDispHeader)
formatFlags = fnObjectByRef | fnPrefixGet | fnAutoTypes;
if (mode & tfDispImpl)
formatFlags = fnObjectByRef | fnPrefixGet | fnClassName | fnAutoTypes;
typeInfo.GetVarDesc(varIndex);
TYPEDESC& typeDesc = typeInfo.VarDesc->elemdescVar.tdesc;
int invKind = typeInfo.VarDesc->wVarFlags & VARFLAG_FREADONLY ? 3 : 7;
// should we insure that (type.Info.VarDesc->varkind==VAR_DISPATCH) ?
typeInfo.GetDocumentation(typeInfo.VarDesc->memid);
if (!(mode & tfDispImpl) && typeInfo.Doc)
out << " // " << typeInfo.Doc << '\n';
bool isDispObject = IsDispObject(typeInfo, typeDesc);
bool boolProp = !(mode & tfBoolType) && typeDesc.vt == VT_BOOL;
bool boolRef = !(mode & tfBoolType) && typeDesc.vt == VT_PTR
&& typeDesc.lptdesc->vt == VT_BOOL;
do {
char* argName = 0;
if (!(mode & tfDispImpl))
out << " ";
if (formatFlags == 0 ||
!((formatFlags & fnPrefixSet) || isDispObject)){
FormatTypeName(typeInfo, typeDesc, typeInfo.Name, out, formatFlags);
if (formatFlags & fnPrefixGet)
out << "()";
out << semi << " ";
} else {
FormatTypeName(typeInfo,typeDescVoid,typeInfo.Name,out,formatFlags);
if (mode & tfDispImpl)
argName = isDispObject ? "obj" : "val";
out << '(';
FormatTypeName(typeInfo,typeDesc,argName,out,
formatFlags & (fnObjectByRef | fnAutoTypes));
out << ')' << semi;
}
if (mode & tfDispImpl) {
out << "\n{\n AUTONAMES0(\"" << typeInfo.Name
<< "\")\n AUTOARGS0()\n AUTOCALL_PROP_"; /*}*/
if (formatFlags & fnPrefixSet)
out << "SET";
else if (isDispObject)
out << "REF";
else if (boolProp)
out << "CONV(TAutoBool)";
else if (boolRef)
out << "CONV(TAutoBoolRef)";
else
out << "GET";
if (argName) {
if (boolProp)
out << "(TAutoBool(" << argName << "))";
else if (boolRef)
out << "(TAutoBoolRef(" << argName << "))";
else
out << '(' << argName << ')';
}
/*{*/ out << "\n}\n";
} else {
out << " // ";
FormatDispId(typeInfo.VarDesc->memid, invKind,
typeInfo.VarDesc->wVarFlags & ~VARFLAG_FREADONLY, out);
}
out << '\n';
if ((formatFlags & fnPrefixGet) && invKind == 7)
formatFlags ^= (fnPrefixGet | fnPrefixSet);
else
formatFlags = 0;
} while (formatFlags & fnPrefixSet);
}
for (int funcIndex = 0; funcIndex < typeInfo.Attr->cFuncs; funcIndex++) {
int formatFlags = 0;
if (mode & tfDispHeader)
formatFlags = fnObjectByRef | fnAutoTypes;
if (mode & tfDispImpl)
formatFlags = fnObjectByRef | fnAutoTypes | fnClassName;
typeInfo.GetFuncDesc(funcIndex);
if (typeInfo.FuncDesc->wFuncFlags & FUNCFLAG_FRESTRICTED)
continue; // not accessible from dispatch controller
typeInfo.GetDocumentation(typeInfo.FuncDesc->memid);
int argCount = typeInfo.FuncDesc->cParams;
TBSTR argNames[35]; // max. arg count + 1, minimum 35 for MSWord6
unsigned int nameCount;
OLECALL(typeInfo->GetNames(typeInfo.FuncDesc->memid, argNames[0],
sizeof(argNames)/sizeof(TBSTR), &nameCount),"TKIND_DISPATCH GetNames");
if (!(mode & tfDispImpl)) {
if (typeInfo.Doc)
out << " // " << typeInfo.Doc << '\n';
out << " ";
}
int argIndex = -1; // index into ELEMDESC[], -1 for return type
int nameIndex = 0; // index into name table, no propset param name
int outParam = 0; // index of type/name being output
bool voidRet = false;
bool boolRet = false;
bool boolRetRef = false;
bool isObject = false;
bool isIterator = (typeInfo.FuncDesc->memid == DISPID_NEWENUM);
for ( ; argIndex<argCount; argIndex++, outParam++) {
TYPEDESC far* typeDesc = &typeInfo.FuncDesc->elemdescFunc.tdesc;
if (argIndex >= 0) { // processing an argument
typeDesc = &typeInfo.FuncDesc->lprgelemdescParam[argIndex].tdesc;
} else if (outParam == 0 && (mode & (tfDispHeader | tfDispImpl)) &&
(IsDispObject(typeInfo, *typeDesc) || isIterator)) {
typeDesc = &typeDescVoid;
argIndex--; // reprocess return as first arg
isObject = true;
} else if (typeDesc->vt == VT_VOID || typeDesc->vt == VT_EMPTY) {
voidRet = true;
} else if (!(mode & tfBoolType) && typeDesc->vt == VT_BOOL) {
boolRet = true;
} else if (!(mode & tfBoolType) && typeDesc->vt == VT_PTR
&& typeDesc->lptdesc->vt == VT_BOOL) {
boolRetRef = true;
}
char far* name = 0;
char argName[10];
if (isObject && argIndex == -1) {
if (mode & tfDispImpl)
name = "obj";
if (isIterator)
formatFlags |= fnIterator;
} else if (argIndex==0 && typeInfo.FuncDesc->invkind>=INVOKE_PROPERTYPUT) {
if (mode & tfDispImpl)
name = "val";
} else if (nameIndex >= nameCount) {
if (mode & tfDispImpl)
wsprintf(name = argName, "arg%d", argIndex+1);
} else
name = argNames[nameIndex++];
if (outParam == 0 && (mode & (tfDispHeader | tfDispImpl))) {
if (typeInfo.FuncDesc->invkind>=INVOKE_PROPERTYPUT)
formatFlags |= fnPrefixSet; // must differentiate from get
else if (typeInfo.FuncDesc->invkind==INVOKE_PROPERTYGET) {
if (isIterator)
name = "Enumerate";
else
formatFlags |= fnPrefixGet; // get&set may have same name
}
}
FormatTypeName(typeInfo, *typeDesc, name, out, formatFlags);
formatFlags &= ~fnIterator;
if (outParam == 0) {
out << '(';
formatFlags &= ~(fnClassName | fnPrefixGet | fnPrefixSet);
}
else if (argIndex != argCount-1)
out << ", ";
}
out << ')' << semi;
if (mode & tfDispImpl) {
out << "\n{\n AUTONAMES0("; /*}*/
if (isIterator)
out << "DISPID_NEWENUM";
else
out << '"' << typeInfo.Name << '"';
if (typeInfo.FuncDesc->invkind>=INVOKE_PROPERTYPUT)
argCount--;
out << ")\n AUTOARGS" << argCount << '(';
argIndex = 1; // 1-based for following loop
for ( ; argIndex <= argCount; argIndex++) { // 1-based
if (argIndex != 1)
out << ", ";
TYPEDESC far& typeDesc =
typeInfo.FuncDesc->lprgelemdescParam[argIndex-1].tdesc;
bool boolArg = !(mode & tfBoolType) && typeDesc.vt == VT_BOOL;
bool boolRef = !(mode & tfBoolType) && typeDesc.vt == VT_PTR
&& typeDesc.lptdesc->vt == VT_BOOL;
if (boolArg)
out << "TAutoBool(";
else if (boolRef)
out << "TAutoBoolRef(";
if (argIndex < nameCount)
out << argNames[argIndex];
else
out << "arg" << argIndex;
if (boolArg || boolRef)
out << ")";
}
out << ")\n AUTOCALL_";
if (typeInfo.FuncDesc->invkind==INVOKE_PROPERTYGET) {
if (isObject)
out << "PROP_REF(obj)";
else
out << "PROP_GET";
} else if (typeInfo.FuncDesc->invkind==INVOKE_PROPERTYPUT) {
out << "PROP_SET(val)";
} else {
out << "METHOD_";
if (isObject)
out << "REF(obj)";
else if (voidRet)
out << "VOID";
else if (boolRet)
out << "CONV(TAutoBool)";
else if (boolRetRef)
out << "CONV(TAutoBoolRef)";
else
out << "RET";
}
/*{*/ out << "\n}\n"; //(for editor brace check)
} else {
out << " // ";
FormatDispId(typeInfo.FuncDesc->memid,
typeInfo.FuncDesc->invkind,
typeInfo.FuncDesc->wFuncFlags, out);
}
out << '\n';
}
if (!(mode & tfDispImpl))
/*{*/ out << "};\n";
break;
}
case TKIND_COCLASS: {
for (unsigned int cindex=0; cindex<typeInfo.Attr->cImplTypes; cindex++) {
HREFTYPE hrefType;
OLECALL(typeInfo->GetRefTypeOfImplType(cindex, &hrefType), "GetRefTypeofImplType");
int typeFlags;
OLECALL(typeInfo->GetImplTypeFlags(cindex, &typeFlags), "GetImplTypeFlags");
TComRef<ITypeInfo> refTypeInfo;
OLECALL(typeInfo->GetRefTypeInfo(hrefType, refTypeInfo),"TKIND_COCLASS GetRefTypeInfo");
refTypeInfo.GetDocumentation();
out << "\n// " << refTypeInfo.Name;
char* delim = " [";
if (typeFlags) {
for (int iflag = 0; iflag < implFlagCount; iflag++, typeFlags >>= 1)
if (typeFlags & 1) {
out << delim << implFlagText[iflag];
delim = ", ";
}
out << ']';
}
}
out << "\n\n";
break;
}
}
delete ClassName;
ClassName = 0;
}
//____________________________________________________________________________
//
// Local class to hold selection and iterator information for type library
//____________________________________________________________________________
class TLogTypeInfo {
public:
typedef bool (*TCall)(TLogTypeInfo&);
TLogTypeInfo(HWND hWnd);
~TLogTypeInfo() {delete SelectList;}
bool Report();
HWND GetWindow() {return Window;}
int GetSelectCount() {return SelectCount;}
int* GetSelectList() {return SelectList;}
void SetSelectList(int count, int* list);
int GetRequestCount() {return ReqCount;}
void SetRequestList(int count, int* list, char** names);
void SetCallback(TLogTypeInfo::TCall proc) {Proc = proc;}
bool MatchRequest(); // return true to continue, false if all done
char* ExtractRequest();// return unmatched type name, 0 if list empty
void ClearLists();
int Index; // returned selection index, within user select types
int TypeIndex; // returned typeinfo index, within entire type library
char* TypeKind; // returned typeinfo kind text
char far* TypeName; // returned typeinfo name text
private:
char** ReqNames; // temp requested type names
int ReqCount; // temp requested name count
int* SelectList; // list of selected typeinfos in type library
int SelectCount; // number of selected items
HWND Window; // window to receive data
TCall Proc; // callback function to display data
};
inline TLogTypeInfo::TLogTypeInfo(HWND hWnd)
: Window(hWnd), SelectList(0), Proc(0)
{
ClearLists(); // SelectList must be 0 to prevent delete of garbage
}
inline void TLogTypeInfo::ClearLists()
{
if(!ReqNames)
delete SelectList;
ReqNames = 0;
SelectList = 0;
SelectCount = 0;
ReqCount = 0;
}
inline void TLogTypeInfo::SetSelectList(int count, int* list)
{
ClearLists();
SelectCount = count;
SelectList = list;
}
inline void TLogTypeInfo::SetRequestList(int count, int* list, char** names)
{
ClearLists();
ReqCount = count;
ReqNames = names;
SelectList = list;
}
inline bool TLogTypeInfo::Report()
{
return Proc ? Proc(*this) : MatchRequest();
}
bool TLogTypeInfo::MatchRequest()
{
if (!ReqCount)
return false;
for (int i = 0; i < ReqCount; i++) {
if (stricmp(TypeName, ReqNames[i]) == 0) {
SelectList[SelectCount++] = TypeIndex;
if (--ReqCount != i)
memcpy(&ReqNames[i],&ReqNames[i+1],(ReqCount-i)*sizeof(int));
return ReqCount != 0;
}
}
return true; // keep going
}
char* TLogTypeInfo::ExtractRequest()
{
if (!ReqCount)
return 0;
char* name = ReqNames[0];
if (--ReqCount)
memcpy(&ReqNames[0], &ReqNames[1], ReqCount*sizeof(int));
return name;
}
//____________________________________________________________________________
//
// ITypeLib iterator, emits file header info, calls ITypeInfo iterator
//____________________________________________________________________________
void ReadTypeLib(char* libName, char* incName, int mode, ostream& out,
TLogTypeInfo& log)
{
try { // catch OLE errors, no OLE calls are made outside of this block
char nameBuf[50]; // large enough for basename.tlb, overflow not fatal
TOleAllocator oleMem(0);
TComRef<ITypeLib> typeLib;
TComRef<ITypeInfo> coclassInfo;
OLECALL(::LoadTypeLib(libName, typeLib),"LoadTypeLib");
typeLib.GetAttr();
if (mode & tfLibHeader) {
typeLib.GetDocumentation();
if (::GetFileTitle(libName, nameBuf, sizeof(nameBuf)) <= 0)
out << "// Type Library: " << nameBuf;
out << " " << typeLib.Doc << '\n';
out << "// " << typeLib.Name;
FormatVers(typeLib.Attr->wMajorVerNum, typeLib.Attr->wMinorVerNum, out);
FormatGuidLang(typeLib.Attr->guid, typeLib.Attr->lcid, out);
out << "\n\n";
}
int infoCount = typeLib->GetTypeInfoCount();
if (incName)
out << "#include " << incName << "\n";
if (mode & tfDispHeader) {
for (int infoIndex = 0; infoIndex < infoCount; infoIndex++) {
TYPEKIND infoType;
typeLib->GetTypeInfoType(infoIndex, &infoType);
if (infoType == TKIND_DISPATCH) {
TComRef<ITypeInfo> typeInfo;
OLECALL(typeLib->GetTypeInfo(infoIndex, typeInfo),"typeLib->GetTypeInfo");
typeInfo.GetDocumentation();
out << "\nclass " << typeInfo.Name << ';';
}
if (infoType == TKIND_COCLASS) {
OLECALL(typeLib->GetTypeInfo(infoIndex, coclassInfo),"typeLib->GetTypeInfo");
}
}
out << "\n";
}
// need to scan coclass typeinfo for [source] classes
// and eliminate them from HXX/CXX code generation
// eventually should emit server code tables
//
int infoIndex = 0;
int selIndex = 0;
int selCount = log.GetSelectCount();
int* selList = log.GetSelectList();
for (; infoIndex < infoCount; infoIndex++) {
if (selList && !(mode & tfScanOnly)) { // partial selection
if (!selCount || infoIndex != selList[selIndex])
continue;
selCount--;
}
TYPEKIND infoType;
typeLib->GetTypeInfoType(infoIndex, &infoType);
if (((1<<infoType) & mode) == 0)
continue;
TComRef<ITypeInfo> typeInfo;
OLECALL(typeLib->GetTypeInfo(infoIndex, typeInfo),"GetTypeInfo");
typeInfo.GetDocumentation();
typeInfo.GetAttr();
log.TypeIndex = infoIndex;
log.Index = selIndex++;
log.TypeName = typeInfo.Name;
log.TypeKind = infoKind[infoType];
if (!log.Report())
break;
if (mode & tfScanOnly)
continue;
FormatTypeInfo(typeInfo, mode, out);
}
}
catch(TXOle& x) { // convert OLE exception into local exception
Error(libName, x.why().c_str());
}
}
//____________________________________________________________________________
//
// Command line and UI processing, creates streams
//____________________________________________________________________________
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <fstream.h>
#include <strstrea.h>
// Command line token extraction class
class TCmdLine {
public:
enum Kind {Null, Name, Option, Value};
TCmdLine(char far* cmdLine);
~TCmdLine();
Kind NextToken();
int TokenLen;
char* Token;
Kind Type;
private:
char* Buf;
Kind NextType;
};
TCmdLine::TCmdLine(char far* cmdLine) : NextType(Name)
{
Token = Buf = new char[lstrlen(cmdLine)+1];
TokenLen = -1; // cancels increment on next assignment
lstrcpy(Buf, cmdLine);
}
TCmdLine::~TCmdLine()
{
delete Buf;
}
TCmdLine::Kind TCmdLine::NextToken()
{
Token += (TokenLen + 1);
if (NextType == Name) { // name or leading spaces
Token += strspn(Token, " \t"); // skip leading white space
switch (*Token++) {
case 0:
return Type = NextType = Null;
case '=':
Type = Value;
break;
case '-':
case '/':
Type = Option;
break;
default:
Type = Name;
Token--;
}
} else { // must have stopped on a delimiter
Type = NextType;
if (Type == Null)
return Type;
}
TokenLen = strcspn(Token, "=/- \t");
char* nextToken = Token + TokenLen;
switch (*nextToken) {
case 0:
NextType = Null;
break;
case '=':
NextType = Value;
break;
case '-':
case '/':
NextType = Option;
break;
default:
NextType = Name;
}
*nextToken = 0; // null-terminate current token
return Type;
}
// File name processing
enum fileKind { fkDispHdr, fkDispSrc, fkFullCpp, fkCount };
char* optText[] = { "Header", "Code", "Definitions" };
char* fileExt[] = { "HXX", "CXX", "HPP" };
int libMode[] = { tfEnum|tfAlias|tfDispatch|tfLibHeader|tfDispHeader,
tfDispatch|tfDispImpl, tfAllKinds|tfLibHeader };
char* stdFile[] = { ".HXX", ".CXX", 0 }; // OC controller proxy code
char* cppFile[] = { 0, 0, ".HPP" };// standard C++ defs
int GenerateFiles(char* libName, char** outFiles, TLogTypeInfo& log)
{
char outName[_MAX_PATH];
char outDrive[_MAX_DRIVE];
char outDir [_MAX_DIR];
char outFName[_MAX_FNAME];
char outExt [_MAX_EXT];
char libDrive[_MAX_DRIVE];
char libDir [_MAX_DIR];
char libFName[_MAX_FNAME];
char libExt [_MAX_EXT];
char incFile [_MAX_FNAME+_MAX_EXT+2];
char* incName;
_splitpath(libName, libDrive, libDir, libFName, libExt);
int outCount = 0; // count of files actually output
for (int fileIndex = 0; fileIndex < fkCount; fileIndex++) {
if (!outFiles[fileIndex])
continue;
_splitpath(outFiles[fileIndex], outDrive, outDir, outFName, outExt);
_makepath (outName,
outDrive[0] ? outDrive : libDrive,
outDir[0] ? outDir : libDir,
outFName[0] ? outFName : libFName,
outExt[0] ? outExt : fileExt[fileIndex]);
ofstream out;
out.open(outName);
ErrorIf(out.bad(), outName, IDS_OUTFILEERR);
switch(fileIndex) {
case fkDispHdr:
incName = "<ocf/automacr.h>";
incFile[0] = '"';
_splitpath(outName, 0, 0, incFile+1, outExt);
strcat(incFile, outExt);
strcat(incFile, "\"");
break;
case fkDispSrc:
incName = incFile;
break;
case fkFullCpp:
incName = 0;
break;
}
if (log.GetWindow()) {
::SetDlgItemText(log.GetWindow(), IDC_STATUS, (char far*)outName);
int* selectList = log.GetSelectList();
int selectCount= log.GetSelectCount();
if (!selectList) {
::SendDlgItemMessage(log.GetWindow(), IDC_INFOLIST, LB_SETSEL, 1, -1);
} else if (outCount != 0) {
for (int i = 0; i < selectCount; i++)
::SendDlgItemMessage(log.GetWindow(), IDC_INFOLIST, LB_SETSEL, 1,
(LPARAM)(unsigned)selectList[i]);
}
}
ReadTypeLib(libName, incName, libMode[fileIndex], out, log);
outCount++;
}
return 0;
}
#define WM_USERSTAT (WM_USER + 100)
bool CALLBACK __export
HelpProc(HWND hDlg, UINT msg, WPARAM /*wParam*/, LPARAM /*lParam*/)
{
if (msg != WM_COMMAND)
return (msg == WM_INITDIALOG);
::EndDialog(hDlg, TRUE);
return true;
}
bool CALLBACK __export
SelectProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM /*lParam*/)
{
if (msg == WM_INITDIALOG) {
int tabs = IDC_INFOLIST_TAB;
::SendDlgItemMessage(hDlg, IDC_INFOLIST, LB_SETTABSTOPS, 1, (LPARAM)&tabs);
::SendDlgItemMessage(hDlg, IDC_AUTOCODE, BM_SETCHECK, 1, 0);
return 1;
} else if (msg == WM_COMMAND) {
switch (wParam) {
case IDOK:
case IDCANCEL:
::PostMessage(hDlg, WM_USERSTAT, wParam, 0);
return 1;
case IDC_SELECTALL:
case IDC_SELECTNONE:
::SendDlgItemMessage(hDlg, IDC_INFOLIST, LB_SETSEL,
wParam==IDC_SELECTALL, -1);
return 1;
}
} else if (msg == WM_CLOSE) {
::PostMessage(hDlg, WM_USERSTAT, IDABORT, 0);
}
return 0;
}
bool FillListBox(TLogTypeInfo& info)
{
char buf[100];
wsprintf(buf, "%s\t%s", (char far*)info.TypeKind, info.TypeName);
::SendDlgItemMessage(info.GetWindow(), IDC_INFOLIST, LB_ADDSTRING,
0, (LPARAM)(char far*)buf);
MSG msg;
while (::PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
::IsDialogMessage(info.GetWindow(), &msg);
return true;
}
bool ShowProgress(TLogTypeInfo& info)
{
HWND hWnd = info.GetWindow();
::SendDlgItemMessage(hWnd, IDC_INFOLIST, LB_SETTOPINDEX, info.Index, 0);
::SendDlgItemMessage(hWnd, IDC_INFOLIST, LB_SETSEL,
0, (LPARAM)(unsigned)info.Index);
MSG msg;
while (::PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
::IsDialogMessage(hWnd, &msg);
return true;
}
bool SilentYield(TLogTypeInfo& /*info*/)
{
MSG msg;
while (::PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
;
// if (msg.message == WM_QUIT)
// return false;
return true;
}
const int MaxReqTypes = 20; // maximum number of type names on command line
int PASCAL
WinMain(HINSTANCE hInst, HINSTANCE/*hPrev*/, char far* cmdLine, int/*show*/)
{
TCmdLine cmd(cmdLine);
char* outFiles[fkCount];
int stat = 0;
try {
if (cmd.NextToken() == TCmdLine::Null) {
//
// If command line empty, create dialog and operate in interactive mode
//
char libName[_MAX_PATH];
libName[0] = 0;
HWND hWnd = ::CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_SELECT), 0,
(DLGPROC)SelectProc, 0);
OPENFILENAME ofn = {sizeof(OPENFILENAME), hWnd, hInst,
"TypeLib\0*.TLB;*.OLB\0",0,0,0,
libName, sizeof(libName), 0, 0,
0, "AUTOGEN - TypeLib to C++ Conversion",
OFN_HIDEREADONLY | OFN_FILEMUSTEXIST,
0,0,0,0,0,0 };
while(::GetOpenFileName(&ofn)) {
::SetDlgItemText(hWnd, IDC_LIBFILE, (char far*)libName);
::ShowWindow(hWnd, SW_SHOW);
TLogTypeInfo fillInfo(hWnd);
fillInfo.SetCallback(FillListBox);
strstream temp;
ReadTypeLib(libName, 0, tfScanOnly | tfAllKinds, temp, fillInfo);
MSG msg;
int stat = 0;
while ( !stat && ::GetMessage(&msg, 0, 0, 0)) {
if (msg.message == WM_USERSTAT)
stat = msg.wParam;
else
::IsDialogMessage(hWnd, &msg);
}
if (stat == IDABORT)
break;
if (stat == IDOK) {
::ShowWindow(::GetDlgItem(hWnd, IDC_SELECTALL), SW_HIDE);
::ShowWindow(::GetDlgItem(hWnd, IDC_SELECTNONE), SW_HIDE);
::ShowWindow(::GetDlgItem(hWnd, IDC_STATUS), SW_SHOW);
int cppdefState = (int)::SendDlgItemMessage(hWnd, IDC_CPPDEF,
BM_GETCHECK, 0, 0);
memcpy(outFiles, cppdefState ? cppFile : stdFile, sizeof(outFiles));
fillInfo.SetCallback(ShowProgress);
int* selectList = 0;
int selectCount = (int)::SendDlgItemMessage(hWnd, IDC_INFOLIST,
LB_GETSELCOUNT, 0, 0);
if (selectCount) {
selectList = new int[selectCount];
::SendDlgItemMessage(hWnd, IDC_INFOLIST, LB_GETSELITEMS,
selectCount, (LPARAM)(int far*)selectList);
}
fillInfo.SetSelectList(selectCount, selectList);
stat = GenerateFiles(libName, outFiles, fillInfo);
while (!::GetFocus() ||
::GetWindowTask(::GetFocus())!=::GetCurrentTask())
if (::PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
::IsDialogMessage(hWnd, &msg);
::ShowWindow(::GetDlgItem(hWnd, IDC_SELECTALL), SW_SHOW);
::ShowWindow(::GetDlgItem(hWnd, IDC_SELECTNONE), SW_SHOW);
::ShowWindow(::GetDlgItem(hWnd, IDC_STATUS), SW_HIDE);
}
::ShowWindow(hWnd, SW_HIDE);
::SendDlgItemMessage(hWnd, IDC_INFOLIST, LB_RESETCONTENT, 0, 0);
}
::DestroyWindow(hWnd);
return stat;
}
if (cmd.Type == TCmdLine::Name) {
//
// If type library supplied on command line, operate in non-interactive
//
char* libName = cmd.Token; // first argument should be a typelib name
int optFound = 0;
memset(outFiles, 0, sizeof(outFiles));
char* reqTypes[MaxReqTypes];
int reqInfos[MaxReqTypes];
int reqCount = 0;
int optIndex = -1;
while (cmd.NextToken() != TCmdLine::Null) {
if (cmd.Type == TCmdLine::Option) {
for (optIndex = 0; optIndex < fkCount; optIndex++) {
if (strnicmp(cmd.Token, optText[optIndex], cmd.TokenLen) == 0)
break;
}
ErrorIf(optIndex == fkCount, IDS_UNKNOWNOPT, cmd.Token);
outFiles[optIndex] = "";
optFound++;
} else if (cmd.Type == TCmdLine::Value) {
ErrorIf(optIndex == -1, IDS_MISSINGOPT, cmd.Token);
outFiles[optIndex] = cmd.Token;
optIndex = -1;
} else { // TCmdLine::Name should be a class name to select
ErrorIf(reqCount == MaxReqTypes, cmd.Token, IDS_TOOMANYTYPES);
reqTypes[reqCount++] = cmd.Token;
}
}
if (optFound == 0) // if no file options, default to controller files
memcpy(outFiles, stdFile, sizeof(outFiles));
TLogTypeInfo silentInfo(0);
if (reqCount) {
silentInfo.SetRequestList(reqCount, reqInfos, reqTypes);
strstream temp;
ReadTypeLib(libName, 0, tfScanOnly | tfAllKinds, temp, silentInfo);
char* badName = silentInfo.ExtractRequest();
ErrorIf(badName!=0, IDS_BADTYPENAME, badName);
}
silentInfo.SetCallback(SilentYield);
stat = GenerateFiles(libName, outFiles, silentInfo);
} else {
//
// If first command line arg is an option flag, show help dialog
//
stat = ::DialogBox(hInst, MAKEINTRESOURCE(IDD_HELP), 0,(DLGPROC)HelpProc);
}
return stat;
}
catch (TLocalError& xcpt) {
char msgbuf[80];
const char ** pmsg;
if ( *(pmsg = &xcpt.Message) <= (const char*)IDS_MAX ||
*(pmsg = &xcpt.Title) <= (const char*)IDS_MAX) {
::LoadString(hInst, *(unsigned*)pmsg, msgbuf, sizeof(msgbuf));
*pmsg = msgbuf;
}
::MessageBox(0, xcpt.Message, xcpt.Title, MB_OK);
return 1;
}
catch (xmsg& xcpt) { // should not occur, but check anyway while catching
::MessageBox(0, xcpt.why().c_str(), "Exception", MB_OK);
return 2;
}
}