|
Вопрос # 5 788/ вопрос открыт / |
|
Здравствуйте!
Скачал исходник секундомера.
На мультимедийном секундомере вылетает на строке
MMTimer1 := TimeSetEvent(t, 0, @MyTimerCallBackProg, 0, TIME_PERIODIC);
ошибка
[DCC Error] GUI.Form.StopWatch.pas(66): E2010 Incompatible types: 'TFNTimeCallBack' and 'Pointer'
Подскажите, в чем дело??
И какой секундомер лучше использовать, если предполагается что будут нужны миллисекунды??
Приложение: Переключить в обычный режим- unit GUI.Form.StopWatch;
-
- interface
-
- uses
- Windows,
- Messages,
- SysUtils,
- Variants,
- Classes,
- Graphics,
- Controls,
- Forms,
- Dialogs,
- ExtCtrls,
- StdCtrls,
- MMSystem,
- AdvGlowButton;
-
- type
- TGUIFormStopWatch = class(TForm)
- StartButton1: TAdvGlowButton;
- StopButton: TAdvGlowButton;
- Label1: TLabel;
- Timer: TTimer;
- Label2: TLabel;
- procedure StopButtonClick(Sender: TObject);
- procedure StartButton1Click(Sender: TObject);
- procedure TimerTimer(Sender: TObject);
- private
- FirstTick: Integer;
- public
-
- end;
-
- const
- GMillisecondsPerDay = 3600 * 1000 * 24;
-
- var
- GUIFormStopWatch: TGUIFormStopWatch;
-
- implementation
-
- {$R *.dfm}
-
- var
- Cnt1: Integer;
-
-
- procedure MyTimerCallBackProg(uTimerID, uMessage: UINT;
- dwUser, dw1, dw2: DWORD); stdcall;
- begin
-
- TimeToStr(Cnt1 / GMillisecondsPerDay);
-
- end;
-
- procedure TGUIFormStopWatch.StartButton1Click(Sender: TObject);
- const
-
- begin
- FirstTick := Integer(GetTickCount);
- Timer.Interval := 1;
- Timer.Enabled := True;
-
- MMTimer1 := TimeSetEvent(t, 0, @MyTimerCallBackProg, 0, TIME_PERIODIC);
- // Multimedia
- end;
-
- procedure TGUIFormStopWatch.StopButtonClick(Sender: TObject);
- var
- t: Integer;
- begin
- t := Integer(GetTickCount) - FirstTick;
-
-
-
- TimeKillEvent(MMTimer1); // Multimedia
- end;
-
- procedure TGUIFormStopWatch.TimerTimer(Sender: TObject);
- var
- t: Integer;
- begin
- t := Integer(GetTickCount) - FirstTick;
-
- end;
-
- end.
 |
Вопрос задал: Aндрей (статус: 1-ый класс)
Вопрос отправлен: 30 ноября 2011, 17:34
Состояние вопроса: открыт, ответов: 1.
|
Ответ #1. Отвечает эксперт: DNK
Здравствуйте, Aндрей!
По моему все четко сказано: типы 'TFNTimeCallBack' и 'Pointer' не совместимы. Нужно убрать собаку в третьем параметре, которая преобразует нужный процедурный тип в простой указатель.
 |
Ответ отправил: DNK (статус: Студент)
Время отправки: 1 декабря 2011, 09:32
|
Мини-форум вопроса
Всего сообщений: 10; последнее сообщение — 1 декабря 2011, 14:17; участников в обсуждении: 2.
|
DNK (статус: Студент), 30 ноября 2011, 18:48 [#1]:
По моему все четко сказано: типы 'TFNTimeCallBack' и 'Pointer' не совместимы. Выкинь собаку.
"Digital Networked Knight"
|
|
Aндрей (статус: 1-ый класс), 1 декабря 2011, 09:33 [#2]:
Спасибо, с собакой разобрался, но есть еще пару вопросов
1. в процедуру MyTimerCallBackProg при запуске кнопки старт заходит, и в отладчике показывает, что GUIFormStopWatch.Label2.Caption изменен, а вот на форме изменений не видно
2. Через секунд 7-15 вылетает ошибка
Project TPM.Calculator.exe faulted with message: 'access violation at 0x00402ffl: read of address Oxfffffffc'. Process Stopped. Use Step or Run to continue.
Что делаю не так??
Код стал таким:
unit GUI.Form.StopWatch;
interface
uses
Windows,
Messages,
SysUtils,
Variants,
Classes,
Graphics,
Controls,
Forms,
Dialogs,
ExtCtrls,
StdCtrls,
MMSystem,
AdvGlowButton, AdvOfficeImage;
type
TGUIFormStopWatch = class(TForm)
StartButton1: TAdvGlowButton;
StopButton: TAdvGlowButton;
Label1: TLabel;
Timer: TTimer;
Label2: TLabel;
AdvOfficeImage1: TAdvOfficeImage;
AdvGlowButton1: TAdvGlowButton;
procedure StopButtonClick(Sender: TObject);
procedure StartButton1Click(Sender: TObject);
procedure TimerTimer(Sender: TObject);
procedure AdvGlowButton1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
FirstTick: Integer;
procedure Clear;
public
MMTimer1: Integer; // Код мультимедийного таймера
end;
const
GMillisecondsPerDay = 3600 * 1000 * 24;
var
GUIFormStopWatch: TGUIFormStopWatch;
implementation
{$R *.dfm}
var
Cnt1: Integer;
// процедура мультимедийного таймера
procedure MyTimerCallBackProg(uTimerID, uMessage: UINT;
dwUser, dw1, dw2: DWORD); stdcall;
begin
GUIFormStopWatch.Label2.Caption := TimeToStr(Cnt1 / GMillisecondsPerDay);
Inc(Cnt1); // Счетчик срабатывания мультимедиа таймера
end;
procedure TGUIFormStopWatch.AdvGlowButton1Click(Sender: TObject);
begin
Clear;
end;
procedure TGUIFormStopWatch.Clear;
var
t: Integer;
begin
FirstTick := Integer(GetTickCount);
t := Integer(GetTickCount) - FirstTick;
Label1.Caption := TimeToStr(t / GMillisecondsPerDay);
Cnt1 := 0;
Label2.Caption := TimeToStr(Cnt1 / GMillisecondsPerDay);
end;
procedure TGUIFormStopWatch.FormCreate(Sender: TObject);
begin
Self.Clear;
end;
procedure TGUIFormStopWatch.StartButton1Click(Sender: TObject);
const
t = 1; // интервал
begin
Timer.Interval := 1;
Timer.Enabled := True;
MMTimer1 := TimeSetEvent(t, 0, MyTimerCallBackProg, 0, TIME_PERIODIC); // Multimedia
end;
procedure TGUIFormStopWatch.StopButtonClick(Sender: TObject);
var
t: Integer;
begin
t := Integer(GetTickCount) - FirstTick;
Label1.Caption := TimeToStr(t / GMillisecondsPerDay);
Label2.Caption := TimeToStr(Cnt1 / GMillisecondsPerDay);
Timer.Enabled := False;
TimeKillEvent(MMTimer1); // Multimedia
end;
procedure TGUIFormStopWatch.TimerTimer(Sender: TObject);
var
t: Integer;
begin
t := Integer(GetTickCount) - FirstTick;
Label1.Caption := TimeToStr(t / GMillisecondsPerDay);
// Label2.Caption := TimeToStr(Cnt1 / GMillisecondsPerDay);
end;
end.
|
|
DNK (статус: Студент), 1 декабря 2011, 09:44 [#3]:
Aндрей: На счет секундомера четко ответить не смогу. Во-первых что конкретно, узнать количество миллисекунд между моментами или запустить таймер?
"Digital Networked Knight"
|
|
DNK (статус: Студент), 1 декабря 2011, 09:52 [#4]:
Я никогда не пользовался этим таймером. Могу предположить, код меняющий метку выполняется не в основном потоке программы, а VCL это всегда недолюбливало.
"Digital Networked Knight"
|
|
Aндрей (статус: 1-ый класс), 1 декабря 2011, 09:53 [#5]:
Мне нужно сделать нормальный секундомер с миллисекундами
|
|
Aндрей (статус: 1-ый класс), 1 декабря 2011, 09:58 [#6]:
DNK: можно и не в основном потоке, лишь бы работало
|
|
DNK (статус: Студент), 1 декабря 2011, 10:12 [#7]:
...
private
StartTime: TDateTime;
...
procedure TGUIFormStopWatch.StartButton1Click(Sender: TObject);
begin
StartTime := Now;
end;
procedure TGUIFormStopWatch.StopButtonClick(Sender: TObject);
var
t: Integer;
begin
t := MilliSecondsBetween(Now, StartTime);
Label1.Caption := IntToStr(t) + 'ms';
end;
Достаточно нормальный секундомер с миллисекундами?
"Digital Networked Knight"
|
|
Aндрей (статус: 1-ый класс), 1 декабря 2011, 10:19 [#8]:
в общем я так тож думал сделать, но почитал, что системное время обладает погрешностью
Но за вариант спасибо, его тож добавлю
|
|
DNK (статус: Студент), 1 декабря 2011, 12:14 [#9]:
У человека давящего на кнопку мыши погрешность гораздо выше. Или в дальнейшем планируется управлять секундометром через датчики?
"Digital Networked Knight"
|
|
Aндрей (статус: 1-ый класс), 1 декабря 2011, 14:17 [#10]:
Секундомером вроде понятно, но вот незадача:
я проверял как работает этот секундомер со своими:
1. на телефоне секундомер, написанный на java показывает тот же результат
2. на часах секунды идут медленнее (не думаю, что у спортивных часов casio погрешность есть)
|
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|