Форум: "Начинающим";
Текущий архив: 2009.04.26;
Скачать: [xml.tar.bz2];
ВнизПомогите разобраться с CallBack вызовами Найти похожие ветки
← →
Nil (2009-03-04 18:03) [0]я совсем запутался с процедурными типами в 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"
подскажите пож, что не так делаю...
← →
Anatoly Podgoretsky © (2009-03-04 18:14) [1]Вот жто
> Incompatible types: "regular procedure and method pointer"
← →
Nil (2009-03-04 18:29) [2]сорь, но читать я научился, а как regular procedure привести или представить в method pointer пока не нет, зачем и задал вопрос...
← →
Медвежонок Пятачок © (2009-03-04 18:30) [3]метод он у класса.
а регулар он сам по себе
← →
Григорьев Антон © (2009-03-04 18:34) [4]
> как regular procedure привести или представить в method
> pointer
Откуда такое желание? Там, где ожидается процедура, должна быть именно процедура, потому что ссылка на метод требует ещё и ссылки на объект, а заставить вызывающую сторону хранить эту ссылку нет, если это чужой код.
Можно хакерскими методами подсунуть метод там, где нужна процедура, но, чтобы это устойчиво работало, на метод накладываются жёсткие ограничения: нельзя обращаться к полям объекта (не только прямо, но и опосредовано - через свойства, вызовы других методов и т.п.), нельзя вызывать из него виртуальные и динамические методы, и вообще нельзя ничего, что не будет работать без Self. Оно вам надо? С такими ограничениями логичнее делать процедуру.
← →
clickmaker © (2009-03-04 18:49) [5]если ThrItem и ThrData не свойства класса, то нафиг там метод класса?
← →
Nil (2009-03-05 12:11) [6]
>
> Откуда такое желание? Там, где ожидается процедура, должна
> быть именно процедура, потому что ссылка на метод требует
> ещё и ссылки на объект, а заставить вызывающую сторону хранить
> эту ссылку нет, если это чужой код.
>
> Можно хакерскими методами подсунуть метод там, где нужна
> процедура, но, чтобы это устойчиво работало, на метод накладываются
> жёсткие ограничения: нельзя обращаться к полям объекта (не
> только прямо, но и опосредовано - через свойства, вызовы
> других методов и т.п.), нельзя вызывать из него виртуальные
> и динамические методы, и вообще нельзя ничего, что не будет
> работать без Self. Оно вам надо? С такими ограничениями
> логичнее делать процедуру.
усвоил, чем проще тем лучше)
возник попутный вопрос, если вынесу ShowAnalyzeCallback из класса в regular как тогда я смогу обратится к методу Synchronize() класса TThread?
в ShowAnalyzeCallback сейчас есть строчка Synchronize(Upd_VLC_ShowAnalyzeCallback) а если ShowAnalyzeCallback вынесу из класса как тогда выполнить Synchronize(Upd_VLC_ShowAnalyzeCallback)? нельзя же написать Synchronize(TAnalyzeThread.Upd_VLC_ShowAnalyzeCallback)?
← →
Nil (2009-03-05 12:13) [7]
> если ThrItem и ThrData не свойства класса, то нафиг там
> метод класса?
было бы конечно красивее сделать эти переменные свойством класса, но чтобы было наверняка, вынес их из класса чтобы ещё каких нибудь камней не повылазило..
← →
Ega23 © (2009-03-05 12:19) [8]Не используй Synchronize, делай SendMessage, а в форме (или где там) его обрабатывай.
← →
clickmaker © (2009-03-05 14:10) [9]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;
← →
Nil (2009-03-09 15:38) [10]спасибо большое, выручили!
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2009.04.26;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.007 c