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

Вниз

подмена WndProc   Найти похожие ветки 

 
jonni   (2003-08-18 02:51) [0]

идея значит вот какая......

пишу класс.... из себя он представляет простое окно определённого названия класса.

В главной программе я регестрирую класс.

И далее уже пользуясь своим классом создаю несколько окон.

мой Create у класса:
//создаю окно
CreateWindowEx(bla bla bla);

//переопределяю WndProc
oldLV:=Pointer(SetWindowLong(hTrayIconWnd,GWL_WNDPROC,longint(@IconWnd Proc)));

где function IconWndProc(Wnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; определена таким образом.

ВСЁ РАБОТАЕТ ПРЕКРАСТНО, НО.....

у меня в классе определена переменная:
TMyClass=class;
private
myperemennay:String;
.............

Мне её нужно использовать в функцие IconWndProc, НО т.к. функция IconWndProc не являеться объектом и/или методом класса, мне переменная myperemennaya в теле функции не доступна!!!!

как мне можно решить эту проблему???

нужно либо делать IconWndProc методом классаа (Я НЕ МОГУ ДОБИТЬСЯ ЧТО БЫ ВСЁ ПРИ ЭТОМ РАБОТАЛО.... делая так:
определяя функцыю в классе и описываю вот так:
TMyClass.IconWndProc():LRESULT;stdcall;
и соответственно
oldLV:=Pointer(SetWindowLong(hTrayIconWnd,GWL_WNDPROC,longint(@TMyClas s.IconWndProc)));
НЕ РАБОТАЕТ
), либо как то получать переменние данного класса... как это сделать я не знаю....

всё написано только на API (Windows,Messages)..

если кто с этим сталкивался расскажите пожалуйста.


 
Крот   (2003-08-18 08:33) [1]

Посмотри как в Dlephi устроена подмена WndProc в классе TWinControl


 
Игорь Шевченко   (2003-08-18 10:10) [2]

MakeObjectInstance


 
jonni   (2003-08-18 13:13) [3]

to Крот:
я уже посмотрел....... как то..... не получилось.....

to Игорь Шевченко:

MakeObjectInstance......хмм.... а где это такое???
на скока я понимаю (точнее мне Delphi skazalo) это в Forms.pas.. а у меня то ведь только Windows,MEssages... и всё... :(

может есть что конкретного посоветовать?


 
Игорь Шевченко   (2003-08-18 14:13) [4]


> нужно либо делать IconWndProc методом классаа (Я НЕ МОГУ
> ДОБИТЬСЯ ЧТО БЫ ВСЁ ПРИ ЭТОМ РАБОТАЛО.... делая так:


MakeObjectInstance.

RTFS: forms.pas


 
VMcL   (2003-08-18 16:44) [5]

>Игорь Шевченко © (18.08.03 14:13) [4]

D6 - Classes.pas


 
PVOzerski   (2003-08-18 17:30) [6]

Может, мой путь и извратный, но я когда-то использовал в похожей задаче GetWindowLong и SetWindowLong. Сначала один раз загонял по GWL_USERDATA адрес экземпляра класса, потом на каждом сообщении извлекал это значение и передавал всё полученное в метод Dispatch. Получалось, как в VCL, даже message handler"ы в стиле Delphi работали, хотя механизм совсем другой.


 
jonni   (2003-08-18 18:00) [7]

to VMcL и >Игорь Шевченко

извините но я же писал что у меня нету ничего кроме Windows.pas i messages.pas

я пишу ТОЛЬКО на API

to PVOzerski что такое адресс экземпляра класса??
как его получить??
что с ним можно делать?


 
PVOzerski   (2003-08-18 18:26) [8]

2jonni © (18.08.03 18:00):
по сути, сама переменная типа класс.
т.е.,
type
tMyClass=class(...
...
end;
....
var
MyClass:tMyClass;
так вот, этот MyClass и есть то самое, что надо "пристегнуть" к окошку через SetWindowLong. А в callback"е вытягивать его через GetWindowLong как longint, приведением типов обращать в tMyClass и вызывать его Dispatch.


P.S. В описании класса в методе DefaultHandler делал вызов DefWindowProc.


 
Марсианин   (2003-08-18 18:55) [9]

>PVOzerski © (18.08.03 17:30) [6]
по-моему это самый нормальный способ. Фень Юань например только так и делает


 
jonni   (2003-08-18 21:10) [10]

Фень Юань делает вот как...........

регистрасия класса:
//----------------------------
wcex.lpfnWndProc = (WNDPROC)(void *)m_Thunk;
//----------------------------

Create в самом классе ():
//----------------------------
ThunkInit(m_Thunk, this);
(WNDPROC)SetWindowLong(m_hWnd,GWL_WNDPROC,(LONG)(void *)m_Thunk);
//----------------------------
m_Thunk ThunkData; <--- конечно же....

где собственно:

typedef unsigned char ThunkData[9];
и
void inline ThunkInit(ThunkData t, void * This)
{ t[0] = 0xB9; // mov ecx,
*((DWORD *)(t+1)) = (DWORD) This; // this
*((DWORD *)(t+5)) = 0x20FF018B; // mov eax, [ecx]
// jmp [eax]
}

КАК ЭТО ПЕРЕВЕСТИ НА Delphi
помогите плз.....


 
Ray Adams   (2003-08-19 00:37) [11]

Грубый косук из моей программы для работы с OpenGl. Там есть обьект TRWinGl=class(TObject), который сам создает окно и использует свои же методы для обработки.
private
procedure WndProc(var AMsg: TMessage);
public
FNewWndProc:pointer;

FNewWndProc := Classes.MakeObjectInstance(WndProc);//Поучаем адрес
h_Wnd := CreateWindowEx(dwExStyle, // Extended window styles
"OpenGL", // Class name
PChar(FWND_TITLE), // Window title (caption)
dwStyle, // Window styles
0, 0, // Window position
Width, Height, // Size of window
0, // No parent window
0, // No menu
hInstance, // Instance
FNewWndProc); // Pass self
------
Может не совсем понятно обьяснил, просто не могу сюда запихать весь текст из юнита.


 
jonni   (2003-08-19 00:59) [12]

to Ray Adams dlya togo chto bi ispol"zovat" Classes.MakeObjectInstance(WndProc) нужен модуль Classes, а я не использую этот модуль!!! только Windows&Messages....

люди помогите перевести C++(код выше ) на Delphi плиззз


 
Крот   (2003-08-19 06:15) [13]

type
TThuncData = Array[0..8] of byte;

procedure ThunkInit(t: TThunkData; this: Pointer)
begin
t[0] := $b9;
Move(t[1], DWORD(this), sizeof(DWORD));
Move(t[1 + (sizeof(DWORD)], $20ff018b, sizeof(DWORD));
end;

//где то в классе есть переменная типа TThunkData
FThunk: TThunkData;

wcex.lpfnWndProc := TFNWndProc(@FThuncData[0]);

//в методе Create

ThunkInit(FThunk, Pointer(self));
SetWindowLong(Handle, GWL_WNDPROC, Pointer(@FThunk));


Мне кажется, так. Но я, признаться, не понял как этот код работает. Похоже на механизм переходников в WTL, но где собственно вызов оконной процедуры? По-моему, в результате всех
этих манипуляций в ecx просто поместили указатель на объект и все.


 
Игорь Шевченко   (2003-08-19 09:05) [14]

jonni © (18.08.03 18:00)

А никто и не говорит об использовании. Но посмотреть, как реализована функция MakeObjectInstance в Forms.pas или в Classes.pas я думаю, религия позволяет ? Или чукча не читатель ни грамма ?


 
Марсианин   (2003-08-19 16:51) [15]

>Игорь Шевченко © (19.08.03 09:05) [14]
идти по стопам Delphi - не самое мудрое решение. там это реализовано СЛИШКОМ сложно. но поглядеть не мешает

>jonni © (18.08.03 21:10) [10]

Фень Юань делает вот как...........


в инете нашел? странно. у меня в книге все по-другому.

посмотри исходник WLTScreensaver на DelphiGFX


 
PVOzerski   (2003-08-20 14:28) [16]

Еще раз вернусь к своему подходу, попробую разжевать.
1) Я делаю обычный callback, никакой не метод класса, и он делает ровно следующее: по прибытии любого сообщения, кроме WM_CREATE, выдергивает из GWL_USERDATA 4 байта, конвертит их в переменную типа мой_класс, и вызывает ее метод dispatch, передавая туда код и параметры сообщения. А уже dispatch вызовет handler"ы-методы а-ля Delphi VCL. Если же сообщение WM_CREATE (оно возникает сразу после CreateWindow<Ex>), в этот момент "штатным образом" по смещению GWL_USERDATA должен жить 0. Если это действительно так (проверить ведь не сложно), перед вызовом dispatch надо загнать туда адрес класса. Для этого я использую глобальную переменную типа tObject, которой непосредственно перед CreateWindow присваиваю значение переменной типа мой_класс, которую хочу "пристегнуть" к окну. Естественно, глобальная переменная доступна из callback-функции, и ее значение без проблем через SetWindowLong загоняется, куда надо. В принципе, конечно, в таком виде конструкция не совсем thread-safe, но ее вполне можно и улучшить.


 
jonni   (2003-08-20 16:19) [17]

и всё же я схожусь к тому что делать надо через GWL_WNDPROC..

oldLV:=Pointer(SetWindowLong(hTrayIconWnd,GWL_WNDPROC,longint(MakeObje ctInstance(@IconWnd Proc))));

vot tak vse chudesno rabotaet no tol"ko problema
v tooy samoy MakeObjectInstance.... v Calsses.pas ona ochen" bol"shaya... logiki poka ya ne ochen" ponyal tam..

zato u Фень Юань vse eto v paru strochek kak vidno...

v исходник WLTScreensaver на DelphiGFX imeet ochen" shozhuyu kartinu kak i u Фень Юань....... pitayus" vikusit" to chto nuzhno....

vsem bol"shoe spasibo... est" teper" nad chem zadumat"sya i v chem razobrat"sya

tol"ko ostalsya vopros.... vse zhe smisl MakeObjectInstance...
videlyaet pamyat" pod snosku na novuyu funkciyu...... chto esche?


 
jonni   (2003-08-20 22:15) [18]

Всем огромное спасиба.......
задача решена.........
//--opisanie classa---
.....
private
FWndCallback,oldproc: Pointer;
function WindowCallback(hWnd: HWnd; Msg, myWParam, myLParam: Longint): Longint; stdcall;
.....
//------------------

//----CREATE CLESS--------
MyWnd:=CreateWindowEx();

FWndCallback := VirtualAlloc(nil, 12, MEM_RESERVE OR MEM_COMMIT, PAGE_EXECUTE_READWRITE);
asm
mov EAX, Self
mov ECX, [EAX].TMyWnd.FWndCallback
mov word ptr [ECX+0], $6858 // pop EAX
mov dword ptr [ECX+2], EAX // push _Self_
mov word ptr [ECX+6], $E950 // push EAX
mov EAX, OFFSET(TMyWnd.WindowCallback)
sub EAX, ECX
sub EAX, 12
mov dword ptr [ECX+8], EAX // jmp TLiteFrame.WindowCallback
end;
oldproc := Pointer(GetWindowLong(MyWnd,GWL_WNDPROC));
SetWindowLong(MyWnd,GWL_WNDPROC,DWORD(FWndCallback));
//---END CREATE CLASS--------

//----destroy class----
......
VirtualFree(FWndCallback, 0, MEM_RELEASE);
......
//----end destroy-------

//---
function TMyWnd.WindowCallback(hWnd: HWnd; Msg, myWParam, myLParam: Integer): Longint;
......
Result := CallWindowProc(oldproc, MyWnd, Msg, myWParam, myLParam);
.....
//---
....


 
имя   (2003-08-21 07:34) [19]

Удалено модератором



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

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

Наверх




Память: 0.5 MB
Время: 0.012 c
14-89505
Думкин
2003-10-09 04:50
2003.10.27
С днем рождения! 9 октября.


14-89492
Мазут Береговой
2003-10-09 01:22
2003.10.27
Сегодня праздник! : Календарь рыболова: Сергии Радонежский


7-89595
aj_ua
2003-08-13 14:49
2003.10.27
Как перегрузить компьютер с коммандной строчки?


7-89591
luckygluck
2003-08-10 17:19
2003.10.27
Включение компьютера


7-89590
Nestor
2003-08-13 07:15
2003.10.27
Уважаемые мастера подскажите как закрывать виндовые приложения.





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