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

  • Автор темы Кирилл
  • Дата начала
Кирилл

Кирилл

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

Dragokas

Very kind Developer
Команда форума
Супер-Модератор
Разработчик
Клуб переводчиков
Сообщения
6,075
Реакции
5,855
Баллы
648
Привет!

Это довольно обширная тема, чтобы охватить всё в рамках одного поста.
Лучше почитать книгу "Эпплман Дан. 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,721
Реакции
6,111
Баллы
913
Именно с этим именем функция будет вызываться из модуля Wtsapi32.dll.
Начал разбирать вопрос.
Какую именно dll нужно использовать, если ее нет в API.txt понимать как?
Например через сайт MS достоверно же будет?
wtsapi32.h header
Грубо говоря ссылка сама за себя говорит, что речь о wtsapi32.dll , верно?
 
Dragokas

Dragokas

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

_WTS_SESSION_INFOA
_WTS_SESSION_INFOW

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

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

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

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

11111.png
Post automatically merged:

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

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

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

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

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