Форум: "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.47 MB
Время: 0.038 c