Форум: "Система";
Текущий архив: 2004.02.06;
Скачать: [xml.tar.bz2];
ВнизWH_SHELL Найти похожие ветки
← →
наблюдатель (2003-11-13 13:44) [0]Вопрос у мени такой. Почему при установки вышеупомянутого хука, на Win2k/XP всё просто OK, а в Win98/ ME почти всё просто OK. А именно при открывании окна с папкой, хук иногда промахивается, и ловит это сообщение, как-то по настроению (зависимость мною не наблюдается), тогда как все остальные окна (от других приложений ловит на ура). И ещё, он вообще не всегда становится на Win98/ ME. При этом на Win98 ведёт себя немного лучше, чем на WinMe. В чём тут может быть проблема? А? Заранее спасибо за любую рекомендацию.
← →
Дубинин Алексей (2003-11-13 22:56) [1]Кусочек кода бы...
← →
DVM (2003-11-14 17:01) [2]Все ловит нормально во всех версиях, начиная от Win95/NT и заканчивая Win2003. Не ловятся только окна консольных программ под >=Win2000.
Как уже подмечено, неплохо бы кусок кода. А именно полный код ДЛЛ с хуком и часть программы отвечающую за прием сообщений от хука.
← →
наблюдатель (2003-11-14 22:54) [3]Вот такой вот кусочек кода:
и другие взяты просто для удобства, т.к. часто приходилось переходить от RegisterShellHook к WH_SHELL и обратно...
.....
type
TBufData = packed record
WndMain: HWND;
Mes:integer;
end;
.....
library hooks;
.....
var shellhook:hhook;
.....
function ShellProc(Code: Integer; wParam, lParam: Integer): Integer; stdcall;
begin
if Code>HC_ACTION then
case Code of
HSHELL_WINDOWCREATED: PostMessage(PBufData^.WndMain, PBufData^.Mes, HSHELL_WINDOWCREATED, wParam);
HSHELL_WINDOWDESTROYED: PostMessage(PBufData^.WndMain, PBufData^.Mes, HSHELL_WINDOWDESTROYED, wParam);
HSHELL_WINDOWACTIVATED: PostMessage(PBufData^.WndMain, PBufData^.Mes, HSHELL_WINDOWACTIVATED, wParam);
HSHELL_REDRAW: PostMessage(PBufData^.WndMain, PBufData^.Mes, HSHELL_REDRAW, wParam);
end;
Result:=CallNextHookEx(ShellHook, Code, wParam, lParam);
end;
.....
procedure SetHooks;stdcall;
begin
ShellHook:=SetWindowsHookEx(WH_SHELL, @ShellProc, HInstance, 0);
end;
.....
unit unit1;
.....
var WM_MYHOOK:integer;
.....
procedure TForm1.WndProc (var mes:tmessage);
var buf:array [0..256] of char;
hnd:hwnd;
msg:integer;
lparam,wparam:integer;
begin
msg:=mes.Msg;
lparam:=mes.LParam;
wparam:=mes.WParam;
if msg=WM_MYHOOK then
begin
case wparam of
HSHELL_WINDOWCREATED:
begin
getwindowtext (LParam,buf,sizeof (buf));
xcreatewindow (LParam,strpas (buf),strpas (buf));
end;
HSHELL_WINDOWDESTROYED: xdeletewindow (LParam);
HSHELL_WINDOWACTIVATED: xactivatewindow (LParam);
HSHELL_REDRAW: xredrawwindow (LParam);
end;
end;
inherited;
end;
.....
procedure TForm1.FormShow(Sender: TObject);
begin
WM_MYHOOK:=RegisterWindowMessage("Sample_Shell_Hook");
PBufData.WndMain:=Handle;
PBufData.Mes:=WM_MYHOOK
sethooks;
end;
.....
HSHELL_WINDOWCREATED
← →
DVM (2003-11-14 23:17) [4]Что-то из приведенного кода совсем непонятно как попадают в длл данные типа:
type
TBufData = packed record
WndMain: HWND;
Mes:integer;
end;
При установке хука длл откуда их берет?
Там наверное должен быть файл отображенный в память или как?
Надо весь остальной код длл.
← →
наблюдатель (2003-11-14 23:45) [5]Может я где-то в нём ошибся:
unit unit1;
.....
uses dllprc;
.....
var WM_MYHOOK:integer;
.....
procedure TForm1.WndProc (var mes:tmessage);
var buf:array [0..256] of char;
hnd:hwnd;
msg:integer;
lparam,wparam:integer;
begin
msg:=mes.Msg;
lparam:=mes.LParam;
wparam:=mes.WParam;
if msg=WM_MYHOOK then
begin
case wparam of
HSHELL_WINDOWCREATED:
begin
getwindowtext (LParam,buf,sizeof (buf));
xcreatewindow (LParam,strpas (buf),strpas (buf));
end;
HSHELL_WINDOWDESTROYED: xdeletewindow (LParam);
HSHELL_WINDOWACTIVATED: xactivatewindow (LParam);
HSHELL_REDRAW: xredrawwindow (LParam);
end;
end;
inherited;
end;
procedure TForm1.FormShow(Sender: TObject);
begin
WM_MYHOOK:=RegisterWindowMessage("Sample_Shell_Hook");
OpenMapFile;
PBufData.WndMain:=Handle;
PBufData.Mes:=WM_MYHOOK
sethooks;
end;
.....
unit dllprc;
.....
const
MName:PChar="Sample_Shell_Map_File";
type
TBufData = packed record
WndMain: HWND;
Mes:integer;
end;
var
MHandle: THandle;
PBufData:^TBufData;
.....
procedure OpenMapFile;
begin
MHandle:=CreateFileMapping(INVALID_HANDLE_VALUE,nil,PAGE_READWRITE,0,SizeOf(TBufData),MName);
if MHandle=0 then
begin
MessageBox(0,"Глюки! Глюки! Глюки!","Внимание!",0);
Exit;
end;
PBufData:=MapViewOfFile(MHandle,FILE_MAP_ALL_ACCESS,0,0,SizeOf(TBufData));
if PBufData=nil then
begin
CloseHandle(MHandle);
MessageBox(0,"Глюки! Глюки! Глюки!","Внимание!",0);
Exit;
end;
end;
procedure CloseMapFile;
begin
UnmapViewOfFile(PBufData);
CloseHandle(MHandle);
end;
.....
library hooks;
.....
uses dllprc;
.....
var shellhook:hhook;
.....
function ShellProc(Code: Integer; wParam, lParam: Integer): Integer; stdcall;
begin
if Code>HC_ACTION then
case Code of
HSHELL_WINDOWCREATED: PostMessage(PBufData^.WndMain, PBufData^.Mes, HSHELL_WINDOWCREATED, wParam);
HSHELL_WINDOWDESTROYED: PostMessage(PBufData^.WndMain, PBufData^.Mes, HSHELL_WINDOWDESTROYED, wParam);
HSHELL_WINDOWACTIVATED: PostMessage(PBufData^.WndMain, PBufData^.Mes, HSHELL_WINDOWACTIVATED, wParam);
HSHELL_REDRAW: PostMessage(PBufData^.WndMain, PBufData^.Mes, HSHELL_REDRAW, wParam);
end;
Result:=CallNextHookEx(ShellHook, Code, wParam, lParam);
end;
procedure SetHooks;stdcall;
begin
shellhook:=SetWindowsHookEx(WH_SHELL, @ShellProc, HInstance, 0);
end;
procedure DLLEntryPoint(dwReason: DWord); stdcall;
begin
case dwReason of
DLL_PROCESS_ATTACH:OpenMapFile;
DLL_PROCESS_DETACH:CloseMapFile;
end;
end;
.....
begin
DLLProc:=@DLLEntryPoint;
DLLEntryPoint(DLL_PROCESS_ATTACH);
end.
.....
← →
наблюдатель (2003-11-16 15:49) [6]Так чё там с hook-ом та...
← →
jonni (2003-11-17 00:42) [7]che takoe HC_ACTION??? dolzno bit" prosto Code>=0 togda ok
a gde naprimer takoy kusok??
HSHELL_GETMINRECT
A window is being minimized or maximized. The system needs the coordinates of the minimized rectangle for the window.
pochemu ne vse tak skazat" podhodyachie soobscheniya ne obrabativayut"sya?
← →
наблюдатель (2003-11-17 14:50) [8]> a gde naprimer takoy kusok??
Это у меня реализовано через RegisterShellHook
> che takoe HC_ACTION??? dolzno bit" prosto Code>=0 togda ok
Так ведь в Win2k/XP (а в Win98/ME только с Explorer-ром) всё работает. Но всё равно спасибо за подсказку. Раньше у меня было именно Code>=HC_ACTION. Видимо случайно исправил. Будем проверять.
← →
наблюдатель (2003-11-18 18:07) [9]Вообщем результаты тестирования такие:
Win98/2k/XP - всё OK, а вот в WinME без Explorer-ра всё далеко не OK, с Explorer-ром нормально.
При открытии окон с содержимым каких-либо папок ловится только HANDLE этого окна, а вот GetWindowText на нём не работает (но это не столь суть важно, если посидеть, то и это можно исправить).
Короче говоря, ни WH_SHELL ни RegisterShellHook в WinME у меня не работают. Никто не знает в чём тут может быть дело?
← →
DVM (2003-11-19 11:50) [10]
> Win98/2k/XP - всё OK, а вот в WinME без Explorer-ра всё
> далеко не OK, с Explorer-ром нормально.
> При открытии окон с содержимым каких-либо папок ловится
> только HANDLE этого окна, а вот GetWindowText на нём не
> работает (но это не столь суть важно, если посидеть, то
> и это можно исправить).
Что то Вы противоречите сами себе: "без Explorer-ра всё далеко не OK" и "При открытии окон с содержимым каких-либо папок". В чем проблема то?
И еще: если есть окно, то получить его заголовок можно всегда.
Как кстати вы ставите RegisterShellHook? Дело в том, что если это сделать неправильно, то хук в dll тоже начинает работать неправильно.
← →
Digitman (2003-11-19 12:09) [11]ShellHook должна быть глобально-доступной переменной
← →
наблюдатель (2003-11-19 12:42) [12]> Что то Вы противоречите сами себе: "без Explorer-ра всё далеко не OK" и "При открытии окон с содержимым каких-либо папок".
Я имел ввиду, что если в Win98/ME запустить эту Shell-ку просто как программу, то хук работает, но как я уже говорил раньше, папки ловит через раз (или через два). А если её прописать как Shell, то в Win98 хук тоже работает и окна Explorer-ра ловит нормально, но вот в WinME ничего не ловит.
> И еще: если есть окно, то получить его заголовок можно всегда.
Я с этим согласен, но проведя вот такой вот эксперимент выяснилось, что HSHELL_WINDOWCREATED приходит всегда, но если считать заголовок именно в этот момент, и используя именно переданный HANDLE, то на папках, такой прикол проходит не всегда. А вот на приложениях стабильно. Но это не столь суть важно, если перебирать список окон каждый раз при получении HSHELL_WINDOWCREATED, то всё будет нормально. Волнует другое, то что в WinME ничего толком не работает.
> Как кстати вы ставите RegisterShellHook? Дело в том, что если это сделать неправильно, то хук в dll тоже начинает работать неправильно.
Ставлю я его так:
.....
var WM_SHELLHOOK:integer;
.....
WM_SHELLHOOK:=RegisterWindowMessage("SHELLHOOK");
RegisterShellHook(handle, 3);
.....
Ещё раз повторюсь, всё замечательно везде, кроме как в WinME, при Shell=MySampleShell.exe.
>ShellHook должна быть глобально-доступной переменной
Раньше так и было, но я много раз менял код, и видимо по привычке забросил не туда. Но даже, когда она была в TBufData, всё также работало. Но всё равно спасибо за замечание.
← →
DVM (2003-11-19 13:14) [13]
> наблюдатель (19.11.03 12:42) [12]
У меня нет к сожалению нигде WinMe, но если напомните по почте, то я могу выслать dll + несложный пример-проект на API, где все ловится нормально. Заодно узнаю, работает ли он в WinMe.
В дополнение к хукам стоит сделать периодическое перечитывание списка окон по таймеру, т.к. некоторые окна (особенно после TerminateProcess) исчезают не прощаясь.
> Ставлю я его так:
>
> .....
> var WM_SHELLHOOK:integer;
> .....
> WM_SHELLHOOK:=RegisterWindowMessage("SHELLHOOK");
> RegisterShellHook(handle, 3);
Вообще то правильнее
RegisterShellHook(handle, 1)
и RegisterShellHook(handle, 3);
в WinNt и не WinNt (только где 1, а где 3 я запамятовал).
← →
DVM (2003-11-19 22:18) [14]
> Я с этим согласен, но проведя вот такой вот эксперимент
> выяснилось, что HSHELL_WINDOWCREATED приходит всегда, но
> если считать заголовок именно в этот момент, и используя
> именно переданный HANDLE, то на папках, такой прикол проходит
> не всегда. А вот на приложениях стабильно.
Я кажется понял в чем дело здесь. При создании окна папки вначале оно не имеет заголовка, а добавляет его потом. При этом приходит HSHELL_REDRAW. В этот момент и надо считывать заголовок.
← →
наблюдатель (2003-11-19 22:51) [15]> Я кажется понял в чем дело здесь. При создании окна папки вначале оно не имеет заголовка, а добавляет его потом. При этом приходит HSHELL_REDRAW. В этот момент и надо считывать заголовок.
HSHELL_REDRAW у меня стоит в обработке. Правда в оригинальной программе, с него толку мало, т.к. если кнопки, соответствующей этому окну нет, то и перерисовывать в ней нечего. Однако за замечание спасибо, учту. Но это всё, как я уже говорил не важно, т.к. решаемо весьма просто. Самое главное сейчас, заставить её работать под WinME.
Страницы: 1 вся ветка
Форум: "Система";
Текущий архив: 2004.02.06;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.037 c