Вызов LIMODS из кода
Вложив столько усилий в гарантии правильного использования MFC DLL, можно слегка разочароваться, узнав, что утилита LIMODS заработает, если добавить в исходный код С/С++-приложения всего лишь одну строку:
LoadLibrary ( "LIMODSDLL.DLL");
Основная часть работы LIMODSDLL.DLL сосредоточена в ее функции DllMain, так что никаких других функций вызывать не нужно. Полагаю, что добавление одной строки кода — не слишком большая цена за услуги LIMODS.
Если разрабатываются Visual Basic-программы, то заставить работать LIMODS в их коде немного сложнее, — но не очень. Сначала нужно копировать файлы LIMODS.CLS и INDESIGNMOD.BAS из каталога \SourceCode \LIMODS\VB сопровождающего компакт-диска и добавить их к вашему проекту. Затем нужно создать глобальный экземпляр класса CISLIMODS, показанного в листинге 14-1. Я бы рекомендовал именовать глобальную переменную экземпляра как CLIMODS. Класс CISLIMODS содержит только один метод; его имя Trace, а его входные параметры — такие же, как у метода Debug.Print. Нет никакой возможности перехватить внутренний объект Debug.Print, поэтому, чтобы утилита LIMODS работала в приложении Visual Basic, это приложение нужно компилировать. Если запускать такую программу из IDE, то метод Trace класса CISLIMODS преобразуется в вызов метода Debug. Print, вот почему предложения трассировки можно будет увидеть в окне Immediate.
Кроме того, в проекте нужно определить режим условной компиляции LIMODS=-1, что позволит при компиляции получать необходимые методы класса. Если этого не сделать, то будут получены пустые версии. Условная компиляция позволяет избежать дополнительных расходов на применение LIMODS в тех случаях, когда она не нужна, а расходы на пустые функции можно исключить, окружив все обращения к объекту ClsLIMODS директивами условной компиляции.
Листинг 14-1. LIMDOS.CLSVERSION 1.0 CLASS
BEGIN
MultiUse = -1 'True
Persistable = 0 'NotPersistable
DataBindingBehavior = 0 'vbNone
DataSourceBehavior = 0 'vbNone
MTSTransactionMode = 0 'NotAnMTSObject
END
Attribute VB_Name = "clsLIMODS"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'Copyright (c) 1997-2000 John Robbins — All rights reserved.
' "Debugging Applications" (Microsoft Press)
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Вспомогательный класс LIMODS для разработки приложений Visual Basic
' 1. Включить этот файл класса в Visual Basic-проект и создать в нем
' глобальный экземпляр этого класса. ( Я назвал экземплярную
' переменную "cLIMODS".)
' 2. Чтобы отправлять отсюда предложения трассировки, нужно просто
' вызвать метод cLIMODS.Trace.
' 3. LIMODS активен только в компилированном Visual Basic-приложении.
' Если выполнять объект этого класса под отладчиком VB-IDE, то
' предложения трассировки будут посылаться с помощью регулярного
' оператора трассировки Debug.Print.
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Option Explicit
Private Declare Function LoadLibrary Lib "kerne!32" _
Alias "LoadLibraryA" _
(ByVal IpLibFileName As String) As Long
Private Declare Sub OutputDebugString Lib "kerne!32" _
Alias "OutputDebugStringA" _
(ByVal IpOutputString As String)
Private Declare Function GetModuleFileName Lib "kerne!32" _
Alias "GetModuleFileNameA"
_ (ByVal hModule As Long, _
ByVal IpFileName As String, _
ByVal nSize As Long) As Long
Private Declare Function GetModuleHandle Lib "kerne!32" _
Alias "GetModuleHandleA" _
(ByVal IpModuleName As String) As Long
Private m_Is!nIDE As Boolean
#If LIMODS Then
Private Sub Class_Initialize()
Dim blsInlDE As Boolean
blsInlDE = InDesign()
' If blsInlDE is False, the main module isn't the Visual Basic IDE,
' so I can load LIMODSDLL.DLL.
If (False = blsInlDE) Then
LoadLibrary "LIMODSDLL.DLL"
m_Is!nIDE = False Else
m_IsInIDE = True
End If
End Sub
#End If
#If LIMODS Then
Public Sub Trace(sOut As Variant)
If (True = m_Is!nIDE) Then
Debug.Print sOut
Else
Dim s As String
s = sOut
OutputDebugString s
End If
End Sub
#Else ' LIMODS is *not* conditionally defined.
Public Sub Trace(sOut As Variant)
End Sub
#End If