Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - Общий форум

Страница: 1 |

 

  Вопрос: API - CallByName Добавлено: 09.10.02 21:51  

Автор вопроса:  CyRax  | Web-сайт: basicproduction.nm.ru | ICQ: 204447456 

Можно ли объявлять API-функции с помощью CallByName?

Нацарапайте примерчик.

Ответить

  Ответы Всего ответов: 12  

Номер ответа: 1
Автор ответа:
 MAGNUS



Вопросов: 12
Ответов: 430
 Профиль | | #1 Добавлено: 10.10.02 14:14

Ты имеешь ввиду, запускать их на выполнение через эту ф-ю? А вводить гденибуд в текстбоксе? Интересно.... Не пробовал.

И главный вопрос: А ЗАЧЕМ?

Ответить

Номер ответа: 2
Автор ответа:
 alex



Вопросов: 84
Ответов: 453
 Профиль | | #2 Добавлено: 10.10.02 19:08

Модуль 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(a), 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

Ответить

Номер ответа: 3
Автор ответа:
 CyRax



Разработчик Offline Client

ICQ: 204447456 

Вопросов: 180
Ответов: 4229
 Web-сайт: basicproduction.nm.ru
 Профиль | | #3
Добавлено: 10.10.02 19:39

Спасибо alex. Я всегда знал что БЕЙСИКЕ есть все лазейки к программированию на низком уровне. Не удивлюсь если обнаружится какая-нибудь комнада типа POKE.

 

MAGNUS - почти угадал. Только не в текстбоксе, а в тексовом фйле. Зачем ? Сложный вопрос. Хочу состряпать что-нибудь монструозное.

Ответить

Номер ответа: 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-сайт: basicproduction.nm.ru
 Профиль | | #6
Добавлено: 10.10.02 21:24

Не могу согласиться с тобой.

Во первых всё зависит от внимания и опыта (имеется ввиду автоматизм) программиста.
Во вторых, все неправильные функции можно исправить непосредственно в текстовом файле. Удобство налицо.
Ну а втретьих, ты всегда можешь добавить нехватающие ко[sensored]ы или функции, либо изменить существующие.
Есть ещё в четвёртых. Не нужно устанавливать VB на машину. Ну, как в GW-Basice, там вообще не было компилятора. Хотя тут есть некоторая потеря в скорости. С памятью конечно быстре работать, чем диском. Но преимущество окупает себя.

Конечно встаёт вопрос об авторском праве. Но такая программа не расчитана на копирайт. Я думаю такая форма программирования не распространена (хотя кто знает) из-за невозможности взымания платы. Иначе Микрософт давно бы уже обанкротилась.

Ответить

Номер ответа: 7
Автор ответа:
 MAGNUS



Вопросов: 12
Ответов: 430
 Профиль | | #7 Добавлено: 10.10.02 21:36

OK! В принципе согласен, НО.. Неужели ты будешь использовать такой кусок кода ради 5-10 апишек?

Хотя в принципе используя этот вариант да еще добавив оригинальную CallByName можно наваять что то вроде компилятора который будет исполнять твои текстовые файлы, подозреваю именно этим ты сейчас и занят ... :)) А CyRax?

Ответить

Номер ответа: 8
Автор ответа:
 CyRax



Разработчик Offline Client

ICQ: 204447456 

Вопросов: 180
Ответов: 4229
 Web-сайт: basicproduction.nm.ru
 Профиль | | #8
Добавлено: 10.10.02 21:51

Честно говоря создание компилятора выходит за пределы моих возможностей.

Я пока только собираю информацию. Её ещё явно недостаточно. Так, я не получил ответ на следующий мой топик http://www.vbnet.ru/forum/show.asp?id=4409

А сейчас пытаю создать доделать программу создания файлов RTF для HelpWorkShop (HTMP HelpWorkShop кстаи поддерживает проекты для обычного). Если есть время - можешь помочь. Я её создаю не для себя, а для программистов.

Ответить

Номер ответа: 9
Автор ответа:
 Павел



Администратор

ICQ: 326066673 

Вопросов: 368
Ответов: 5968
 Web-сайт: www.vbnet.ru
 Профиль | | #9
Добавлено: 11.10.02 09:58

Ответ на первоначальный вопрос: думаю, если АПИ объявить Public, то можно:

 

CallByName Me, "ShellExecute" , параметры

 

Ответить

Номер ответа: 10
Автор ответа:
 MAGNUS



Вопросов: 12
Ответов: 430
 Профиль | | #10 Добавлено: 11.10.02 13:49

В принципе то можно, но изююминка приведенного выше кода была в том что нужные АПИ обьявлять не нужно, Имея этот кусок кода можно вызывать любое их количество без предварительных деклараций. Именно поэтому я и говорил что тут можно сэкономить на декарациях при необходимости вызова большого количества функций. Да и для исполнений их из файла лод действительно почти идеально подходит.

Ответить

Номер ответа: 11
Автор ответа:
 alex



Вопросов: 84
Ответов: 453
 Профиль | | #11 Добавлено: 11.10.02 15:41

А я как раз использовал этот кусок кода для своего интерпретатора, ScriptCOM

http://scriptcom.narod.ru/

С помошью него я реализовал вызов АPI функций из VBS скриптов...

Ответить

Номер ответа: 12
Автор ответа:
 vitOS



Вопросов: 1
Ответов: 17
 Web-сайт: www.litmodern.narod.ru
 Профиль | | #12
Добавлено: 13.10.02 05:42

Да... CallByName предназначена для обращения к функциям и процедурам ActiveX контролов и библиотек, описанным в TypeLib'е.

alex, ты спёр мою идею:))) так как времени на реализацию интерпретатора скриптов у меня нету:((, с удовольствием взгляну на твой.

Ответить

Страница: 1 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам