имя процедуры как аргумент....

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Chell
Начинающий
Начинающий
 
Сообщения: 1
Зарегистрирован: 17.11.2003 (Пн) 19:09

имя процедуры как аргумент....

Сообщение Chell » 17.11.2003 (Пн) 19:22

Такая задача:
Есть ActiveX dll, есть прога которая ее юзает.
кусок проги:

..........
Код: Выделить всё
myActiveXobject.test (progaSub)

..........
Код: Выделить всё
public sub progaSub()
msgbox "ura"
end sub

--------------------------------------------
кусок Дллки:
............
Код: Выделить всё
private sub test (tmpprogaSub as ???)
call tmpprogaSub
end sub

............
--------------------------------------------

т.е. нужно из дллки вызвать процедуру проги имя которой передано в качестве аргумента...
может кто то понял что я хотел спросить? :)

Спасибо за советы и линки!

Rainbow
Человек-радуга
Человек-радуга
 
Сообщения: 543
Зарегистрирован: 13.05.2003 (Вт) 14:16

Сообщение Rainbow » 17.11.2003 (Пн) 20:32

Вопрос понятен. Но у тебя как-то криво спроектировано. Получается, что твоя DLL должна "знать" про основную программу. Да, бывают случаи, когда надо вызвать функцию из dll или в этом же проекте, имя которой становится известно только в рантайме. Тогда используют CallByName. В твоем же случае код можно переделать:

сейчас твой код в DLL выглядит примерно так

Код: Выделить всё
public sub MyDLLSub()
   DoSomething1
   MyMainProjectSub
   DoSomething2
end sub


Раздели его на 2 вызова
Код: Выделить всё
public sub DLLSub1
   DoSomething1
end sub

public sub DLLSub2
   DoSomething2
end sub


Из основной программы вызывай:
Код: Выделить всё
DLLSub1
MyMainProjectSub
DLLSub2


Если тебе надо какого-то события дождаться - значит организуй работу с событиями и вызывай MyMainProjectSub на обработчике.

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

Сообщение GSerg » 18.11.2003 (Вт) 10:05

As String, батенька, As String.
Как сказал alibek, учите матчасть. Функция CallByName.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Rainbow
Человек-радуга
Человек-радуга
 
Сообщения: 543
Зарегистрирован: 13.05.2003 (Вт) 14:16

Сообщение Rainbow » 18.11.2003 (Вт) 12:26

GSerg, ты о чем? Какой As String?

А, ты о типе аргумента!.. Так дело не в том, чтобы вызвать функцию из DLL - тогда понятно, что CallByName. И это уже, кстати, написано :wink:. Chell хочет вызвать функцию DLL, которая по ИМЕНИ вызовет функцию из ОСНОВНОЙ программы. Так же не получится, да и не надо...

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

Сообщение GSerg » 18.11.2003 (Вт) 17:21

Получицца...
Тема такая была недавно совсем. Там предлагалось, чтобы главная прога предоставила библе public non-creatable объект, через который библа могла бы рулить основным. Этому объекту callbyname и направляется.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Rainbow
Человек-радуга
Человек-радуга
 
Сообщения: 543
Зарегистрирован: 13.05.2003 (Вт) 14:16

Сообщение Rainbow » 18.11.2003 (Вт) 18:56

И правда получаецца :oops:
В принципе, действительно, какая разница, чей объект... Можно и из основной в длл его передать...

Вот так ты имел в виду?

основной проект
Код: Выделить всё
Dim mc As MainClass
Dim dc As DLLClass
    Set mc = New MainClass
    Set dc = New DLLClass
   
    dc.DLLSub "DoSomething", mc


DLLClass в DLL
Код: Выделить всё
Public Sub DLLSub(sFunctionName As String, obj As Object)
    CallByName obj, sFunctionName, VbMethod
End Sub



А есть хороший пример, когда такая логика оправдана?

gaidar
System Debugger
System Debugger
 
Сообщения: 3152
Зарегистрирован: 23.12.2001 (Вс) 13:22

Сообщение gaidar » 19.11.2003 (Ср) 16:26

На счет хорошего примера - вряд ли такой есть. Я посмотрел на задачу и меня крайне заинтересовал вполне резонный, на мой взгляд, вопрос - а зачем это надо?

Если писать plugin'ы, то лучше использовать единый интерфейс для dll в котором заренее прописаны основные классы основной программы. Тогда "база" имеет связь с любой библиотекой через них, а там уже что хочешь делай. Можно, например, в функцию передавать код подфункции (список которых возвращает библиотека) - обычное int число, да дальше ... Обычный Select Case.
Вполне логично сделать так. То, что хочет товарищ задающий вопрос мне несколько непонятно ...
The difficult I’ll do right now. The impossible will take a little while. (c) US engineers in WWII
I don't always know what I'm talking about, but I know I'm right. (c) Muhammad Ali

sanches
El compañero
El compañero
 
Сообщения: 823
Зарегистрирован: 09.01.2003 (Чт) 3:58
Откуда: Р_О_С_С_И_Я ! (Питер)

Сообщение sanches » 19.11.2003 (Ср) 18:10

gaidar писал(а):На счет хорошего примера - вряд ли такой есть. Я посмотрел на задачу и меня крайне заинтересовал вполне резонный, на мой взгляд, вопрос - а зачем это надо?

Если писать plugin'ы, то лучше использовать единый интерфейс для dll в котором заренее прописаны основные классы основной программы. Тогда "база" имеет связь с любой библиотекой через них, а там уже что хочешь делай. Можно, например, в функцию передавать код подфункции (список которых возвращает библиотека) - обычное int число, да дальше ... Обычный Select Case.
Вполне логично сделать так. То, что хочет товарищ задающий вопрос мне несколько непонятно ...

А где бы найти инфу поподробнее по plug-ins. А то лично мне не понятно, как это делается.
Изображение

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 19.11.2003 (Ср) 18:18

Можно например представить такую задачу (кстати реальная, у меня это используется).

Есть основная форма (frmDoc), в которой есть ListView с какими-то данными. При DblClick на нем должна открываться форма (frmItem), в которой можно отредактировать значения выбранного элемента. В моем случае это четыре значения: начальный номер, конечный номер и еще два числа. И соответственно две кнопки, OK и Cancel.
Форма frmItem показывается как модальная к frmDoc.
Задачу можно реализовать просто: при нажатии на кнопку форма frmItem не выгружается, а скрывается, в frmDoc в переменные копируется значения из текст-боксов. Затем форма выгружается, а значения вводятся в ListView.
Если надо организовать проверку вводимых данных, то после выгрузки формы и перед вводом данных делается проверка и в случае чего вываливается MessageBox, мол неправильный ввод, повторите.
Но гораздо лучше, если проверка будет осуществляться непосредственно при нажатии на кнопку OK. А если форма frmItem многофункциональная и используется в различных случаях, такую проверку в коде этой формы не сделаешь.
Я делал примерно так:

frmDoc
Код: Выделить всё
Option Explicit
...
Public Function CheckProc(ByVal N1, ByVal N2) As Boolean
CheckProc = ((N1>0 And N1<1000) And (N2>0 And N2<1000))
End Function
...
Private Sub cmdChange_Click()
Dim L As ListItem, N1 As Long, N2 As Long
If lvwDoc.SelectedItem Is Nothing Then Exit Sub
Set L = lvwDoc.SelectedItem
N1 = Val(L.SubItems(1))
N2 = Val(L.SubItems(2))
If frmItem.GetItem(N1, N2, "CheckProc", Me) Then
  L.SubItems(1) = Trim$(Str$(N1))
  L.SubItems(2) = Trim$(Str$(N2))
End If
Set L = Nothing
End Sub


frmItem
Код: Выделить всё
Option Explicit
...
Private FeedbackObject As Object, FeedbackProc As String
...
Public Function GetItem(ByRef N1 As Long, ByRef N2 As Long, Optional ByVal CheckProcName As String, Optional ByVal CheckProcObject As Object) As Boolean
If Len(CheckProcName) > 0 Then
  If CheckProcObject Is Nothing Then
    Set FeedbackObject = Me
  Else
    Set FeedbackObject = CheckProcObject
  End If
  FeedbackProc = CheckProcName
End If
Tag = vbNullString
Text1.Text = Trim$(Str$(N1))
Text2.Text = Trim$(Str$(N2))
Show vbModal
Set FeedbackObject = Nothing
If Tag = "OK" Then
  N1 = Val(Text1.Text)
  N2 = Val(Text2.Text)
End If
Unload Me
End Function

Private Sub cmdCancel_Click()
Tag = "CANCEL"
Hide
End Sub

Private Sub cmdOk_Click()
If Len(FeedbackProc) > 0 Then
  If Not CallByName(FeedbackObject, FeedbackProc, VbMethod, Val(Text1.Text), Val(Text2.Text)) Then
    MsgBox "Error!", vbExclamation, Caption
    Exit Sub
  End If
End If
Tag = "OK"
Hide
End Sub

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
If UnloadMode = QueryUnloadConstants.vbFormControlMenu Then Cancel = True
End Sub
Lasciate ogni speranza, voi ch'entrate.

Rainbow
Человек-радуга
Человек-радуга
 
Сообщения: 543
Зарегистрирован: 13.05.2003 (Вт) 14:16

Сообщение Rainbow » 20.11.2003 (Чт) 12:07

Ну, да. Мысля понятна. Если форма для введения значений супер-многофункциональна (то есть вид формы задается извне, она предназначена для редактирования чисел, строк, дат и еще кучи всего, причем проверки самые разнообразные), или если проверок всяких много из одного класса и они все разные, то придется делать так, как описал alibek.

А если проблема состоит в том, что конкретная форма вызывается из разных классов (или форм), которые имеют разные взгляды на правильность данных, то по мне приятнее использовать интерфейсы.

Создаем класс IFeedback с функцией
Код: Выделить всё
Public Function CheckValue(ByVal nNumber) as Boolean
end Function


frmDoc и остальные, кто использует frmItem будет этот интерфейс имплементить
Код: Выделить всё
Implements IFeedback

Public Function IFeedback_CheckValue(ByVal nNumber) as Boolean
   IFeedback_CheckValue = (nNumber > 0) and (nNumber < 10000)
end function


В frmItem фенкция GetItem будет принимать IFeedback вместо абстрактного Object
Код: Выделить всё
Public Function GetItem(ByRef N1 As Long, ByRef N2 As Long, Optional ByVal CheckProcObject As IFeedback) As Boolean


Только теперь у него совершенно законно будет вызываться CheckValue. И в зависимости от того, кто этот IFeedback на самом деле - rfmDoc или COtherClass - будет вызываться нужная функция проверки.

Я обычно стремлюсь упорядочить такие вещи, потому что тогда ошибки типа "забыл передать параметр" или "передал, но не того типа" будут выявляться уже на этапе компиляции.

gaidar
System Debugger
System Debugger
 
Сообщения: 3152
Зарегистрирован: 23.12.2001 (Вс) 13:22

Сообщение gaidar » 23.11.2003 (Вс) 14:27

sanches писал(а):А где бы найти инфу поподробнее по plug-ins. А то лично мне не понятно, как это делается.


Очень легко - иди на www.pscode.com и ищи plugins :), примеров выше крыши и все достаточно простые, насколько я могу судить.
The difficult I’ll do right now. The impossible will take a little while. (c) US engineers in WWII
I don't always know what I'm talking about, but I know I'm right. (c) Muhammad Ali

sanches
El compa&#241;ero
El compa&#241;ero
 
Сообщения: 823
Зарегистрирован: 09.01.2003 (Чт) 3:58
Откуда: Р_О_С_С_И_Я ! (Питер)

Сообщение sanches » 24.11.2003 (Пн) 23:42

Хех, а до меня че-то и не дошло там поискать :oops: спасибо :)
Изображение


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

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

Сейчас этот форум просматривают: AhrefsBot, Yandex-бот и гости: 6

    TopList