Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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
2-1236664136
AIK
2009-03-10 08:48
2009.04.26
Access Violation


2-1236752941
dort12
2009-03-11 09:29
2009.04.26
!!!! Как разместить компоненты на форме программно


2-1237215031
пикассо
2009-03-16 17:50
2009.04.26
Что не так с utf8?


2-1237269805
igorntk
2009-03-17 09:03
2009.04.26
Как сделать выборку из таблицы с помощью SQL-запроса?


15-1235079002
Юрий
2009-02-20 00:30
2009.04.26
С днем рождения ! 20 февраля 2009 пятница





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский