Страница: 1 |
Можно ли объявлять API-функции с помощью CallByName? Нацарапайте примерчик.
Ты имеешь ввиду, запускать их на выполнение через эту ф-ю? А вводить гденибуд в текстбоксе? Интересно.... Не пробовал. И главный вопрос: А ЗАЧЕМ? Модуль 1 Option Explicit '*********************************************** '* This module use excelent solution from '* http://www.vbdotcom.com/FreeCode.htm '* how to implement assembly calls directly '* into VB code. '*********************************************** Private Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long Private Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Long) As Long Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (lpDest As Any, lpSource As Any, ByVal cBytes As Long) Private mlngParameters() As Long 'list of parameters Private mlngAddress As Long 'address of function to call Private mbytCode() As Byte 'buffer for assembly code Private mlngCP As Long 'used to keep track of latest byte added to code Public Function CallApiByName(libName As String, funcName As String, ParamArray FuncParams()) As Long Dim lb As Long, i As Integer ReDim mlngParameters(0) ReDim mbytCode(0) mlngAddress = 0 lb = LoadLibrary(ByVal libName) If lb = 0 Then MsgBox "DLL not found", vbCritical Exit Function End If mlngAddress = GetProcAddress(lb, ByVal funcName) If mlngAddress = 0 Then MsgBox "Function entry not found", vbCritical FreeLibrary lb Exit Function End If ReDim mlngParameters(UBound(FuncParams) + 1) For i = 1 To UBound(mlngParameters) mlngParameters(i) = CLng(FuncParams(i - 1)) Next i CallApiByName = CallWindowProc(PrepareCode, 0, 0, 0, 0) FreeLibrary lb End Function Private Function PrepareCode() As Long Dim lngX As Long, codeStart As Long ReDim mbytCode(18 + 32 + 6 * UBound(mlngParameters)) codeStart = GetAlignedCodeStart(VarPtr(mbytCode(0))) mlngCP = codeStart - VarPtr(mbytCode(0)) For lngX = 0 To mlngCP - 1 mbytCode(lngX) = &HCC Next AddByteToCode &H58 'pop eax AddByteToCode &H59 'pop ecx AddByteToCode &H59 'pop ecx AddByteToCode &H59 'pop ecx AddByteToCode &H59 'pop ecx AddByteToCode &H50 'push eax For lngX = UBound(mlngParameters) To 1 Step -1 AddByteToCode &H68 'push wwxxyyzz AddLongToCode mlngParameters(lngX) Next AddCallToCode mlngAddress AddByteToCode &HC3 AddByteToCode &HCC PrepareCode = codeStart End Function Private Sub AddCallToCode(lngAddress As Long) AddByteToCode &HE8 AddLongToCode lngAddress - VarPtr(mbytCode(mlngCP)) - 4 End Sub Private Sub AddLongToCode(lng As Long) Dim intX As Integer Dim byt(3) As Byte CopyMemory byt(0), lng, 4 For intX = 0 To 3 AddByteToCode byt(intX) Next End Sub Private Sub AddByteToCode(byt As Byte) mbytCode(mlngCP) = byt mlngCP = mlngCP + 1 End Sub Private Function GetAlignedCodeStart(lngAddress As Long) As Long GetAlignedCodeStart = lngAddress + (15 - (lngAddress - 1) Mod 16) If (15 - (lngAddress - 1) Mod 16) = 0 Then GetAlignedCodeStart = GetAlignedCodeStart + 16 End Function Форма 1 Form1 На нее кладешь кнопку Command1 Private Declare Function GetDC& Lib "user32" (ByVal hwnd As Long) Private Declare Function ReleaseDC& Lib "user32" (ByVal hwnd As Long, ByVal hdc As Long) Private Sub Command1_Click() Dim a As Long, b As Long Dim s() As Byte, x As Long, y As Long s = StrConv("Hello !", vbFromUnicode) b = 15 x = CallApiByName("user32", "SetWindowTextA", hwnd, VarPtr(s(0))) Debug.Print "x= ", x x = CallApiByName("kernel32", "RtlMoveMemory", VarPtr, VarPtr(b), 4&) Debug.Print "a= ", a x = CallApiByName("user32", "FlashWindow", hwnd, 1&) Debug.Print "x= ", x dc1 = GetDC(hwnd) x = CallApiByName("user32", "GetDC", hwnd) Debug.Print "x= ", x, "dc= ", dc1 x = ReleaseDC(hwnd, dc1) End Sub Спасибо alex. Я всегда знал что БЕЙСИКЕ есть все лазейки к программированию на низком уровне. Не удивлюсь если обнаружится какая-нибудь комнада типа POKE. MAGNUS - почти угадал. Только не в текстбоксе, а в тексовом фйле. Зачем ? Сложный вопрос. Хочу состряпать что-нибудь монструозное. Да... код хороший ничего не скажешь, но только вот вижу я ему всего одно применение: Если нужно вызывать ну ОЧЕНЬ много АПИ, то используя этот код можно сэкономить на декларациях, а в фругих случаях проще , надежнее и безопаснее вызывать просто сами ф-ии, которые то кстати говоря и сами по себе частенько могут вытащить на свет божий из недр чикаги какой нибудь шедевр ошибкоописательного искуства.... Да еще забыл кое что... А как по поводу апишек которые работают с некоторыми структурами, читают или пишут в них? Как им то парамтры передашь? Не могу согласиться с тобой. Во первых всё зависит от внимания и опыта (имеется ввиду автоматизм) программиста. Конечно встаёт вопрос об авторском праве. Но такая программа не расчитана на копирайт. Я думаю такая форма программирования не распространена (хотя кто знает) из-за невозможности взымания платы. Иначе Микрософт давно бы уже обанкротилась. OK! В принципе согласен, НО.. Неужели ты будешь использовать такой кусок кода ради 5-10 апишек? Хотя в принципе используя этот вариант да еще добавив оригинальную CallByName можно наваять что то вроде компилятора который будет исполнять твои текстовые файлы, подозреваю именно этим ты сейчас и занят ... ) А CyRax? Честно говоря создание компилятора выходит за пределы моих возможностей. Я пока только собираю информацию. Её ещё явно недостаточно. Так, я не получил ответ на следующий мой топик http://www.vbnet.ru/forum/show.asp?id=4409 А сейчас пытаю создать доделать программу создания файлов RTF для HelpWorkShop (HTMP HelpWorkShop кстаи поддерживает проекты для обычного). Если есть время - можешь помочь. Я её создаю не для себя, а для программистов. Ответ на первоначальный вопрос: думаю, если АПИ объявить Public, то можно: CallByName Me, "ShellExecute" , параметры В принципе то можно, но изююминка приведенного выше кода была в том что нужные АПИ обьявлять не нужно, Имея этот кусок кода можно вызывать любое их количество без предварительных деклараций. Именно поэтому я и говорил что тут можно сэкономить на декарациях при необходимости вызова большого количества функций. Да и для исполнений их из файла лод действительно почти идеально подходит. А я как раз использовал этот кусок кода для своего интерпретатора, ScriptCOM http://scriptcom.narod.ru/ С помошью него я реализовал вызов АPI функций из VBS скриптов... Да... CallByName предназначена для обращения к функциям и процедурам ActiveX контролов и библиотек, описанным в TypeLib'е. alex, ты спёр мою идею)) так как времени на реализацию интерпретатора скриптов у меня нету(, с удовольствием взгляну на твой. Страница: 1 |
Вопрос: API - CallByName
Добавлено: 09.10.02 21:51
Автор вопроса: CyRax | Web-сайт:
Ответы
Всего ответов: 12
Номер ответа: 1
Автор ответа:
MAGNUS
Вопросов: 12
Ответов: 430
Профиль | | #1
Добавлено: 10.10.02 14:14
Номер ответа: 2
Автор ответа:
alex
Вопросов: 84
Ответов: 453
Профиль | | #2
Добавлено: 10.10.02 19:08
Номер ответа: 3
Автор ответа:
CyRax
Разработчик Offline Client
ICQ: 204447456
Вопросов: 180
Ответов: 4229
Web-сайт:
Профиль | | #3
Добавлено: 10.10.02 19:39
Номер ответа: 4
Автор ответа:
MAGNUS
Вопросов: 12
Ответов: 430
Профиль | | #4
Добавлено: 10.10.02 20:12
Номер ответа: 5
Автор ответа:
MAGNUS
Вопросов: 12
Ответов: 430
Профиль | | #5
Добавлено: 10.10.02 20:16
Номер ответа: 6
Автор ответа:
CyRax
Разработчик Offline Client
ICQ: 204447456
Вопросов: 180
Ответов: 4229
Web-сайт:
Профиль | | #6
Добавлено: 10.10.02 21:24
Во вторых, все неправильные функции можно исправить непосредственно в текстовом файле. Удобство налицо.
Ну а втретьих, ты всегда можешь добавить нехватающие ко[sensored]ы или функции, либо изменить существующие.
Есть ещё в четвёртых. Не нужно устанавливать VB на машину. Ну, как в GW-Basice, там вообще не было компилятора. Хотя тут есть некоторая потеря в скорости. С памятью конечно быстре работать, чем диском. Но преимущество окупает себя.
Номер ответа: 7
Автор ответа:
MAGNUS
Вопросов: 12
Ответов: 430
Профиль | | #7
Добавлено: 10.10.02 21:36
Номер ответа: 8
Автор ответа:
CyRax
Разработчик Offline Client
ICQ: 204447456
Вопросов: 180
Ответов: 4229
Web-сайт:
Профиль | | #8
Добавлено: 10.10.02 21:51
Номер ответа: 9
Автор ответа:
Павел
Администратор
ICQ: 326066673
Вопросов: 368
Ответов: 5968
Web-сайт:
Профиль | | #9
Добавлено: 11.10.02 09:58
Номер ответа: 10
Автор ответа:
MAGNUS
Вопросов: 12
Ответов: 430
Профиль | | #10
Добавлено: 11.10.02 13:49
Номер ответа: 11
Автор ответа:
alex
Вопросов: 84
Ответов: 453
Профиль | | #11
Добавлено: 11.10.02 15:41
Номер ответа: 12
Автор ответа:
vitOS
Вопросов: 1
Ответов: 17
Web-сайт:
Профиль | | #12
Добавлено: 13.10.02 05:42