Статьи

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. В диалоговом окне найдите название нашей библиотеки. Открыжте ее и нажмите кнопку ОК. Мы подсоединили нашу библиотеку к тестировочному проекту.

Все вышесказанное (Шаг 5) характерно для среды разработки до версии VB5 включительно. VB6, кроме данного способа, предлагает более легкий путь для тестирования и отладки библиотек: Добавьте новый проект StandardEXE, сделайте его стартовым и подключите вновь создаваемую библиотеку, как это было описано выше. Теперь вы можете не просто протестировать Вашу библиотеку, но и сделать это пошагово.

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 поставьте галочку. Нажмите ОК.

К листингу

2001 г.

Hosted by uCoz