Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.02.06;
Скачать: CL | DM;

Вниз

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]

Вот такой вот кусочек кода:

.....
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
и другие взяты просто для удобства, т.к. часто приходилось переходить от RegisterShellHook к WH_SHELL и обратно...


 
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;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.018 c
14-16593
Nous Mellon
2004-01-14 19:20
2004.02.06
Приятный интерфейс на WinApi


3-16155
Александр
2004-01-16 13:32
2004.02.06
Посоветуйте компонент!


1-16305
SeS
2004-01-23 18:15
2004.02.06
Забор значений из файла


14-16704
syte_ser78
2004-01-16 16:04
2004.02.06
Работа с DirectX


1-16465
Натуся
2004-01-27 23:08
2004.02.06
Округление double