Модераторы: Akina
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Название одной функции как параметр другой 
:(
    Опции темы
I_Am_Rock
Дата 11.8.2010, 23:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 523
Регистрация: 18.1.2008

Репутация: 12
Всего: 15



Всем добрый день.  smile 

Вот такая проблема возникла. Помогите, пожалуйста.

Допустим, две функции. Нужно, чтобы выполнилась та функция, которая указана как параметр другой.

К примеру,
Код


MyFunc2 (MyFunc1)

Function MyFunc1()
'код
End Function


Насколько я понимаю (объясните, если я ошибаюсь) такой же принцип в случае сабклассинга.
Ведь там если SetWindowLong используется с GWL_WNDPROC, то в качестве третьего параметра адрес новой функции для окна.

Но там всё понятно - аддрессоф возвращает адрес функции. 

А вот как мне быть? Как это реализовывается изнутри?

 smile 

Это сообщение отредактировал(а) I_Am_Rock - 12.8.2010, 00:03
PM MAIL WWW   Вверх
Akina
Дата 12.8.2010, 00:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 34
Всего: 454



Если функция является методом объекта - то CallByName().
А если нет... ну сделай обёртку типа

Код

Sub FNCall(FNName As String)
Select Case UCASE(FNName)
  Case "FUNC1"
    Call Func1
  Case "FUNC2"
    Call Func2
  Case "FUNC3"
    Call Func3
'...
  Case Else
    Err.Raise 35
End Select
End Sub



--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
I_Am_Rock
Дата 12.8.2010, 11:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 523
Регистрация: 18.1.2008

Репутация: 12
Всего: 15



Цитата(Akina @  12.8.2010,  00:10 Найти цитируемый пост)
Если функция является методом объекта - то CallByName().

Нет

Цитата(Akina @  12.8.2010,  00:10 Найти цитируемый пост)
А если нет... ну сделай обёртку типа

Не получится - заранее низвестно название функции, переданной как параметр.

Тут вот какое дело.
Допустим, я пишу модуль с функцией FuncIAmRock, которая что-то делает, а затем (в определенный момент) вызывает функцию, как-то переданную ей в виде параметра. Вот эта самая функция - которая передается как параметр - она пишется не мною, а человеком, который и вызывает мою.

Вот как я пытаюсь решить.
Допустим, моя функция сидит в модуле ModuleIAmRock. Другой человек подключает мой модуль к своему проекту.
и вызывает функцию
Код

Private Sub Form_Load()
g = FuncIAmRock(AddressOf SomeFunc)
End Sub


Затем этот же человек пишет свою функцию SomeFunc. Для этого ему надо создать уже свой модуль (ну, это требование addressof, насколько я знаю)

Код

Function SomeFunc()
MsgBox "Hello"
End Function


А вот как я пытаюсь сделать свою функцию. И она работает! - только потом вылетает с ошибкой.
Код

Public 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

Function FuncIAmRock(ByVal z As Long)
CallWindowProc z, 0, 0, 0, 0
End Function


Я понимаю, что CallWindowProc предназначена не для этого, но может ее можно как-то приспособить...


Возможно, кто-нибудь захочет предложить вообще не делать передачу функции как параметр для другой, а просто сделать в моем модуле строгую привязку к SomeFunc и просто сделать это требованием (чтобы человек, который работал бы с моим модулем, называл свою функцию таким именем). Но по определенным причинам, я так не могу сделать. Прошу такой способ не предлагать smile

Я прикрепляю этот тестовый проект.

Добавлено @ 11:37
Проблема решена - здесь тупо не нужно было писать addressof  smile

Добавлено @ 11:43
аааааа  smile 
Теперь новая проблема, но из той же оперы

Вот код формы
Код

Private Sub Form_Load()
g = FuncIAmRock(SomeFunc)
End Sub

Function SomeFunc()
a = 4 + 5
MsgBox a
End Function


А вот код моего модуля
Код

Public 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

Function FuncIAmRock(ByRef z As Long)
MsgBox "1"
CallWindowProc z, 0, 0, 0, 0
MsgBox "2"
End Function


Все работает, но (!!!) сначала показывается 9, а затем 1 и 2. Хотя ведь должен быть такой порядок 1, 9, 2

 smile

Добавлено @ 11:44
А, ну ведь тут происходит вызов функции из функции, а не передача функции как параметра...

Кому не лень было всё это прочитать - подскажите!

Это сообщение отредактировал(а) I_Am_Rock - 12.8.2010, 11:45

Присоединённый файл ( Кол-во скачиваний: 7 )
Присоединённый файл  asdfg.rar 1,46 Kb
PM MAIL WWW   Вверх
Akina
Дата 12.8.2010, 11:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 34
Всего: 454



а так?

Код

Function FuncIAmRock(ByRef z As Long)
MsgBox "1"
DoEvents
CallWindowProc z, 0, 0, 0, 0
MsgBox "2"
End Function



--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
I_Am_Rock
Дата 12.8.2010, 13:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 523
Регистрация: 18.1.2008

Репутация: 12
Всего: 15



Пробовал - аналогично.

Причину я понял - если вызываешь вот так g = FuncIAmRock(SomeFunc), то просто сначала выполняется SomeFunc, а затем сама FuncIAmRock. А CallWindowProc вообще в данном случае не выполняется, потому что в z ничего нет (в данном случае).

Так что это мне только показалось, что это работает.

А на самом деле правильный путь - это моя первая попытка - где аддрессоф - т.е. тот, который в прикрепленном файле в предыдущем посте.

Вот только почему после выполнения CallWindowProc возникает ошибка!! smile 

Это сообщение отредактировал(а) I_Am_Rock - 12.8.2010, 13:27
PM MAIL WWW   Вверх
I_Am_Rock
Дата 12.8.2010, 16:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 523
Регистрация: 18.1.2008

Репутация: 12
Всего: 15



ололо вспомнил, что были уже у меня случаи, когда в среде не запускается, а екзешник работает нормально. Попробовал - и в этом случае так.

Но это не нормальное решение проблемы. Поэтому тему лучше не закрывать, я думаю. У кого будут какие мысли - пишите.

Для тех, кто зайдет в эту тему и не поймет, то правильное решение - это то, что в прикрепленном файле во 2 посте.

Спасибо Akina за то, что пытался помочь  smile 

Это сообщение отредактировал(а) I_Am_Rock - 12.8.2010, 16:14
PM MAIL WWW   Вверх
Akina
Дата 12.8.2010, 16:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 34
Всего: 454



Ну в принципе у Офиса есть функция Eval, которая выполняет оператор из строковой переменной в текущем контексте. Можно попробовать прицепить референсную либу к проекту и использовать - вдруг заработает?

Но вообще при вашей (извини, но черезжопной) методике работы я бы предложил вам оформлять ваши модули в виде модуля класса, а соответственно все процедуры и функции станут методами этого класса. Тогда тебе присылается новая версия модуля, ты заменяешь старый модуль, на старте создаёшь экземпляр класса и спокойно вызываешь нужные тебе процедуры и функции через CallByName. Более того, у тебя появится возможность энумеровать их, проверять существование, получать подсказку и автозаполнение в GUI и прочие вкусности.


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
I_Am_Rock
Дата 12.8.2010, 16:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 523
Регистрация: 18.1.2008

Репутация: 12
Всего: 15



Я объясню почему так. Только не смейся, если я ошибаюсь. ;)

Вообще, задача - написать dll на асме, которая автоматизирует работу с добрым десятком api-функций, а к ней собой доступ через экспортную функцию (это та самая, которую я для примера назвал FuncIAmRock).

Но ассемблер - не такая вещь, где легко пробовать - добавлять и убирать куски кода (по крайней мере, для меня). Поэтому сначала я пишу на VB.

И если я сейчас сделаю через модуль класса, то на асме у меня никаких классов не будет.
PM MAIL WWW   Вверх
Dexx
Дата 12.8.2010, 23:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 292
Регистрация: 13.6.2005

Репутация: 5
Всего: 7



Может так.

пишем dll на асме с этой самой экспортной функцией(с максимально нужным количеством параметров которые нужно будет передавать в вызываемые функции+название вызываемой функции) . 
далее анализируем какую нужно функцию и передаем управление на нужный кусок кода.
но тут все пишется в dll на асме

а в вб
 просто объявляем что то типа 
Код

Public Declare Function FuncIAmRock  Lib "FuncIAmRock"  (ByVal FuncName As any, ByVal, param1 as any, ByVal, param2 as any .....) As Long


пользуем как то так
Код

 FuncIAmRock("kill", procN,0,0,..)


Если трудно пробовать dll на асме, пробуй dll на делфи.

Ну если я что то не так понял извините.

Это сообщение отредактировал(а) Dexx - 12.8.2010, 23:23


--------------------

PM   Вверх
I_Am_Rock
Дата 13.8.2010, 08:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 523
Регистрация: 18.1.2008

Репутация: 12
Всего: 15



Dexx, да я и собираюсь так сделать. С этим проблем нет  smile 
PM MAIL WWW   Вверх
Dexx
Дата 15.8.2010, 01:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 292
Регистрация: 13.6.2005

Репутация: 5
Всего: 7



тогда все вопросы в asm ветку  форума.


--------------------

PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "VB6"
Akina

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по VB обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • Используйте теги [code=vb][/code] для подсветки кода. Используйтe чекбокс "транслит" (возле кнопок кодов) если у Вас нет русских шрифтов.


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Akina.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | VB6 | Следующая тема »


 




[ Время генерации скрипта: 0.0539 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.