Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Система";
Текущий архив: 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]

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

.....
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.037 c
14-16708
Undert
2004-01-16 13:52
2004.02.06
Не подскажете ли алгоритм


1-16309
Chuha
2004-01-25 16:56
2004.02.06
Прогрессия


6-16564
Andersen
2003-12-02 14:04
2004.02.06
Что это за инфу выдает 80-ый порт?


1-16418
Nau13
2004-01-22 16:02
2004.02.06
как проверить имплементирует ли данный класс данный интерфейс


3-16072
chtr
2004-01-12 05:04
2004.02.06
Какая строка отправляется на сервер?





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