VB 6 Как на VB правильно использовать API функции?

Кирилл

Команда форума
Администратор
Сообщения
13,549
Симпатии
6,003
Баллы
843
#1
Понятно, если есть пример - скопировал, под себя подправил и все.
Но по какому принципу все происходит, если это заранее неизвестно?
Таких функций много, например, последнее с чем столкнулся - получение id терминальной сессии по имени пользователя.
WTSEnumerateSessions
Можно как то пошагово объяснить принципы работы, что бы можно было применять на других функциях?
 

Dragokas

Very kind Developer
Команда форума
Супер-Модератор
Разработчик
Клуб переводчиков
Сообщения
5,917
Симпатии
5,757
Баллы
588
#2
Привет!

Это довольно обширная тема, чтобы охватить всё в рамках одного поста.
Лучше почитать книгу "Эпплман Дан. Win32 API и Visual Basic. Для профессионалов"

В остальном, чтобы начать пользоваться Win API в vb6 достаточно объявить функцию так, как она описана на странице MSDN и вызвать ее, передав соответствующие аргументы.

Объявления можно брать:
- встроенные в VB6 IDE (Add-in => Add-In Manager => VB6 API Viewer => галки Lodead, load on startup. Add-ins => Api Viewer => File => Load text file => Win32API.txt),
- сторонних сборниках (например, "New API Viewer by David Ross Goben", или от Dave Carter, или от Dennis Wallentin.
- лично я декларации всегда пишу вручную, т.к. в упомянутых сборниках часто встречаются ошибки.

Также тебе могут понадобятся объявления констант:
- можно получить через конвертор: Готовые решения и полезные коды на Visual Basic 6.0 - VB - Страница 12 - Киберфорум
- я беру обычно со страниц MSDN поиском, либо через MS Visual Studio, просто объявив include и распечатав через cout.

Если ты не собираешься вручную писать объявления, то инфу ниже можешь не читать,
хотя это поможет в понимании того, как правильно вызывать функции.

===============================================================

Вот пример объявления:

Оригинал на C++:
Код:
BOOL WTSEnumerateSessionsA(
  IN HANDLE          hServer,
  IN DWORD           Reserved,
  IN DWORD           Version,
  PWTS_SESSION_INFOA *ppSessionInfo,
  DWORD              *pCount );
На VB6:
Код:
Private Declare Function WTSEnumerateSessions Lib "Wtsapi32.dll" Alias "WTSEnumerateSessionsA" _
(ByVal hServer As Long, _
ByVal Reserved As Long, _
ByVal Version As Long, _
ByRef ppSessionInfo As Long, _
ByRef pCount As Long) As Long
(для удобства, разбил на несколько строк)

Эта функция не самый лучший вариант, чтобы начать изучение WinAPI с нее. Тем не менее:

Private или Public - область видимости. (для модулей форм и классов API функции можно объявлять только как Private).
Declare - собственно ключевое слово означающее, что мы декларируем функцию, вызываемую из модуля.
Function или Sub - в зависимости от того, что мы вызываем, функцию или процедуру. Процедуры не возвращают значений. Т.е. аналог C++ - это void. Пример: ExitProcess function
Если видишь в начале void, то пишешь Sub, если что-то другое, то это Function.
В C++ возвращаемое значение пишется в самом начале, тогда как в vb6 - наоборот, пишется в самом конце прототипа, см. выше ) As Long
Lib
- модуль из которого будет вызываться функция.
WTSEnumerateSessions - название, по которому мы будем вызывать функцию в нашем vb6 коде. Заметь, что оно без буквы "A" на конце (т.е. оно может не совпадать с реальным названием функции в модуле). Здесь можно написать что угодно, но лучше придерживаться стандарта.
А реальное название указано в Alias "WTSEnumerateSessionsA". Именно с этим именем функция будет вызываться из модуля Wtsapi32.dll.

Изначально, тебе нужно определиться, хочешь ты вызывать юникодные версии функций или ANSI.
ANSI - обычно записываются с буквой A на конце, как WTSEnumerateSessionsA
Unicode - обычно с буквой W на конце, как WTSEnumerateSessionsW

Я предпочитаю Unicode, их проще объявлять, они поддерживают юникодный текст, но ими сложнее пользоваться если не знать правил передачи аргументов по адресу.

ByVal hServer As Long - здесь через запятую начинаются объявления аргументов:
ByVal - означает передачу по значению
ByRef - по ссылке (если аргумент начинается со звёздочки *, т.е. нужно передавать аргумент по указателю, то можно написать ByRef и тогда VB6 сам передаст значение по указателю, исключение: строки).
Отдельно нужно обратить внимание на ** - или pp - значит что это указатель на указатель. В случае с PWTS_SESSION_INFOW *ppSessionInfo, - по описанию мы видим, что это указатель на указатель на массив. Когда ты передаешь в этот аргумент переменную, то она получит адрес начала массива с данными.

Кроме прочего, тебе понадобится задекларировать структуру (пользовательский тип данных) PWTS_SESSION_INFOA (или PWTS_SESSION_INFOW). Эти типы также можно найти в готовых сборниках или написать самому.

===============================================

Как видишь, тема обширная, и я не могут рассказать сразу обо всём.

Есть пример использования конкретно этой функции: Q291789: HOWTO: Use WTSEnumerateSessions Terminal Server Function from VB
Я его не проверял, но могу прокомментировать.

В остальном, если хочется сберечь время, можно найти пример на любом языке и портировать его в VB6.

===============================================

И напоследок хорошая дока по сессиям и WinAPI: Using and Understanding APIs for Terminal Server
 
Последнее редактирование:

Кирилл

Команда форума
Администратор
Сообщения
13,549
Симпатии
6,003
Баллы
843
#3
Именно с этим именем функция будет вызываться из модуля Wtsapi32.dll.
Начал разбирать вопрос.
Какую именно dll нужно использовать, если ее нет в API.txt понимать как?
Например через сайт MS достоверно же будет?
wtsapi32.h header
Грубо говоря ссылка сама за себя говорит, что речь о wtsapi32.dll , верно?
 

Dragokas

Very kind Developer
Команда форума
Супер-Модератор
Разработчик
Клуб переводчиков
Сообщения
5,917
Симпатии
5,757
Баллы
588
#4
В общем-то да. В этом хидере содержится описание прототипов для языка C.
Но тебе об этом сильно беспокоится не нужно. Ты просто берешь то название, которое указано в заголовке статьи MSDN по соответствующей функции.
Даже если не правильно укажешь, не страшно. Программа не упадёт, а остановится. Главное не путать ANSI версию с юникодной. Это будет указано либо в описании функции, либо ее аргументов, либо их типов.
Например,

_WTS_SESSION_INFOA
_WTS_SESSION_INFOW

структуры, которые передаются обсуждаемой функции.

В ANSI версии - LPSTR pWinStationName;
В юникодной - LPWSTR pWinStationName;

LP - Long Pointer. "Длинный" указатель.
W - Wide - "Широкие" символы. Т.е. юникод.
STR - String - строка.
Сообщения объединены:

Грубо говоря ссылка сама за себя говорит, что речь о wtsapi32.dll , верно?
Я видно не верно истолковал твой вопрос.
Ты спрашиваешь, как узнать из какой dll вызывается функция?
Это всё описано в конце статьи MSDN.


Сообщения объединены:

Вообще, на практике WinAPI нужно изучать с чего-нибудь по-легче, вроде функций:

Beep function (Windows)
GetFileAttributesA function
SetFileAttributesA function
GetDriveTypeA function
CopyFile function

Потом переходить к более сложным, у которых идёт заполнение структуры.

Дальше изучить указатели. Рано или поздно с ними придётся иметь дело.

Потом уже разбираться с функциями, которые возвращают массив, вроде обсуждаемой.
 
Последнее редактирование:
Сверху Снизу