![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Помогите разобраться с CallBack вызовами
Nil © (2009-03-04 18:03:00)я совсем запутался с процедурными типами в callback вызовах.. чтобы долго не рассказывать вот код:
DataUnit.pas:
....................
TDefragShowStatusCallback=procedure(Data: PDefragDataStruct); CDECL;
TDefragShowMoveCallback = procedure(Item: PItemStruct; Clusters, FromLcn, ToLcn,FromVcn: ULONG64 ); CDECL;
TDefragShowAnalyzeCallback = procedure(Data: PDefragDataStruct; Item:PItemStruct); CDECL;
TDefragShowDebugCallback = procedure(Level: Integer; Item: PItemStruct; Msg: PChar); CDECL;
TDefragDrawClusterCallback= procedure(Data: PDefragDataStruct; ClusterStart, ClusterEnd: ULONG64; Color: Integer); CDECL;
TDefragClearScreenCallback= procedure(Format: PChar); CDECL;
.....................
unit uAnalyzeThread;
interface
uses
Classes, Windows, Graphics, DataUnit;
type
TAnalyzeThread = class(TThread)
private
{ Private declarations }
procedure Upd_VLC_ShowAnalyzeCallback;
procedure ShowAnalyzeCallback(Data: PDefragDataStruct; Item:PItemStruct); CDECL;
protected
procedure Execute; override;
end;
procedure RunJkDefrag(
Path: PWideChar;
Mode: Integer;
Speed: Integer;
FreeSpace: Double;
Excludes: PWideChar;
SpaceHogs: PWideChar;
Running: PInteger;
RedrawScreen: PInteger;
ShowStatus: TDefragShowStatusCallback;
ShowMove: TDefragShowMoveCallback;
ShowAnalyze: TDefragShowAnalyzeCallback;
ShowDebug: TDefragShowDebugCallback;
DrawCluster: TDefragDrawClusterCallback;
ClearScreen: TDefragClearScreenCallback;
DebugMsg: PWideChar);
CDECL;external 'JkDefragLib.dll' name 'RunJkDefrag';
procedure StopJkDefrag(Running: Pointer; TimeOut: Integer);
CDECL;external 'JkDefragLib.dll' name 'StopJkDefrag';
var
spacehogs:pwidechar=nil;
Excludes:pwidechar=nil;
DebugMessages:pwidechar=nil;
running,redrawscreen:integer;
count:integer=0;
ThrItem:PItemStruct;
ThrData: PDefragDataStruct;
implementation
uses Unit1, SysUtils;
procedure TAnalyzeThread.Upd_VLC_ShowAnalyzeCallback;
begin
if(ThrItem<>nil) then form1.label1.caption:= ThrItem^.Path;
form1.label3.caption:= inttostr(ThrData^.CountFragmentedItems);
end;
procedure TAnalyzeThread.ShowAnalyzeCallback(Data: PDefragDataStruct; Item:PItemStruct); CDECL;
begin
ThrItem:=Item;
ThrData:=Data;
Synchronize(Upd_VLC_ShowAnalyzeCallback);
end;
procedure TAnalyzeThread.Execute;
var
PShowAnalyzeCallback: TDefragShowAnalyzeCallback;
begin
// PShowAnalyzeCallback:=ShowAnalyzeCallback;
running:=0;
redrawscreen:=0;
DebugMessages:=nil;
Excludes:=nil;
spacehogs:=nil;
RunJkDefrag('C:', 0, 100, 10, excludes, spacehogs, @running, nil, nil, nil, ShowAnalyzeCallback, nil, nil, nil, nil);
end;
end.
в RunJkDefrag ругается на ShowAnalyzeCallback ошибкой:
[DCC Error] uAnalyzeThread.pas(76): E2009 Incompatible types: 'regular procedure and method pointer'
подскажите пож, что не так делаю...
Nil (2009-03-09 15:38:00) [1]спасибо большое, выручили!
clickmaker (2009-03-05 14:10:00) [2]type
TAnalyzeData = record
ThrItem:PItemStruct;
ThrData: PDefragDataStruct;
end;
PAnalyzeData = ^TAnalyzeData;
procedure ShowAnalyzeCallback(Data: PDefragDataStruct; Item:PItemStruct); CDECL;
var
Data: TAnalyzeData;
begin
Data.ThrItem:=Item;
Data.ThrData:=Data;
SendMessage(form1.Handle, WM_ShowAnalyze, 0, Integer(@Data));
end;
procedure TForm1.WMShowAnalyze(var Msg: TMessage);
var
Data: PAnalyzeData;
begin
Data := PAnalyzeData(Msg.LParam);
if(Data.ThrItem<>nil) then label1.caption:= ThrItem^.Path;
label3.caption:= inttostr(Data.ThrData^.CountFragmentedItems);
end;
Ega23 (2009-03-05 12:19:00) [3]Не используй Synchronize, делай SendMessage, а в форме (или где там) его обрабатывай.
Nil (2009-03-05 12:13:00) [4]
> если ThrItem и ThrData не свойства класса, то нафиг там
> метод класса?
было бы конечно красивее сделать эти переменные свойством класса, но чтобы было наверняка, вынес их из класса чтобы ещё каких нибудь камней не повылазило..
Nil (2009-03-05 12:11:00) [5]
>
> Откуда такое желание? Там, где ожидается процедура, должна
> быть именно процедура, потому что ссылка на метод требует
> ещё и ссылки на объект, а заставить вызывающую сторону хранить
> эту ссылку нет, если это чужой код.
>
> Можно хакерскими методами подсунуть метод там, где нужна
> процедура, но, чтобы это устойчиво работало, на метод накладываются
> жёсткие ограничения: нельзя обращаться к полям объекта (не
> только прямо, но и опосредовано - через свойства, вызовы
> других методов и т.п.), нельзя вызывать из него виртуальные
> и динамические методы, и вообще нельзя ничего, что не будет
> работать без Self. Оно вам надо? С такими ограничениями
> логичнее делать процедуру.
усвоил, чем проще тем лучше)
возник попутный вопрос, если вынесу ShowAnalyzeCallback из класса в regular как тогда я смогу обратится к методу Synchronize() класса TThread?
в ShowAnalyzeCallback сейчас есть строчка Synchronize(Upd_VLC_ShowAnalyzeCallback) а если ShowAnalyzeCallback вынесу из класса как тогда выполнить Synchronize(Upd_VLC_ShowAnalyzeCallback)? нельзя же написать Synchronize(TAnalyzeThread.Upd_VLC_ShowAnalyzeCallback)?
clickmaker (2009-03-04 18:49:00) [6]если ThrItem и ThrData не свойства класса, то нафиг там метод класса?
Григорьев Антон (2009-03-04 18:34:00) [7]
> как regular procedure привести или представить в method
> pointer
Откуда такое желание? Там, где ожидается процедура, должна быть именно процедура, потому что ссылка на метод требует ещё и ссылки на объект, а заставить вызывающую сторону хранить эту ссылку нет, если это чужой код.
Можно хакерскими методами подсунуть метод там, где нужна процедура, но, чтобы это устойчиво работало, на метод накладываются жёсткие ограничения: нельзя обращаться к полям объекта (не только прямо, но и опосредовано - через свойства, вызовы других методов и т.п.), нельзя вызывать из него виртуальные и динамические методы, и вообще нельзя ничего, что не будет работать без Self. Оно вам надо? С такими ограничениями логичнее делать процедуру.
Медвежонок Пятачок (2009-03-04 18:30:00) [8]метод он у класса.
а регулар он сам по себе
Nil (2009-03-04 18:29:00) [9]сорь, но читать я научился, а как regular procedure привести или представить в method pointer пока не нет, зачем и задал вопрос...
Anatoly Podgoretsky (2009-03-04 18:14:00) [10]Вот жто
> Incompatible types: 'regular procedure and method pointer'