Haftungsausschluss: Ich bin kein Experte für IDL (Interface Definition Language, die die Sprache COM-Typen verwendet werden, definieren) oder die Microsoft IDL-Compiler (MIDL), aber ich kam zu den nachstehenden Schlussfolgerungen nach dem Spielen um mit der Typbibliothek für scrrun.dll, die ein ähnliches Problem mit enum hat. Einige dieser Informationen wurde von einem kurzen Blick auf diese DevX Artikel auf IDL und VB6 aufgelesen: IDL for VB Tutorial
VB6 die tatsächliche Enum erwartet einen Namen haben, nicht nur eine Enum, die typedef
ist ‚zu einem Namen d. Der Name __MIDL___MIDL_itf_autosvcs_0469_0002
ist ein Platzhalter, da die ursprüngliche typelib den enum-Namen nicht in demselben typedef
definiert, in dem die enum-Konstanten definiert sind.
Wenn Sie die Typbibliothek in OLE-Viewer ansehen, dann sieht die enum
wahrscheinlich wie folgt aus:
typedef [public] __MIDL___MIDL_itf_autosvcs_0469_0002 LockModes;
typedef enum {
LockSetGet = 0,
LockMethod = 1
} __MIDL___MIDL_itf_autosvcs_0469_0002;
Der erste typedef
den öffentlichen Namen LockModes
als Alias für den automatisch generierten MIDL___MIDL_itf_autosvcs_0469_0002
Namen erstellt, die gegeben wurde die enum
. Wenn die Bibliothek vom ursprünglichen Typ kompiliert wurde, generierte der Compiler midl
den langen __MIDL
-Namen für das ursprüngliche enum
und automatisch erstellte einen Alias typedef
, der darauf zurückleitete.
Die ursprüngliche IDL definiert wahrscheinlich die Enum wie folgt aus:
typedef enum {
LockSetGet = 0,
LockMethod = 1
} LockModes;
Wenn der midl
Compiler eine enum
Definition geschrieben auf diese Weise verarbeitet, es einen Namen für die enum
generiert automatisch (da es fehlt - es sollte erscheinen nach dem Schlüsselwort enum
). Dies ist der Name __MIDL
, den Sie sehen, wenn Sie die Typbibliothek in OLE Viewer anzeigen. Der midl
Compiler generiert auch automatisch eine zweite typedef
, die den typedef
Namen automatisch generiert enum
Namen.
Das Problem ist, dass VB6 Enum, die auf diese Weise erstellt werden, nicht verstehen kann. Er erwartet, dass alles in einem einzigen typedef
sein (dh Sie enum
einen Namen geben, sowie die Benennung der typedef
):
typedef enum LocksMode {
LockSetGet = 0,
LockMethod = 1
} LocksMode;
IDL behandelt typedef
‚s die gleiche Art und Weise, dass C oder C++ tut: Sie don‘ t muss dem enum selbst einen Namen geben, denn der typedef
hat schon einen Namen, aber du kannst dem enum einen Namen geben, wenn du es wählst. Mit anderen Worten, die typedef
und die enum
sind eigentlich zwei separate Entitäten. VB6 passiert, die typedef
und die enum
als zwei verschiedene, aber vage verwandte Dinge zu erkennen, so in Ihrem Fall sieht es typedef
mit dem Namen __MIDL___MIDL_itf_autosvcs_0469_0002
, und es sieht, dass dies ein Alias für eine unbenannte enum ist, und es sieht auch eine typedef
für LockModes
, die ein öffentlicher Alias für die anderen typedef
ist.
Da die erste typedef
öffentlich ist, wird im Objektbrowser ein Eintrag für LockModes
angezeigt, und da es sich um einen Alias für eine Enumeration handelt, werden die Enum-Konstanten auch im Objektbrowser angezeigt. Allerdings hat die tatsächliche enum selbst keinen Namen (so erhält es den funky automatisch generierten Namen im Browser zugewiesen), und VB6 kann die enum nicht verwenden, weil der automatisch generierte Name zufällig in ist VB6 (Namen mit doppelten Unterstrichen werden in VB6 automatisch ausgeblendet).
Um diesen letzten Punkt zu demonstrieren, wenn Sie diesen Code in Ihrem VB6 eingeben, wird Intellisense arbeiten und es wird kompilieren, aber offensichtlich ist es nicht sehr ideal:
MsgBox COMSVCSLib.[__MIDL___MIDL_itf_autosvcs_0469_0002].LockMethod
Der Grund dieser Code funktioniert, weil Sie ist kann Namen in Klammern setzen, die normalerweise Syntaxfehler verursachen (z. B. Namen, die mit Unterstrichen beginnen), damit VB6 den normalerweise ungültigen Namen akzeptiert. Darüber hinaus funktioniert das Voranstellen der Konstanten mit dem automatisch generierten Namen mit Intellisense, weil es der tatsächliche Name ist, den VB6 mit der enum
assoziiert (erinnern Sie sich an die andere typedef
ist nur ein Alias zurück zu diesem "echten", aber automatisch generierten Namen, und VB6 kann anscheinend nicht alle Teile zusammenfügen, um zu realisieren, dass beide Namen sich auf denselben beziehen enum
).
Anstatt den lächerlich langen Namen wie oben beschrieben einzugeben, können Sie auch auf die Konstanten enum
zugreifen, indem Sie ihnen den Namen der Bibliothek voranstellen. Beispiel: COMSVCSLib.LockMethod
sollte funktionieren. Es ist mir weniger klar, warum das tatsächlich funktioniert, und ich bin nicht sicher, was passieren würde, wenn zwei verschiedene enum
Konstanten mit dem gleichen Namen definieren.
Schließlich könnte dieses Problem eine andere Art und Weise beheben, indem Sie die IDL aus dem OLE-Viewer mit einer benutzerdefinierten IDL-Datei zu erstellen, in denen ersetzen Sie die vorhandenen enum
typedefs mit einem einzigen typedef
für jede enum
, die einfach gibt sowohl die enum
und die typedef
den gleichen Namen (dh typedef enum LockModes { ... } LockModes;
), aber da der OLE Viewer nicht unbedingt gültige IDL generiert, müssten Sie wahrscheinlich noch mehr zwicken, um es tatsächlich zu kompilieren. Wenn Sie dies zum Funktionieren bringen können, können Sie Ihre benutzerdefinierte .tlb
von Ihrem VB6-Projekt (anstelle der COMSVCSLib
-Bibliothek) referenzieren, und die enum
funktioniert so, wie Sie es erwarten würden.
Wenn Sie diesen Weg gehen wollen, gibt es zwei weitere Werkzeuge, die Sie benötigen, die bereits auf dem Entwicklungscomputer installiert werden sollte (aber Sie können nach ihnen suchen müssen):
midl.exe
: Diese Tool kann eine Typelib-Datei (* .tlb) aus einer .idl
Datei erzeugen. So könnte man die IDL aus dem OLE-Viewer in den Editor kopieren, ändern Sie die Enum-Definitionen, wie oben beschrieben, speichern Sie sie als .idl
Datei und übergeben es an midl.exe
, um einen neuen typelib zu machen:
midl my-custom-typelib.idl
regtlib.exe
: Dieses Tool kann eine TLB-Datei, registriert die, wenn Sie es als Referenz zu Ihrem VB6 Projekt hinzufügen können erforderlich werden sollen:
regtlib.exe my-custom-typelib.tlb
Das Erstellen einer benutzerdefinierten typelib ist jedoch wahrscheinlich übertrieben, und wie bereits erwähnt, kann es schwierig sein, eine kompilierbare IDL-Datei basierend auf der Ausgabe aus dem OLE-Viewer zu erhalten, da sie reverse-engineed IDL für die Typbibliothek anzeigt. nicht die ursprüngliche IDL.
@wqw: Ich bin mir nicht sicher über alle technischen Details - diese Antwort basiert auf empirischen Tests. Wenn Sie beispielsweise die von OLE Viewer generierte IDL für scrrun.dll übernehmen und sie in eine neue Typbibliothek mit 'midl.exe' kompilieren, kann VB6 die Enumeration nur dann korrekt anzeigen, wenn Sie der enum _and_ the typedef einen Namen geben die IDL. Andernfalls sehen Sie den 'enum'-Namen im Objektbrowser, aber IntelliSense wird nicht korrekt funktionieren, und wenn Sie sich die enum-Konstanten im Objektbrowser ansehen, wird es sagen, dass die enum's Mitglied einer enum mit einem auto sind -generierter Name –
Sie müssen nicht einmal eine neue Typbibliothek erstellen, um dies zu sehen: Fügen Sie einfach einen Verweis auf 'scrrun.dll' zu einem neuen VB6-Projekt hinzu, öffnen Sie dann den Objektbrowser und schauen Sie sich die' SpecialFolderConst'-Enumeration an. Ja, es wird im Objektbrowser angezeigt, und ja, die Konstanten sind dafür aufgelistet, aber wenn Sie zum Beispiel auf die 'SystemFolder'-Konstante klicken, sagt der Objektbrowser, dass es ein Mitglied von' Scripting .__ MIDL ___ MIDL_itf_scrun_0001_0000_0002' ist. Es sollte sagen, dass die Konstante ein Mitglied von 'Scripting.SpecialFolderConst' ist, aber die Art, wie die Typbibliothek definiert ist, ist nicht 100% kompatibel mit VB6. –
Auch ich sage zu versuchen, meine Antwort ist perfekt (das ist, warum ich einen Disclaimer dort), aber soweit ich sagen kann, diese Erklärung passt zu tatsächlichen Tests. Ich habe eine neue Typbibliothek für sccrun.dll erstellt und die enum typedefs so geändert, dass sie enum-Namen zusätzlich zu den typedef-Namen enthält. Wenn ich diese Typbibliothek zu VB6 hinzufüge, werden die enum im Object Browser korrekt angezeigt aufgeführt als Mitglieder der richtigen Enumeration, und IntelliSense funktioniert ordnungsgemäß.Wenn ich jedoch die technischen Details falsch verstanden habe, könnten Sie eine Antwort mit den richtigen Informationen geben? –