Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.04.26;
Скачать: CL | DM;

Вниз

Помогите разобраться с 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;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.014 c
15-1235033921
Empleado
2009-02-19 11:58
2009.04.26
Задачка


2-1236745440
Игорь47
2009-03-11 07:24
2009.04.26
обьект Memo


6-1202570010
Kerk
2008-02-09 18:13
2009.04.26
Connection Timeout у TTCPClient


15-1235674928
MsGuns
2009-02-26 22:02
2009.04.26
КУЕФА Есть почин ! Двое из пяти уже там. Ждем остальных !


2-1237201177
Pavel
2009-03-16 13:59
2009.04.26
Работа с WordDocument