|
Den Dateinamen samt Pfad eines aktuell ausgeführten Projekts (EXE, DLL, OCX) erhalten Sie über die Eigenschaft Path des Visual Basic-Objekts App:
PfadName = App.Path
Doch ein auf einem Form platziertes ActiveX-Control kann mit Visual Basic-eigenen Mitteln nicht den Pfadnamen der ausführbaren Datei in Erfahrung bringen, zu dem dieses Form gehört. Die API-Funktion GetModuleFileName könnte diesen Pfadnamen vielleicht liefern, wenn... ja, wenn Sie das anscheinend von dieser Funktion geforderte Module-Handle zur Verfügung hätten.
"Anscheinend" gefordert? Genau - verzichten Sie einfach darauf und übergeben Sie als Module-Handle den Wert 0, bekommen Sie das Gewünschte. Wie die Dokumentation zu GetModuleFileName aussagt, erhalten Sie dann den Pfadnamen der Datei, von der aus der aufrufende Prozess angelegt wurde. Da ein ActiveX-Control (wie auch eine ActiveX-DLL) In-Process-Komponenten sind, ist der aufrufende Prozess tatsächlich die EXE-Datei, die die Komponente angelegt hat - ergo die EXE-Datei, zu der das Form gehört, auf dem ein ActiveX-Control platziert ist.
Das Module-Handle eines Prozesses, der ein bestimmtes Fenster (Form) angelegt (genauer gesagt: registriert) hat, erfahren Sie über die API-Funktion GetClassLong mit dem Index-Parameter GCL_HMODULE. Damit könnten Sie auch den Pfadnamen von einer fremden Anwendung in Erfahrung bringen, wenn Sie das Handle eines Fensters daraus zur Verfügung haben und wenn diese selbst das betreffende Fenster registriert hat. Bei VB-Forms werden Sie jedoch wenig Glück haben, da diese nicht von der jeweiligen Projekt-EXE registriert werden, sondern zur Laufzeit von der VB-Laufzeit-DLL (MSVBVM60.DLL bzw. MSVBVM50.DLL oder VB40032.DLL) und zur Entwicklungszeit von der EXE der VB-Entwicklungsumgebung (VB6.EXE bzw. VB5.EXE oder VB32.EXE).
Die folgende Funktion GetModulePathName liefert den Pfadnamen der EXE-Datei des aufrufenden Prozesses, wenn Sie den optionalen Parameter zur Übergabe eines Fenster-Handles weglassen oder 0 übergeben. Übergeben Sie dagegen ein Fenster-Handle, erhalten Sie, wie gesagt, den Pfadnamen der EXE, die das Fenster registriert hat.
Private Declare Function GetClassLong Lib "user32" _
Alias "GetClassLongA" (ByVal hWnd As Long, ByVal nIndex As Long) _
As Long
Private Declare Function GetModuleFileName Lib "kernel32" _
Alias "GetModuleFileNameA" (ByVal hModule As Long, _
ByVal lpFileName As String, ByVal nSize As Long) As Long
Private Const GCL_HMODULE = (-16)
Public Function GetModulePathName(Optional hWnd As Long) As String
Dim nResult As String
Dim nLenResult As Long
nResult = Space(260)
nLenResult = Len(nResult)
nLenResult = GetModuleFileName(GetClassLong(hWnd, GCL_HMODULE), _
nResult, nLenResult)
GetModulePathName = Left$(nResult, nLenResult)
End Function
Übergeben Sie im Ereignis ReadProperties eines UserControls das Fenster-Handle (Eigenschaft hWnd) des Parent-Objekts (meistens das Form, auf dem das UserControl platziert wird), können Sie anhand des aus dem zurückgegebenen Pfadnamen extrahierten Dateinamens feststellen, ob das Projekt mit dem betreffenden Form in der VB-Entwicklungsumgebung oder als ausführbare Datei ausgeführt wird. In Visual Basic 6 erhalten Sie in ersterem Falle "...\VB6.EXE", im zweiten Falle "...\MSVBVM60.DLL" zurückgeliefert (VB 5: "...\VB5.EXE oder "...\MSVBVM50.DLL"; VB 4-32: "...\VB32.EXE" oder "...\VB40032.DLL").
Die folgende Funktion IsUserControlExecuted fasst diese Auswertung für alle drei VB-Versionen zusammen:
Public Function IsUserControlExecuted(ByVal hWnd As Long) _
As Boolean
Dim nFileName As String
nFileName = Right$(GetModulePathName(hWnd), 12)
If CBool(nFileName Like "MSVBVM?0.DLL") Or _
CBool(Mid$(nFileName, 2) = "VB40032.DLL") Then
IsUserControlExecuted = True
End If
End Function
Auf diese Weise können Sie beispielsweise eine einfache Kontrolle einrichten, wenn Sie etwa im Rahmen einer Demo- oder Shareware-Version Ihres UserControls verhindern wollen, dass es in einem kompilierten und ausgeführten VB-Projekt verwendet wird.
Eine bequem einzusetzende OCX-Version dieses Moduls finden Sie unter "Vaterschaftsnachweis II".
|