Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 17.09.2009, 11:37   #1
flug
Пользователь
 
Регистрация: 23.07.2009
Сообщений: 48
По умолчанию Функция обратного вызова и таймер на WinApi

Здравствуйте уважаемые профи.
Помогите пожалуйста разобраться, вот простой пример кода:
Код:
var
  Form1: TForm1;
  TID:DWORD;
  i:integer;


implementation

{$R *.dfm}
procedure TimerProc(Handle:HWND;uMsg:DWORD;idEvent:DWORD;dwTime:DWORD);stdcall;
begin
inc(i);
form1.label1.Caption:=inttostr(i);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
TID:=SetTimer(0,0,500,@TimerProc);
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
KillTimer(0, TID);
end;

end.
Здесь я создаю таймер на WinApi и обратным вызовом выполняю процедуру procedure TimerProc, но вот в чём вопрос, можно ли как нибудь заставить выполняться эту процедуру не используя "@" в строке SetTimer(0,0,500,@TimerProc) наверняка же есть способ. Ну или можно ли как нибудь узнать 'Адpес экземпляpа пpоцедуpы' procedure TimerProc.
flug вне форума Ответить с цитированием
Старый 17.09.2009, 11:51   #2
SuperVisor
Павел Сергеевич
Форумчанин
 
Регистрация: 05.11.2006
Сообщений: 665
По умолчанию

Дело в том, что символ "@" (читается как ЭТ от английского AT) обозначает, что Вы передаете не процедуру, а указатель (адрес в памяти) на нее. Т.е. Вы передаете TPointer.
Обойтись? А для чего? Или, для чего Вам это нужно - правильнее спросить )
Можно, конечно, объявить переменную-указатель и сначала ей присвоить указатель на Вашу функцию, а после передавать в SetTimer, только какой от этого смысл? )
Познавая других, мы познаем себя.
С'est la vie...
SuperVisor вне форума Ответить с цитированием
Старый 17.09.2009, 13:37   #3
flug
Пользователь
 
Регистрация: 23.07.2009
Сообщений: 48
По умолчанию

SuperVisor
Да смысл есть, дело в том что я пользуюсь одной программой в которой встроен скриптовый язык основанный на урезанном паскале и строка SetTimer(0,0,500,@TimerProc); выдаёт ошибку, и тип pointer этой программе тоже не известен, но я видел как люди всёже реализовали таймер правда через dll и вот привожу куски кода:
Код:
type
  TProc=procedure(HandleW, msg, idEvent, TimeSys: LongWord);
var
  TID: LongWord;
  i:integer;

function WtProc(cb:TProc; paramcount:integer):longword;  stdcall; external 'cb.dll';


procedure TimerProc(Handle:HWND;uMsg:DWORD;idEvent:DWORD;dwTime:DWORD);
begin
inc(i);
label1.Caption:=inttostr(i);
end;


var
  pf: LongWord;
begin
  pf:=WtProc(@TimerProc, 4);
  TID:=SetTimer(0, 0, 200, pf);
end;
И вот мне не понятно, что же за преобразования происходит в function WtProc ведь она возвращает в переменную pf значение типа LongWord и SetTimer спокойно принимает переменную pf и всё работает.

Последний раз редактировалось flug; 17.09.2009 в 13:45.
flug вне форума Ответить с цитированием
Старый 17.09.2009, 15:30   #4
alexBlack
Участник клуба
 
Регистрация: 12.10.2007
Сообщений: 1,204
По умолчанию

Скорее всего SetTimer тоже объявлена по-другому. Что-то вроде:

Код:
function SetTimer(hWnd: HWND; nIDEvent, uElapse: UINT;
  lpTimerFunc: DWORD): UINT; stdcall; external 'user32.dll' name 'SetTimer';

procedure TForm3.Button1Click(Sender: TObject);
var W:DWORD;
begin
   W := Integer(Addr(TimerProc));
   TID := SetTimer(0,0, 500, W);
end;
или вообще свой SetTimer используется. А WtProc() скорее всего возвращает указатель на внутреннюю процедуру, которая и вызывает нашу.

И, кстати, почему, WtProc(@TimerProc, 4) можно, а SetTimer(@...) нельзя ?

Последний раз редактировалось alexBlack; 17.09.2009 в 15:33.
alexBlack вне форума Ответить с цитированием
Старый 17.09.2009, 16:06   #5
flug
Пользователь
 
Регистрация: 23.07.2009
Сообщений: 48
По умолчанию

Цитата:
Сообщение от alexBlack Посмотреть сообщение
Скорее всего SetTimer тоже объявлена по-другому...
Да действительно объявлен по другому, извиняюсь что упустил.
вот как там было:
Код:
function SetTimer(hWnd, nIDEvent, uElapse, lpTimerFunc: LongWord): LongWord; stdcall; external 'user32.dll';
Цитата:
И, кстати, почему, WtProc(@TimerProc, 4) можно, а SetTimer(@...) нельзя ?
Сам не знаю, но факт остаётся фактом.

Код:
   W := Integer(Addr(TimerProc));
А вот это то что мне и требовалось, скорее всего в той сторонней dll и происходило такое преобразование.
Всё вопрос решён!!!!!!
Спасибо ОГРОМНОЕ всем, и особенно alexBlack!!!!!

p.s.
Всем жму на весы

Последний раз редактировалось flug; 17.09.2009 в 16:10.
flug вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Содержание прямого или обратного набора Big-kit Общие вопросы Delphi 1 04.06.2009 17:02
Макрос для вызова файла! SStone Microsoft Office Excel 3 02.03.2009 19:58
блокировка вызова 2-го экземпляра формы из dll Roof Общие вопросы Delphi 6 27.08.2008 01:03
Таймер обратного отсчета на С Raptor Помощь студентам 6 08.01.2008 01:11
нужна функция WinApi, которая переводит десятичное число в шестнадцатиричное??? Morskoivolk Win Api 3 02.04.2007 18:14