Указатель на строчный массив (одномерный).

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
BP
Бывалый
Бывалый
 
Сообщения: 234
Зарегистрирован: 17.02.2004 (Вт) 5:34
Откуда: Украина

Указатель на строчный массив (одномерный).

Сообщение BP » 08.09.2004 (Ср) 19:51

Можно ли как то получить это дело в VB?
Я пробовал через CallWindowProc машинным кодом, но в VB это работает крайне нестабильно (через 2 на 3-й). Да и не только это. Некоторые значения возвращяются нормально, некоторые нет.
Например копирование с помощью CopyMemory по psa всегда выдаёт неверные результаты. GetMem тоже не срабатывает. Даже API из OLEAUT32.DLL не работают.
Может я не там копаю? Вобщем мне нужно передать массив по ссылке в модуль класса.

Во всяком случае мне удалось написать код, который возвращает элементы(не саму структуру) типа SAFEARRAY.
Код: Выделить всё
'Указатель на psa
MOV EBX,[EBP+8]
'Сам psa
MOV EAX,[EBX]
'Function=SAFEARRAY.Член
MOV EAX,[EAX+Позиция элемента]


И указатель на нужный мне элемент массива
Код: Выделить всё
;http://basicproduction.nm.ru/ASM/LASM
;Element address
;1-Array [EBP+8] (Указатель на psa)
;2-Index [EBP+12] (VarPtr)
;3-Long variable [EBP+16] (VarPtr)
;4-SafeArrayGetElement [EBP+20] (Получен с помощью GetProcAddress)
Const Array EQU [EBP+8]
Const Psa EQU EBX
Const Index EQU [EBP+12]
Const EPtr EQU [EBP+16]
Const SafeArrayGetElement EQU [EBP+20]

MOV Psa,Array
MOV Psa,[Psa]

PUSH EPtr
PUSH Index
PUSH Psa
CALL SafeArrayGetElement

В результате этих действий адрес первого байта элемента массива, указанного в Index ([EBP+12]) возвращается в EPtr ([EBP+16]).

А этот код ведёт себя нестабильно, т.е. не всегда возвращает верный адрес.
Код: Выделить всё
'Указатель на psa
MOV EBX,[EBP+8]
'Сам psa
MOV EAX,[EBX]


И вызов SafeArrayGetElement из VB возвращает неверный адрес.

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 08.09.2004 (Ср) 20:02

Я чего-то не понял. Тебе нужен адрес массива? так это адрес первого элемента... И без ассемблера - VarPtr.
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

BP
Бывалый
Бывалый
 
Сообщения: 234
Зарегистрирован: 17.02.2004 (Вт) 5:34
Откуда: Украина

Сообщение BP » 08.09.2004 (Ср) 20:29

Мне нужно чтобы модуль класса помнил ссылку на массив модуля формы или другого модуля и мог с ним работать не только тогда когда его передали, а в любое время. VarPtr хорошо конечно, но как я буду узнавать длину массива? Массив то динамический. Нужно чтобы модуль класса сам знал сколько у массива элементов.

codemaster
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 604
Зарегистрирован: 13.02.2004 (Пт) 13:35

Сообщение codemaster » 08.09.2004 (Ср) 20:39

BP писал(а):Мне нужно чтобы модуль класса помнил ссылку на массив модуля формы или другого модуля и мог с ним работать не только тогда когда его передали, а в любое время. [b]


Зачем такой изврат? Что ты хочеш с этого получить?


tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 08.09.2004 (Ср) 20:47

Код: Выделить всё
Declare Function AryPtr Lib "msvbvm60" Alias "VarPtr" (Ary() As Any) As Long

- это?
Возвращает SAFEARRAY*
Изображение

BP
Бывалый
Бывалый
 
Сообщения: 234
Зарегистрирован: 17.02.2004 (Вт) 5:34
Откуда: Украина

Сообщение BP » 08.09.2004 (Ср) 22:31

Спасибо попробую.

А изврат такой:
http://basicproduction.nm.ru/clrlist.rar
Хочу своё творение в виде класса оформить, чтобы не надо было руками всё прописывать.

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 08.09.2004 (Ср) 22:51

Ты плохо читал статью :)
Тебе нужна функция Assign из оной.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

BP
Бывалый
Бывалый
 
Сообщения: 234
Зарегистрирован: 17.02.2004 (Вт) 5:34
Откуда: Украина

Сообщение BP » 08.09.2004 (Ср) 22:53

Declare Function AryPtr Lib "msvbvm60" Alias "VarPtr" (Ary() As Any) As Long

Сам сделал? Я так колдовал с CallWindowProc чтобы массив туда передать, а вот до VarPtr не додумался. Позже проверю. Eщё охота по топикам полазить.

BP
Бывалый
Бывалый
 
Сообщения: 234
Зарегистрирован: 17.02.2004 (Вт) 5:34
Откуда: Украина

Сообщение BP » 08.09.2004 (Ср) 22:56

Я её вообще не читал. Иначе бы вопросов не возникало. Сейчас прочту.

BP
Бывалый
Бывалый
 
Сообщения: 234
Зарегистрирован: 17.02.2004 (Вт) 5:34
Откуда: Украина

Сообщение BP » 08.09.2004 (Ср) 23:01

Я это в принципе всё знаю. Кроме этого вот кустарного объявления. Мог кстати и сам додуматься.

BP
Бывалый
Бывалый
 
Сообщения: 234
Зарегистрирован: 17.02.2004 (Вт) 5:34
Откуда: Украина

Сообщение BP » 08.09.2004 (Ср) 23:12

Хотя нет, не всё. А для Assign нужно вручную создавать или VB-шный тоже прокатит?

BP
Бывалый
Бывалый
 
Сообщения: 234
Зарегистрирован: 17.02.2004 (Вт) 5:34
Откуда: Украина

Сообщение BP » 08.09.2004 (Ср) 23:45

Вот это думаю самый лучший по простоте способ:
Dim Arr1() as [type name], SA1 as SAFEARRAY, Arr2() as [type name], SA2 as SAFEARRAY

PutMem4 ArrPtr(Arr1), VarPtr(SA1)
PutMem4 ArrPtr(Arr2), VarPtr(SA2)

Если скопировать в структуру приёмника структуру источника, то массивы будут разные, а указатели на pvData одинаковые. Так?

Approximator
Постоялец
Постоялец
 
Сообщения: 572
Зарегистрирован: 26.06.2004 (Сб) 3:10

Сообщение Approximator » 09.09.2004 (Чт) 2:40

BP писал(а):Вот это думаю самый лучший по простоте способ:
Dim Arr1() as [type name], SA1 as SAFEARRAY, Arr2() as [type name], SA2 as SAFEARRAY

PutMem4 ArrPtr(Arr1), VarPtr(SA1)
PutMem4 ArrPtr(Arr2), VarPtr(SA2)

Если скопировать в структуру приёмника структуру источника, то массивы будут разные, а указатели на pvData одинаковые. Так?


Само собой это лучший способ. Кстати, пример подобного реферринга я уже приводил вот здесь (см. самый первый пример в топике):
http://bbs.vbstreets.ru/viewtopic.php?t=9286&start=0
С уважением, Approximator.

BP
Бывалый
Бывалый
 
Сообщения: 234
Зарегистрирован: 17.02.2004 (Вт) 5:34
Откуда: Украина

Сообщение BP » 09.09.2004 (Чт) 4:21

Я хотел сделать так:
Скопировать структуру SAFEARRAY из источника в приёмник.

Но тут возникает проблема. Я не могу никак (кроме ассемблера) получить данные структуры SAFEARRAY источника чтобы скопировать их в SAFEARRAY приёмника. GetMem и CopyMemory отказываются работать напрочь. Они просто не читают из памяти. Вероятность ошибки с моей стороны мала. Сделал проверку на Long'ах - всё работает.

В принципе машинный код у меня уже готов. Но может как то всё таки стандартными средствами можно?

Approximator
Постоялец
Постоялец
 
Сообщения: 572
Зарегистрирован: 26.06.2004 (Сб) 3:10

Сообщение Approximator » 09.09.2004 (Чт) 4:46

BP писал(а):Я хотел сделать так:
Скопировать структуру SAFEARRAY из источника в приёмник.

Но тут возникает проблема. Я не могу никак (кроме ассемблера) получить данные структуры SAFEARRAY источника чтобы скопировать их в SAFEARRAY приёмника. GetMem и CopyMemory отказываются работать напрочь. Они просто не читают из памяти. Вероятность ошибки с моей стороны мала. Сделал проверку на Long'ах - всё работает.

В принципе машинный код у меня уже готов. Но может как то всё таки стандартными средствами можно?

Дык, это ж просто. И GSerg уже всё об этом рассказал.

Приведу пример.

Код: Выделить всё
Private Declare Function PutMem4 Lib "msvbvm60" (ByVal pDst As Long, ByVal NewValue As Long) As Long
Private Declare Sub CopyMem Lib "kernel32" Alias "RtlMoveMemory" _
(ByVal pDst As Long, ByVal pSrc As Long, ByVal ByteLen As Long)
Private Declare Function ArrPtr Lib "msvbvm60" Alias "VarPtr" (ByRef vArr() As Any) As Long

Private Type SAFEARRAYBOUND_L '8 bytes
p1_DSize As Long
p2_DLbound As Long
End Type

Private Type SAFEARRAY_L '24 bytes
p1_Dims As Integer
p2_Feat As Integer
p3_ESize As Long
p4_cLocks As Long
p5_pData As Long
Bounds As SAFEARRAYBOUND
End Type

Dim SrcA() as Long,DstA() as Long, DstSA as SAFEARRAY_L,pSSA as Long

...
ReDim SrcA(1 to vArraySize)
'заполняем массив
...
putmem4 VarPtr(pSSA),ArrPtr(SrcA)
CopyMem VarPtr(DstSA),pSSA,24
putmem4 ArrPtr(DstA),VarPtr(DstSA)


А дальше можешь менять интересующие тебя параметры DstSA.
С уважением, Approximator.

BP
Бывалый
Бывалый
 
Сообщения: 234
Зарегистрирован: 17.02.2004 (Вт) 5:34
Откуда: Украина

Сообщение BP » 09.09.2004 (Чт) 5:12

Не работает. И почему то именно CopyMem. Я уже говорил об этом раньше. Может модуль класса виноват?

Approximator
Постоялец
Постоялец
 
Сообщения: 572
Зарегистрирован: 26.06.2004 (Сб) 3:10

Сообщение Approximator » 09.09.2004 (Чт) 5:18

BP писал(а):Не работает. И почему то именно CopyMem. Я уже говорил об этом раньше. Может модуль класса виноват?


Давай весь код, так ничего не понятно. Должно работать. Кстати, у тебя массив-источник динамический (должен быть им!) или как?

И ещё. Тебе по сути необхоидм только указатель на первый элемент массива. Остальное-то можно заполнить ручками. Ссылку на пример, уже приводил выше (посмотри его ещё раз, там я через массив мониторю содержимое секций в сегменте кода непосредственно ссылаясь через SAFEARRAY на конкретную область памяти, безо всякого копирования). Кстати, к сведению, даже в динамических массивах адрес первого элемента (в норме!) остаётся постоянным до "обнуления"массива (до "разрушения" SAFEARRY). Так, что правильно тебе говорили про то, что свой SAFEARRAY необходимо создавать ручками, а затем в его .p5_pData прописывать VarPtr на первый элемент массива. И будь спокоен, пока массив не обнулится как минимум первый элемент у тебя будет виден всегда.
С уважением, Approximator.

BP
Бывалый
Бывалый
 
Сообщения: 234
Зарегистрирован: 17.02.2004 (Вт) 5:34
Откуда: Украина

Сообщение BP » 09.09.2004 (Чт) 5:31

Код: Выделить всё
Private ArrayRef() As String

Код: Выделить всё
Public Property Let SetArray(WorkArray() As String)
Dim SA As SAFEARRAY
Dim pSSA As Long
PutMem4 VarPtr(pSSA), ArrPtr(WorkArray())
CopyMem VarPtr(SA), pSSA, 24
PutMem4 ArrPtr(ArrayRef()), VarPtr(SA)

  MsgBox "cDims=" & SA.cDims & vbCr & _
                        "fFeatures=&H" & Hex$(SA.fFeatures) & vbCr & _
                        "cbElements=" & SA.cbElements & vbCr & _
                        "cLocks=" & SA.cLocks & vbCr & _
                        "pvData=" & SA.pvData & vbCr & _
                        "rgsabound(0).cElements=" & SA.rgsabound.cElements & vbCr & _
                        "rgsabound(0).cLbound=" & SA.rgsabound.lLBound
End Property

BP
Бывалый
Бывалый
 
Сообщения: 234
Зарегистрирован: 17.02.2004 (Вт) 5:34
Откуда: Украина

Сообщение BP » 09.09.2004 (Чт) 5:34

В принципе если не заработает, то у меня всё равно есть запасной вариант. Главное что указатель на массив есть.

Approximator
Постоялец
Постоялец
 
Сообщения: 572
Зарегистрирован: 26.06.2004 (Сб) 3:10

Сообщение Approximator » 09.09.2004 (Чт) 5:39

BP писал(а):
Код: Выделить всё
Private ArrayRef() As String

Код: Выделить всё
Public Property Let SetArray(WorkArray() As String)
Dim SA As SAFEARRAY
Dim pSSA As Long
PutMem4 VarPtr(pSSA), ArrPtr(WorkArray())
CopyMem VarPtr(SA), pSSA, 24
PutMem4 ArrPtr(ArrayRef()), VarPtr(SA)

  MsgBox "cDims=" & SA.cDims & vbCr & _
                        "fFeatures=&H" & Hex$(SA.fFeatures) & vbCr & _
                        "cbElements=" & SA.cbElements & vbCr & _
                        "cLocks=" & SA.cLocks & vbCr & _
                        "pvData=" & SA.pvData & vbCr & _
                        "rgsabound(0).cElements=" & SA.rgsabound.cElements & vbCr & _
                        "rgsabound(0).cLbound=" & SA.rgsabound.lLBound
End Property


Ща буду материться. Здесь же уже обсуждалась тема про то, как получать указатель на SAFEARRAY сложноустроенных типов данных. Кто ж так делает! Вот как надо:
Код: Выделить всё
Public Property Let SetArray(ByRef WorkArray() As String, Optional ByVal vIgnoreMe as Long)
Dim SA As SAFEARRAY
Dim pSSA As Long
CopyMem VarPtr(pSSA), VarPtr(vIgnoreMe)-4,4
CopyMem VarPtr(SA), pSSA, 24
PutMem4 ArrPtr(ArrayRef()), VarPtr(SA)

  MsgBox "cDims=" & SA.cDims & vbCr & _
                        "fFeatures=&H" & Hex$(SA.fFeatures) & vbCr & _
                        "cbElements=" & SA.cbElements & vbCr & _
                        "cLocks=" & SA.cLocks & vbCr & _
                        "pvData=" & SA.pvData & vbCr & _
                        "rgsabound(0).cElements=" & SA.rgsabound.cElements & vbCr & _
                        "rgsabound(0).cLbound=" & SA.rgsabound.lLBound
End Property


Ну, или вот так:
Код: Выделить всё
Public Property Let SetArray(ByRef WorkArray As Variant)
Dim SA As SAFEARRAY
Dim pSSA As Long
CopyMem VarPtr(pSSA), VarPtr(WorkArray)+8,4
CopyMem VarPtr(SA), pSSA, 24
PutMem4 ArrPtr(ArrayRef()), VarPtr(SA)

  MsgBox "cDims=" & SA.cDims & vbCr & _
                        "fFeatures=&H" & Hex$(SA.fFeatures) & vbCr & _
                        "cbElements=" & SA.cbElements & vbCr & _
                        "cLocks=" & SA.cLocks & vbCr & _
                        "pvData=" & SA.pvData & vbCr & _
                        "rgsabound(0).cElements=" & SA.rgsabound.cElements & vbCr & _
                        "rgsabound(0).cLbound=" & SA.rgsabound.lLBound
End Property
С уважением, Approximator.

BP
Бывалый
Бывалый
 
Сообщения: 234
Зарегистрирован: 17.02.2004 (Вт) 5:34
Откуда: Украина

Сообщение BP » 09.09.2004 (Чт) 5:41

То то у меня на АСМ'е получалось. Щаз проверю.

Approximator
Постоялец
Постоялец
 
Сообщения: 572
Зарегистрирован: 26.06.2004 (Сб) 3:10

Сообщение Approximator » 09.09.2004 (Чт) 5:45

BP писал(а):В принципе если не заработает, то у меня всё равно есть запасной вариант. Главное что указатель на массив есть.

Есть указатель на массив? В твоём варианте ты получал не указатель на массива, а указатель на копию массива.
С уважением, Approximator.

BP
Бывалый
Бывалый
 
Сообщения: 234
Зарегистрирован: 17.02.2004 (Вт) 5:34
Откуда: Украина

Сообщение BP » 09.09.2004 (Чт) 5:53

Спасибо, правда случилось тоже что и в моём ассемблерном варианте
Программа VB6 вызвала сбой при обращении к странице памяти в модуле OLEAUT32.DLL по адресу 0167:65369256.

Чуда не произошло. Какая теперь может быть причина?

Approximator
Постоялец
Постоялец
 
Сообщения: 572
Зарегистрирован: 26.06.2004 (Сб) 3:10

Сообщение Approximator » 09.09.2004 (Чт) 5:56

BP писал(а):Спасибо, правда случилось тоже что и в моём ассемблерном варианте
Программа VB6 вызвала сбой при обращении к странице памяти в модуле OLEAUT32.DLL по адресу 0167:65369256.

Чуда не произошло. Какая теперь может быть причина?


А вот это может означать только одно - эта область памяти принадлежит сегменту с защитой от чтения. То есть чтение этого из этой области может вестись, но на уровне приложений только через соответсвующие функции ядра. Нельзя ссылаться структурой SAFEARRAY на данные этой области пмяти и всё. Или же массив приходящий в эту функцию не является динамическим (у такого массива SAFEARRAY не находится на одном и том же месте и в этом случае сбой происходит по причине того, что ты загружаешь в SAFEARRAY какую-то хрень, сам сбой происходит тогда, если этот случай, то это означает, что ошибка происходит тогда, когда ты записываешь указатель на SAFEARRAY в свой массив).
Последний раз редактировалось Approximator 09.09.2004 (Чт) 5:59, всего редактировалось 1 раз.
С уважением, Approximator.

BP
Бывалый
Бывалый
 
Сообщения: 234
Зарегистрирован: 17.02.2004 (Вт) 5:34
Откуда: Украина

Сообщение BP » 09.09.2004 (Чт) 5:56

Не в моём варианте, а с помощью ArrPtr. Я этот адрес могу в переменной хранить а потом получать элементы массива по нему прямо из памяти.

Approximator
Постоялец
Постоялец
 
Сообщения: 572
Зарегистрирован: 26.06.2004 (Сб) 3:10

Сообщение Approximator » 09.09.2004 (Чт) 6:01

BP писал(а):Не в моём варианте, а с помощью ArrPtr. Я этот адрес могу в переменной хранить а потом получать элементы массива по нему прямо из памяти.

Ты сейчас о чём?
С уважением, Approximator.

BP
Бывалый
Бывалый
 
Сообщения: 234
Зарегистрирован: 17.02.2004 (Вт) 5:34
Откуда: Украина

Сообщение BP » 09.09.2004 (Чт) 6:11

Об этом. Просто у меня браузер сильно тормозит. Подцепил что то. А в поле ввода текста буква в секунду набирается. Вот и не успеваю всё цитировать.
Approximator писал(а):
BP писал(а):В принципе если не заработает, то у меня всё равно есть запасной вариант. Главное что указатель на массив есть.

Есть указатель на массив? В твоём варианте ты получал не указатель на массива, а указатель на копию массива.


Через SafeArrayGetElement, который возвращает адрес первого байта заданного элемента. Мне в принципе только адрес и нужен был. Хотя конечно вариант с сылкой был получше. Но не судьба так не судьба.
Последний раз редактировалось BP 09.09.2004 (Чт) 6:18, всего редактировалось 1 раз.

Approximator
Постоялец
Постоялец
 
Сообщения: 572
Зарегистрирован: 26.06.2004 (Сб) 3:10

Сообщение Approximator » 09.09.2004 (Чт) 6:15

Дык, если ты не читаешь этот адрес напрямую из стека или не пользуешься инкапсуляцией (переаёшь в Variant-контейнер), то через Arrptr() ты адрес на указатель SAFEARRAY строкового массива не получишь.
С уважением, Approximator.

BP
Бывалый
Бывалый
 
Сообщения: 234
Зарегистрирован: 17.02.2004 (Вт) 5:34
Откуда: Украина

Сообщение BP » 09.09.2004 (Чт) 6:26

Если мне не изменяет память, то инкапсуляция - это свойство объекта скрывать свои члены. При чём тут это?
Ладно, может я чего не понял. Вот так у меня работало:
Код: Выделить всё
;http://basicproduction.nm.ru/ASM/LASM
;Element address
;1-Array [EBP+8] (Указатель на psa)
;2-Index [EBP+12] (VarPtr)
;3-Long variable [EBP+16] (VarPtr)
;4-SafeArrayGetElement [EBP+20] (Получен с помощью GetProcAddress)
Const Array EQU [EBP+8]
Const Psa EQU EBX
Const Index EQU [EBP+12]
Const EPtr EQU [EBP+16]
Const SafeArrayGetElement EQU [EBP+20]

MOV Psa,Array
MOV Psa,[Psa]

PUSH EPtr
PUSH Index
PUSH Psa
CALL SafeArrayGetElement

А массив я передавал так:
Private Declare Function ArrayInfo Lib "user32.dll" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, hwnd() As Any, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

Т.е. я просто поменял Long на массив. Но теперь ведь я и Long могу передать.

Approximator
Постоялец
Постоялец
 
Сообщения: 572
Зарегистрирован: 26.06.2004 (Сб) 3:10

Сообщение Approximator » 09.09.2004 (Чт) 6:37

BP писал(а):Если мне не изменяет память, то инкапсуляция - это свойство объекта скрывать свои члены. При чём тут это?
Ладно, может я чего не понял.

А ты видишь "члены" обращаясь с объектом типа Variant? :) Передача чего-либо через вариант всегда является инкапсуляцией.
Вот так у меня работало:
Код: Выделить всё
;http://basicproduction.nm.ru/ASM/LASM
;Element address
;1-Array [EBP+8] (Указатель на psa)
;2-Index [EBP+12] (VarPtr)
;3-Long variable [EBP+16] (VarPtr)
;4-SafeArrayGetElement [EBP+20] (Получен с помощью GetProcAddress)
Const Array EQU [EBP+8]
Const Psa EQU EBX
Const Index EQU [EBP+12]
Const EPtr EQU [EBP+16]
Const SafeArrayGetElement EQU [EBP+20]

MOV Psa,Array
MOV Psa,[Psa]

PUSH EPtr
PUSH Index
PUSH Psa
CALL SafeArrayGetElement

А массив я передавал так:
Private Declare Function ArrayInfo Lib "user32.dll" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, hwnd() As Any, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

Т.е. я просто поменял Long на массив. Но теперь ведь я и Long могу передать.


Массив какой? Первичный источник где? И потом, я же уже давал ссылку на топик в трёпе, где обсуждался вызов функций по указателю. Я там кое-что добавил. Посмотри последний пример и .dll к нему.
С уважением, Approximator.

След.

Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 5

    TopList