DLL - это просто
Прежде чем начать работу с конкретным примером
я бы хотел вначале несколько подробнее остановиться, что же такое dll в VB.
DLL, созданный в VB, отличается от DLL, созданных на С++, как небо и земля.
Чтобы воспользоваться библиотекой, написанной на С, необходимо задекларировать
конкретную функцию в конкретной библиотеке, и можно пользоваться. Эти
библиотеки представляют иногда такие возможности, которые отсутствуют в самом
VB.
Библиотеки, написанные на VB, несмотря на
одинаковое расширение файлов, структурно принципиально отличаются. Это, так
называемые, ActiveX DLL. И, исходя из их названия, работают, как и любое другое
ActiveX-приложение. То есть данную библиотеку необходимо вначале
зарегистрировать, чтобы VB ее увидел, а затем присоединить к программе. Исходя
из того, что эти библиотеки являются внешними, мы получаем некоторые
ограничения при объявлении типов данных. Например, мы не можем передать
параметр с пользовательским типом данных или с типом как форма или контрол (что
VВ интерпретирует как все тот же пользовательский тип). Возможно, это и
послужило среди программистов причиной низкой популярности данного типа
приложений, созданных на VB. Однако, как и любое другое приложение, оно имеет
свои плюсы, например возможность создания объектно-ориентированного кода.
Создавая свои программы, у каждого накопились
какие-либо свои разработки, уловки, хорошо отлаженные коды. И чтобы их
использовать вы начинаете хранить их в виде текстовых файлов, баз данных или
ссылок на Интернет. Я предлагаю использовать для этого свою библиотеку,
подключаемую к любому своему приложению с уже известными вам функциями.
Шаг 1. Создадим новый проект
ActiveX DLL. Назовем его MyLibrary. Класс, который создается с данным проектом
по умолчанию, сделаем главным, назовем MyLib, и пока закроем. К нему мы
вернемся чуть позже.
Шаг 2. Добавим в проект через
меню Project/Add Class Module.
Изменим его название на FrmFunct. Сюда мы будем добавлять коды функций,
связанных с работой форм. Для примера возьмем возможность показа формы поверх
всех и снятия этой возможности. Для этого в разделе деклараций объявим
API-функцию:
Private
Declare Function SetWindowPos Lib "user32" _
(ByVal hwnd As Long, _
ByVal hWndInsertAfter As Long, _
ByVal x As Long, _
ByVal y As Long, _
ByVal cx As Long, _
ByVal cy As Long, _
ByVal wFlags As Long) As Long
А теперь напишем 2 процедуры, которые и выполняют данные функции.
Public
Sub MakeNormal(Handle As Long)
SetWindowPos Handle, HWND_NOTOPMOST, 0, 0, 0, 0,
TOPMOST_FLAGS
End Sub
Public Sub MakeTopMost(Handle As Long)
SetWindowPos Handle, HWND_TOPMOST, 0, 0, 0, 0, TOPMOST_FLAGS
End Sub
Шаг 3. Добавим еще один класс. Он будет отвечать у нас за
работу с ini-файлами. Соответственно дадим ему имя IniFunct. Объявим 2 API
функции, отвечающие за работу с ini-файлами
Private
Declare Function WritePrivateProfileString Lib "kernel32" _
Alias "WritePrivateProfileStringA" _
(ByVal lpApplicationName As String, _
ByVal lpKeyName As Any, _
ByVal lpString As Any, _
ByVal lpFileName As String) As Long
Private Declare Function GetPrivateProfileString Lib "kernel32" _
Alias "GetPrivateProfileStringA" _
(ByVal lpApplicationName As String, _
ByVal lpKeyName As Any, _
ByVal lpDefault As String, _
ByVal lpReturnedString As String, _
ByVal nSize As Long, _
ByVal lpFileName As String) As Long
и напишем также 2 процедуры.
'Читаем данные из ini
Public
Function ReadINIKey(Section As String, KeyName As String, FileName As String)
As String
Dim RetVal As String
RetVal = String(255, Chr(0))
ReadINIKey = Left(RetVal, GetPrivateProfileString(Section,
KeyName, "", RetVal, Len(RetVal), FileName))
End Function
'Записываем данные в ini
Public
Function WriteInIKey(Section As String, KeyName As String, KeyValue As String,
FileName As String)
WritePrivateProfileString Section, KeyName, KeyValue,
FileName
End Function
NB! Функции, написанные в обоих классах, объявлены как
Public для того, чтобы иметь к ним доступ из вне.
Шаг 4. Вернемся в класс MyLib.
Теперь настало самое время привязать другие классы к нему. Для этого в разделе
деклараций объявим 2 переменные (по одной для каждого класса) с типом этого
класса.
Private
m_FormFunction As FrmFunct
Private m_IniFunction As IniFunct
В процедуре инициализации класса запустим эти переменные, а в процедуре
завершения работы класса – не забудем от них почистить память.
Private
Sub Class_Initialize()
Set m_FormFunction = New FrmFunct
Set m_IniFunction = New IniFunct
End Sub
Private Sub Class_Terminate()
Set m_FormFunction = Nothing
Set m_IniFunction = Nothing
End Sub
Теперь объявим 2 свойства Property Get, соответствующих каждому
классу.
Public
Property Get FormFunction() As FrmFunct
Set FormFunction = m_FormFunction
End Property
Public Property Get IniFunction() As IniFunct
Set IniFunction = m_IniFunction
End Property
Вот, собственно говоря, и все.
Шаг 5. Теперь наступает один из
самых неприятных моментов – это тестирование DLL. Их можно тестировать только в
другом проекте. Поэтому запустите на выполнение наш проект, и откройте еще один
экземпляр VB. Создайте проект Standard EXE. Зайдите в меню Project/References. В
диалоговом окне найдите название нашей библиотеки. Открыжте ее и нажмите кнопку
ОК. Мы подсоединили нашу библиотеку к тестировочному проекту.
NB! Если вы в свойствах проекта не заполняли поле
Description, то в качестве названия будет по умолчанию стоять имя ехе-файла. В
противном случае будет выводиться надпись из поля Description.
Шаг 6. Давайте на примере одной функции
покажем, как работает наша библиотека. В разделе деклараций объявим переменную
с типом нашего основного класса (то есть MyLib). В Form_Load озвучим эту
переменную, а в Form_Unload не забудем освободить от нее память.
Private
Sub Form_Load()
Set ML = New MyLib
End Sub
Private Sub Form_Unload(Cancel As Integer)
Set ML = Nothing
End Sub
На форме разместим 2 кнопки, каждой из которых назначим функцию этого
класса, отвечающего за расположение поверх вcех форм и нормального
расположения.
Private
Sub Command1_Click()
ML.FormFunction.MakeTopMost Me.hWnd
End Sub
Private Sub Command2_Click()
ML.FormFunction.MakeNormal Me.hWnd
End Sub
Запустим проект на тестирование. Вы можете добавлять другие
функции в эти классы или создать новые, определив ту структуру хранения
информации, какую вы хотите.
NB! При компиляции библиотеки происходит автоматическая
регистрация ее на Вашем компьютере. Если же вы переносите ее на другой
компьютер, необходимо позаботиться о ее регистрации там (выполняется с помощью
все того же файла, что и для регистрации ОСХ – т.е. regsvr32.exe, или можно
воспользоваться моей утилитой Reg).
Лирическое отступление. Чуть-чуть об апгрейдах. Вполне
вероятно, что вы найдете что-либо новое, которое перечеркнет ваши предыдущие
функции. Мой совет – не удаляйте их. Иначе произведя апгрейд, вы можете
столкнуться с тем, что в какие-то ваши программы не будут работать, т.к. они опирались
на удаленные функции. Скройте их. Они вам не будут мозолить глаза при работе в
программе, и вместе с тем они будут продолжать работать. Для того чтобы скрыть
функцию выберите меню Tools/Procedure
Attributes. Выберите необходимую (-ые) функцию, нажмите кнопку
Advanced>> и в поле Hide this member поставьте галочку. Нажмите ОК.