Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2005.02.27;
Скачать: [xml.tar.bz2];

Вниз

Реализация функций обратного вызова   Найти похожие ветки 

 
Piter ©   (2005-01-16 19:37) [0]

Вот пишу модуль для работы с RAS. Есть класс, инкапсулирующий RAS соединение.

Но вот незадача - никак не могу решить, что передавать при вызове RasDial.
Туда нужно передать или Handle окна или адрес Callback процедуры для обратной связи (чтобы Windows оповещала о ходе подключения). И как реализовать?

Каждому экземпляру класса создавать окно для связи? Но как указать главную процедуру окна? (не может быть методом класса)
Callback функцию указать тоже не могу - опять же метод класса нельзя указывать...

Пока придумал только одно решение - каждый экземпляр создает окно и с помощью SetWindowLong устанавливает значение GWL_USERDATA, которое является указателем на метод нужного класса.
Соответственно, есть какая-то универсальная процедура окна, которая извлекает GWL_USERDATA и вызывает метод по этому адресу.

Есть решения покрасивее?


 
Anatoly Podgoretsky ©   (2005-01-16 19:55) [1]

Кто тебя заставляет указывать метод класса, кепзывай как сказано процедуру.


 
Piter ©   (2005-01-16 20:21) [2]

Анатолий, но все таки вы наверное понимаете, что классов может быть хоть 1000, а процедура одна?


 
Anatoly Podgoretsky ©   (2005-01-16 20:25) [3]

Ну и что? У меня есть процедуры, которые обслуживают кучу классов. Не вижу никаких проблем. Слово диспетчер, списки, классы тебе знакомо.


 
Anatoly Podgoretsky ©   (2005-01-16 20:27) [4]

Посмотри на DataSource, он один может обслуживать любое голичество визуальных компонент.


 
Piter ©   (2005-01-16 20:29) [5]

Anatoly Podgoretsky ©   (16.01.05 20:25) [3]

Понятно...

То есть, вы предлагаете составить список, где можно будет определить соответствие handle и нужного объекта?


 
Anatoly Podgoretsky ©   (2005-01-16 20:40) [6]

Нет я не предлагаю, а говорю процедуры и классы могут нормально соществовать. А как решать тебе виднее, по твоей задаче.
Все АПИ оно не объектно ориентированое, а большинство программ как раз наоборот и это никак не мешает.
Взляни хоть на туже Indy, ICS, NM


 
Anatoly Podgoretsky ©   (2005-01-16 20:41) [7]

А вот класс, аналогичный DataSource, самое то по задаче и обходится без всяких списков.


 
Набережных С.   (2005-01-16 20:51) [8]

unit MakeInstance;

interface

uses
 Windows;

function MakeInstanceStdCall(Obj: TObject; MethodAddr: Pointer): Pointer;
procedure FreeInstanceStdCall(Inst: Pointer);

implementation

var
 FCS: TRTLCriticalSection;
 BlockList: PInstanceBlock = nil;

const
 Page_Size = 4096;

type
 PInstanceBlock = ^TInstanceBlock;
 TInstanceBlock = packed record
   Code:  array[0..31 - SizeOf(PInstanceBlock)] of Byte;
   Next:  PInstanceBlock;
 end;

 TBlockList = array[0..Page_Size div SizeOf(TInstanceBlock)] of TInstanceBlock;
 PBlockList = ^TBlockList;

procedure FreeInstanceStdCall(Inst: Pointer);
begin
 if Inst = nil then Exit;
 EnterCriticalSection(FCS);
 PInstanceBlock(Inst).Next:=BlockList;
 BlockList:=Inst;
 LeaveCriticalSection(FCS);
end;

function MakeInstanceStdCall(Obj: TObject; MethodAddr: Pointer): Pointer;
const
 CodeBlock: array [0..12] of Byte =
   (
    $58,             // POP EAX
    $68,             // PUSH DWORD_Const <= Obj
     0, 0, 0, 0,
    $50,             // PUSH EAX
    $68,             // PUSH DWORD_Const <= MethodAddr
     0, 0, 0, 0,
    $C3              // RET
    );

type
 PCodeBlock = ^TCodeBlock;
 TCodeBlock = packed record
   Code1:     Word;
   Self:      TObject;
   Code2:     Word;
   MtdAddr:   Pointer;
   Code3:     Byte;
 end;

var
 n: integer;
begin
 EnterCriticalSection(FCS);

 if BlockList = nil then
 begin
   BlockList:=VirtualAlloc(nil, Page_Size, MEM_COMMIT or MEM_TOP_DOWN, PAGE_EXECUTE_READWRITE);
   for n:=0 to (Page_Size div SizeOf(TInstanceBlock)) - 2 do
     PBlockList(BlockList)[n].Next:=@PBlockList(BlockList)[n + 1];
   PBlockList(BlockList)[(Page_Size div SizeOf(TInstanceBlock)) - 1].Next:=nil;
 end;
 Result:=BlockList;
 BlockList:=BlockList.Next;

 LeaveCriticalSection(FCS);

 Move(CodeBlock, Result^, SizeOf(CodeBlock));
 with PCodeBlock(Result)^ do
 begin
   Self:=Obj;
   MtdAddr:=MethodAddr;
 end;
end;

procedure InitProc;
begin
 InitializeCriticalSection(FCS);
end;

procedure FinalProc;
begin
 DeleteCriticalSection(FCS);
end;

initialization
 InitProc;

finalization
 FinalProc;

end.


Метод должен быть объявлен как StdCall и иметь те же параметры, что и callback функция. Пример:

//Прототип: function(SomeParam1: TSome_Type1; SomeParam2: TSome_Type2): bool; stdcall;
TMyClass = class(...
private
 function MyCallBack(SomeParam1: TSome_Type1; SomeParam2: TSome_Type2): bool; stdcall;
end;
var
 MyObj: TMyClass;
 P: Pointer;
...
 P:=MakeInstanceStdCall(MyObj, @TMyClass.MyCallBack);

Полученный указатель передаешь как адрес Callback функции.


 
Piter ©   (2005-01-16 23:56) [9]

Какой-то хакерский код...


 
VMcL ©   (2005-01-17 07:59) [10]

>>Piter ©  (16.01.05 23:56) [9]

Не более хакерский, чем MakeObjectInstance() и иже с ним.

WBW.



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2005.02.27;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.04 c
1-1108466313
Checist [root]
2005-02-15 14:18
2005.02.27
Создание новой формы


14-1107745364
Думкин
2005-02-07 06:02
2005.02.27
С Днем рождения! 7 февраля


9-1101229419
dRake
2004-11-23 20:03
2005.02.27
TankMaze вторая демка :)


6-1103521635
Lex_!
2004-12-20 08:47
2005.02.27
Web-чат.


1-1108021065
KingDog
2005-02-10 10:37
2005.02.27
вот знаете что то при n = 31 не считает





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский