Форум: "WinAPI";
Текущий архив: 2003.12.04;
Скачать: [xml.tar.bz2];
ВнизОброботка OnClick Найти похожие ветки
← →
Demetrius2003 (2003-10-04 17:49) [0]Я создал кнопочку на рабочем столе, но так как она принадлежит чужому окну я не могу обрабатывать её события со своего приложения.:(((
Что делать??????
← →
jonni (2003-10-04 19:02) [1]perepisat" etoy knopke okonnuyu proceduru na svoyu programmu
SetWindowLong(hwnd,GWL_WNDPROC);
toka ne zabit" pri etom GetWindowLong i zapomnit" staruyu proceduru i potom v svoey novoy okonnoy procedure vmesto DefWindowProc ispol"zovat" CallWindowProc() s ukazatelem na staruyu proceduru.... i vse....
← →
Demetrius2003 (2003-10-05 13:26) [2]> jonni
Я так и пытался сделать, но у меня почему-то не вышло может не тому окну меняю WinProc , а может что-то не так описал(я ведь только учусь) . Если можно какой-нибудь простой пример.
Заранее спасибо
← →
DVM (2003-10-05 14:27) [3]
> но так как она принадлежит чужому окну
Что значит чужое окно? Окно чужого процесса? Тогда SetWindowLong не поможет.
← →
Demetrius2003 (2003-10-05 15:04) [4]>DVM
Почему??????????
И если это так, то что мне делать
← →
DVM (2003-10-05 15:10) [5]
> Почему??????????
Потому, что SetWindowLong позволяет передать указатель на новую оконную процедуру. Но этот указатель будет указывать на адрес в адресном пространстве Вашей программы, а не той, где кнопка. Т.е. подобное вылетит с ошибкой "Acess Violation" скорее всего.
Как вариант могу предложить хуки, но это не так-то просто и не очень хороший вариант.
Вот вы говорите, что создали кнопку, а как Вы это сделали? Может есть другой способ, позволяющий упростить задачу. И для чего эта кнопка?
← →
Demetrius2003 (2003-10-07 00:12) [6]>DVM
but:=TButton.Create(self);
but.Width:=60;
but.Height:=23;
but.Caption:="Cool";
but.Font.Style:=[fsbold];
but.Font.Size:=10;
but.Visible:=True;
but.Left:=950;
but.Top:=5;
but.ParentWindow:=DTTV;
DTTV- хэндл SysListView32 в Program Manager
А кнопочку делаю для общего развития.
Надо же когда-то из розряда ламаков выбираться :)))
А про хуки я и сам думал, но надеялся, что есть способ попроще.
← →
DVM (2003-10-07 11:18) [7]Поищите в инете где то мне попадалась статья о том, как внедриться с помощью хуков в работу часов, что в трее. Это из той же оперы, что требуется Вам. Это если самому разбираться неохота.
Еще есть пример в книге Рихтера - там речь идет о манипуляциях с иконками рабочего стола - опять же посредством установки хуков, но на С.
В принципе задача решаема.
← →
Demetrius2003 (2003-10-07 22:23) [8]>DVM
Спасибо
← →
jonni (2003-10-07 23:27) [9]to Demetrius2003 ©
vse prekrastno rrabotaet ya ne znayu pochemu u tebya ne poluchaetsya
nahozhu desktop:
h := FindWindow("Progman", nil);
if h = 0 then exit;
h2 := FindWindowEx(h, 0, "SHELLDLL_DefView", nil);
if h2 <> 0 then h := h2;
sozdayu knopku:
hWnd:=CreateWindowEx(ExtStyle,
"button",
"",
Style,
100,100,
100,100,
h,0,
hInstance,nil);
perepisivayu dlya knopki proceduru
//-- Doing Subclassing ---------------------------------------------------------
FWndCallback := VirtualAlloc(nil, 12, MEM_RESERVE OR MEM_COMMIT, PAGE_EXECUTE_READWRITE);
asm
mov EAX, Self
mov ECX, [EAX].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(WndProc)
sub EAX, ECX
sub EAX, 12
mov dword ptr [ECX+8], EAX // jmp
end;
oldproc := Pointer(GetWindowLong(hWnd,GWL_WNDPROC));
SetWindowLong(hWnd,GWL_WNDPROC,DWORD(FWndCallback));
//-- End of Subclassing --------------------------------------------------------
poluchayu soobscheniya ot knopki
function WndProc(Wnd: HWND; Msg: UINT; mywParam: WPARAM;
mylParam: LPARAM): LRESULT;
case Msg of
WM_CREATE:
begin
Result:=CallWindowProc(oldproc,wnd, msg, mywparam, mylparam);;
end;
WM_DESTROY :
begin
Result:=0;
postquitmessage(0);
exit;
end;
WM_LBUTTONDOWN:begin MessageBox (0, pchar("class"), PChar("ShellNam"), MB_OK or MB_ICONERROR or MB_SETFOREGROUND or MB_TOPMOST);end;
else Result:=CallWindowProc(oldproc,wnd, msg, mywparam, mylparam);
end;
end;
naslazhdayus" zhizni........
← →
Demetrius2003 (2003-10-08 13:40) [10]>jonni ©
Не фига себе способ попроще!!!
Что вообще делает твоя ассемблерная вставка???????
Но спасибо, очень интересный пример попробую разобраться.
СПАСИБО!!!
← →
Demetrius2003 (2003-10-08 14:33) [11]>jonni ©
Судя по всему твоя асмовская вставка просто вносит нужные данные в область выделенную
VirtualAlloc(nil, 12, MEM_RESERVE OR MEM_COMMIT, PAGE_EXECUTE_READWRITE);
Но что такое $6858 или $E950 мне вообще не понятно.
Если можно, дай ссылку где об этом можно почитать.
Заранее спасибо за ссылку.
← →
jonni (2003-10-09 02:03) [12]eta asm vstavka peripisivaet adress proceduri zamenyaya ego tvoim novim adressom proceduri......
gde pochitat"......... da ktobi znal.......
eto iz razdela SubClassinga.... kogda u tebay est" odin zaregestrirovanniy class a okon hochetsya mnogo i etim sposobom mozhno pereopredellit" okonnuyu glavnuyu funkciyu...
esli naydesh chto to pro eto n epozhaley podelit"sya infoy.. nudu ochen" rad
← →
Demetrius2003 (2003-10-09 16:16) [13]> jonni
У меня твой код не работает, пишет "Access Violation", может просто у тебя винда XP, а у меня 98.
А может я в чём-то не прав,если второе то разберусь, если причина в первом, то жаль :(((
P.S.
Я читал Рихтера, и он пишет,что без хуков не обойтись
Если чё найду, то скину на аську.
← →
Demetrius2003 (2003-10-09 22:43) [14]> jonni
Ошибка из-за винды 98 :(((
FWndCallback := VirtualAlloc(nil, 12, MEM_RESERVE OR MEM_COMMIT, PAGE_EXECUTE_READWRITE);
Windows 98 поддерживаетлишь атрибугы защиты PAGE_NOACCESS, PAGE_READONLY и PAGE_READWRITE Попытка резервирования региона с атрибутом PAGE_EXECUTE или PAGE_EXECUTE_READ дает регион с атрибутом PAGE_READONLY. А указав PAGE_EXECUTE_READWRITE, Вы получите регион с атрибутом PAGE_READWRITE.
← →
jonni (2003-10-10 01:24) [15]kak ni starnno ya rabotayu na win98 i nikakih problem u menya eto ne vizivaet..... ya pol"zuyus" etim ochen" chasto i vsegda rabotalo podo vsemi vimdami bez edinoy oshibki..... ne znayu pochemu u tebya tak :(
u menya win98 + D7
← →
jonni (2003-10-10 01:25) [16]ya nadeyus" u tebya
FWndCallback,oldproc:Pointer <-- ti tak ih zadal??
← →
Demetrius2003 (2003-10-10 09:29) [17]> jonni ©
>FWndCallback,oldproc:Pointer <-- ti tak ih zadal??
Да
У меня Win98+Delphi6 , хотя это же апи и версия делфи не может повлиять на роботу.
Правда твой код, я немного переписал, может где-то допустил ошибку, если так то сегодня разберусь.
Спасибо!!!
← →
Иван Шихалев (2003-10-10 09:38) [18]Лучше быть проще - сформировать на основе класса
BUTTON
свой собственный и делать в нем что хошь.
← →
Demetrius2003 (2003-10-10 10:02) [19]> jonni ©
> mov EAX, Self
Что такое Self????
Можешь дать мне какой-то рабочий исходник, а то может я что-то упустил.
Заранее спасибо за исходник.
P.S.
Кстати с твоей асмовской вставкой , я почти раздуплился.
Её фишка в том, что она отсчитывает смещение от FWndCallBack до твоей WinProc, а так как FWndCallBack для всех процессов одинаковый, то чужой процесс залазит в АП твоего процесса.
Прикольный способ.
← →
wal (2003-10-10 10:03) [20]Когда мне нужна была кнопка на рабочем столе, я делал из обычной кнопки ActiveX Control, затем писАл простенькую html обвязку для нее и помещал эту html-ку на Active Desktop. Просто, удобно и никаких хуков.
С уважением.
← →
Demetrius2003 (2003-10-10 17:49) [21]to all
Тема насчёт OnClick закрыта.
Я страшно затупил пытаясь, внедриться в процесс Explorer , пытаясь обработать BM_Click, забыв при этом что запросто могу обрабатывать месаги , которые пришли непосредственно к кнопке :))), например WM_LBUTTONUP .
Но мне всёравно очень интересно как внедриться в чужой процесс!!!
> jonni
Надеюсь и жду исходник!!!
← →
jonni (2003-10-11 06:33) [22]vot tebe primerchik dovol"no prostoy
vot tebe sama programma
unit Unit1;
interface
uses
Windows, Classes, Forms, APIButton, Dialogs, Controls, StdCtrls, ActnMan,
ActnColorMaps;
type
TForm1 = class(TForm)
Label1: TLabel;
procedure FormCreate(Sender: TObject);
procedure TstClick(Sender: TAPIButton);
procedure BntClick(Sender: TAPIButton);
private
Bnt,Tst:TAPIButton;
public
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.BntClick(Sender: TAPIButton);
begin
MessageBox(0,"Add",@Caption[1],MB_ICONERROR)
end;
procedure TForm1.FormCreate(Sender: TObject);
var h,h2 :Integer;
begin
Bnt:=TAPIButton.Create(Handle);
h := FindWindow("ProgMan", nil);
if h = 0 then exit;
h2 := FindWindowEx(h, 0, "SHELLDLL_DefView", nil);
if h2 <> 0 then h := h2;
Bnt.Parent:=h;
Bnt.Caption:="Add";
Bnt.Enabled:=True;
Bnt.SetBounds(100,100,Bnt.Width,Bnt.Height);
Bnt.OnMouseClick:=BntClick;
Tst:=TAPIButton.Create(h);
Tst.Left:=Bnt.Left + Bnt.Width + 8;
Tst.Top:=100;
Tst.Caption:="Remove";
Tst.OnMouseClick:=TstClick;
end;
procedure TForm1.TstClick(Sender: TAPIButton);
begin
MessageBox(0,"Remove",@Caption[1],MB_ICONERROR)
end;
end.
← →
jonni (2003-10-11 06:34) [23]vot tebe knopka
unit APIButton;
interface
uses
Windows, Messages, Forms;
type
TAPIButton = class;
TButtonEvent = procedure(Sender: TAPIButton) of object;
TAPIButton = class
protected
// varibles
FHandle:THandle;
FTop,FLeft,FWidth,FHeight:Integer;
FMouseClick:TButtonEvent;
OldWinProc,NewWinProc:Pointer;
FMouse:Boolean;
// for "Caption" property
function GetCaption:string;
procedure SetCaption(const Value: string);
// for "Left" property
procedure SetLeft(const Value: Integer);
// for "Top" property
procedure SetTop(const Value: Integer);
// for "Width" property
procedure SetWidth(const Value: Integer);
// for "Height" property
procedure SetHeight(const Value: Integer);
// for "Visible" property
function GetVisible:Boolean;
procedure SetVisible(const Value: Boolean);
// for "Enabled" property
function GetEnabledB:Boolean;
procedure SetEnabledB(const Value: Boolean);
// for "Parent" property
function GetParent:THandle;
procedure SetParent(const Value: THandle);
// for Windows Messages
procedure msgUser(var Msg:TMessage);
published
property Handle: THandle read FHandle default 0;
property Caption:string read GetCaption write SetCaption;
property Left:Integer read FLeft write SetLeft;
property Top:Integer read FTop write SetTop;
property Width:Integer read FWidth write SetWidth;
property Height:Integer read FHeight write SetHeight;
property Visible:Boolean read GetVisible write SetVisible;
property Enabled:Boolean read GetEnabledB write SetEnabledB;
property Parent:THandle read GetParent write SetParent;
property OnMouseClick:TButtonEvent read FMouseClick write FMouseClick;
procedure SetFocus;
procedure SetBounds(ALeft,ATop,AWidth,AHeight: Integer);
constructor Create(ParentControl: THandle);
destructor UnCreate;
end;
implementation
{ TAPIButton }
constructor TAPIButton.Create(ParentControl: THandle);
begin
FHandle:=CreateWindow("Button","APIButton",WS_VISIBLE or WS_CHILD,0,0,72,25,
ParentControl,0,hInstance,nil);
SendMessage(FHandle,WM_CREATE,0,0);
FMouse:=GetSystemMetrics(SM_SWAPBUTTON) = 1;
FLeft:=0;
FTop:=0;
FWidth:=72;
FHeight:=25;
NewWinProc:=MakeObjectInstance(msgUser);
OldWinProc:=Pointer(SetWindowLong(FHandle,GWL_WNDPROC,Cardinal(NewWinProc)));
end;
destructor TAPIButton.UnCreate;
begin
Visible:=False;
SendMessage(FHandle,WM_DESTROY,0,0);
end;
function TAPIButton.GetCaption: string;
var
Buf:string;
L:Integer;
begin
L:=GetWindowTextLength(FHandle) + 1;
SetLength(Buf,L);
GetWindowText(FHandle,PChar(Buf),L);
Result:=PChar(Buf);
end;
function TAPIButton.GetEnabledB: Boolean;
begin
Result:=IsWindowEnabled(FHandle);
end;
function TAPIButton.GetVisible: Boolean;
begin
Result:=IsWindowVisible(FHandle);
end;
procedure TAPIButton.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
begin
FLeft:=ALeft;
FTop:=ATop;
FWidth:=AWidth;
FHeight:=AHeight;
SetWindowPos(FHandle, 0, ALeft, ATop, AWidth, AHeight,0)
end;
procedure TAPIButton.SetCaption(const Value: string);
begin
SetWindowText(FHandle,PChar(Value));
end;
procedure TAPIButton.SetEnabledB(const Value: Boolean);
begin
EnableWindow(FHandle,Value);
end;
procedure TAPIButton.SetFocus;
begin
Windows.SetFocus(FHandle);
end;
procedure TAPIButton.SetHeight(const Value: Integer);
begin
FHeight:=Value;
SetWindowPos(FHandle,0,FLeft,FTop,FWidth,Value,0);
end;
procedure TAPIButton.SetLeft(const Value: Integer);
begin
FLeft:=Value;
SetWindowPos(FHandle,0,Value,FTop,FWidth,FHeight,0);
end;
procedure TAPIButton.SetWidth(const Value: Integer);
begin
FWidth:=Value;
SetWindowPos(FHandle,0,FLeft,FTop,Value,FHeight,0);
end;
procedure TAPIButton.SetTop(const Value: Integer);
begin
FTop:=Value;
SetWindowPos(FHandle,0,FLeft,Value,FWidth,FHeight,0);
end;
procedure TAPIButton.SetVisible(const Value: Boolean);
begin
if Value then
ShowWindow(FHandle,SW_SHOW)
else
ShowWindow(FHandle,SW_HIDE);
end;
function TAPIButton.GetParent: THandle;
begin
Result:=Windows.GetParent(FHandle);
end;
procedure TAPIButton.SetParent(const Value: THandle);
begin
Windows.SetParent(FHandle, Value);
end;
procedure TAPIButton.msgUser(var Msg: TMessage);
procedure RaiseClick;
var
Pnt:TPoint;
begin
GetCursorPos(Pnt);
if Assigned(FMouseClick) and (WindowFromPoint(Pnt) = FHandle) then
FMouseClick(Self);
end;
begin
Msg.Result:=CallWindowProc(OldWinProc,FHandle,Msg.Msg,Msg.WParam,Msg.LParam);
if not FMouse and (Msg.Msg = Wm_LButtonUp) then
RaiseClick
else if FMouse and (Msg.Msg = Wm_RButtonUp) then
RaiseClick;
end;
end.
← →
jonni (2003-10-11 06:38) [24]zamet" chto kogda pol"zuehsysa classami kotorie zaregestrirovani uzhe samoy windows tak to ne nuzhna asemblernaya vstavka...
i voobsche ta assemblernaya vstavka nuzhna tol"ko dlya subclassinga.... t.e. kogda odin class a okon mnogo ... esli ti rabotaesh s odnim oknom to voobsche nichego ne nado.. nado tol"ko pri registracii classa ukazat" svoyu funkciyu....
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2003.12.04;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.004 c