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

Вниз

зависание при установке ловушки   Найти похожие ветки 

 
MasDen ©   (2008-10-03 18:16) [0]

Добрый день написал dll в которой отлавливаются события создания и закрытия окна и вот проблема при запуске программы виснет компьютер или происходит ошибка. Помогите разобраться, чв чем роблема..вот код dll - библиотеки

library hook;

uses
 windows, messages, dialogs;

 {$R *.res}

var
 SysHook: HHOOK = 0; //дескриптор системной ловушки
 Wnd: word;

 //============================================================================
 //процедура обработки сообщений
 //в которой мы счиываем заголовок окна и выводим его простым сообщением
 function SysMsgProc(code: Integer; wParam: word; lParam: longint):Longint; stdcall;
 var
   windtext: array[0..255] of char;
 begin
   Result := CallNextHookEx(SysHook, code, wParam, lParam);
   case code of
     HCBT_CREATEWND:
     begin
       Wnd:=Wparam;
       GetWindowText(Wnd, windtext, 255);
     end;
     HCBT_DESTROYWND:
     begin
       Wnd:=wParam;
       if Wnd<>0 then
         GetWindowText(Wnd, windtext, 255);
     end;
   end;
   ShowMessage(windtext);
 end;

//Процедура установки ловушки
 procedure SetHook(Hook: Boolean) export; stdcall;
 begin
   if Hook then
   begin
       SysHook:=SetWindowsHookEx(WH_CBT,
         @SysMsgProc, HInstance, 0);
   end
   else
   begin
       UnhookWindowsHookEx(SysHook);
       SysHook:=0;
   end;
 end;

 //============================================================================

 exports SetHook index 1;

begin
end.


А вот как в программе вызывается данная библиотека

...
var
 frmCatalog: TfrmCatalog;
 procedure SetHook(Hook: Boolean) stdcall; external "hook.dll" index 1;
...
procedure TfrmCatalog.FormCreate(Sender: TObject);
begin
 SetHook(true); //устанавливаем ловушку
end;

procedure TfrmCatalog.FormClose(Sender: TObject; var Action: TCloseAction);
begin
 SetHook(false); //удаляем ловушку
end;


 
easy ©   (2008-10-03 18:29) [1]

function SysMsgProc(code: Integer; wParam: word; lParam: longint):Longint; stdcall;
var
  windtext: array[0..255] of char;
begin
  case code of
    HCBT_CREATEWND:
    begin
      Wnd:=Wparam;
      GetWindowText(Wnd, windtext, 255);
    end;
    HCBT_DESTROYWND:
    begin
      Wnd:=wParam;
      if Wnd<>0 then
        GetWindowText(Wnd, windtext, 255);
    end;
  end;
  ShowMessage(windtext);
  Result := CallNextHookEx(SysHook, code, wParam, lParam);
end;


 
easy ©   (2008-10-03 18:40) [2]

var
  windtext: array[0..255] of char;
  Wnd:HWND;


 
MasDen ©   (2008-10-03 18:59) [3]

Спасибо, попробовал..все-равно загрузка по максимум, пробовал и а компе и на ноутбуке, эффект один и тот же=((


 
easy ©   (2008-10-03 19:04) [4]

library hook;
uses
windows, messages;

{$R *.res}

var
SysHook: HHOOK = 0; //дескриптор системной ловушки
Wnd: word;

//============================================================================
//процедура обработки сообщений
//в которой мы счиываем заголовок окна и выводим его простым сообщением
function SysMsgProc(code: Integer; wParam: word; lParam: longint):Longint; stdcall;
var
  windtext: array[0..255] of char;
  Wnd:HWND;
begin

  case code of
    HCBT_CREATEWND:
    begin
      Wnd:=Wparam;
      GetWindowText(Wnd, windtext, 255);
      //ShowMessage(windtext);
      MessageBox(0,"Wnd is created!!","Alarm",MB_OK);
    end;
    HCBT_DESTROYWND:
    begin
      Wnd:=wParam;
      if Wnd<>0 then
        GetWindowText(Wnd, windtext, 255);
        //ShowMessage(windtext);
        MessageBox(0,"Wnd is destroyed!!","Alarm",MB_OK);
    end;
  end;

  Result := CallNextHookEx(SysHook, code, wParam, lParam);
end;

//Процедура установки ловушки
procedure SetHook(Hook: Boolean) export; stdcall;
begin
  if Hook then
  begin
      SysHook:=SetWindowsHookEx(WH_CBT,
        @SysMsgProc, HInstance, 0);
  end
  else
  begin
      UnhookWindowsHookEx(SysHook);
      SysHook:=0;
  end;
end;

//============================================================================

exports SetHook index 1;

begin
end.


> А вот как в программе вызывается данная библиотека
>
> ...
> var
>  frmCatalog: TfrmCatalog;
>  procedure SetHook(Hook: Boolean) stdcall; external "hook.
> dll" index 1;
> ...
> procedure TfrmCatalog.FormCreate(Sender: TObject);
> begin
>  SetHook(true); //устанавливаем ловушку
> end;
>
> procedure TfrmCatalog.FormClose(Sender: TObject; var Action:
>  TCloseAction);
> begin
>  SetHook(false); //удаляем ловушку
> end;
>

procedure TForm1.Button1Click(Sender: TObject);
begin
 SetHook(true);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 SetHook(false);
end;


 
easy ©   (2008-10-03 19:06) [5]

и алярмы разгребать.


 
DVM ©   (2008-10-03 21:55) [6]

вызывать функции, создающие окна из HCBT_CREATEWND - грамотно придумано, ничего не скажешь.


 
Rouse_ ©   (2008-10-03 22:05) [7]

Мдя... я раньше плакал - теперь привык...
Да кто-ж вас учил то WParam в виде WORD-а делать, да еще к тому-же ShowMessage на обработчике WH_CBT поднимать?
Фленов что-ли? :)


 
Городской Шаман   (2008-10-03 22:28) [8]

Ошибка в этой строчке

HCBT_CREATEWND
A window is about to be created. The system calls the hook procedure before sending the WM_CREATE or WM_NCCREATE message to the window. If the hook procedure returns a nonzero value, the system destroys the window; the CreateWindow function returns NULL, but the WM_DESTROY message is not sent to the window. If the hook procedure returns zero, the window is created normally.


Окна пока нет, здесь только уведомление о его создании.


 
Городской Шаман   (2008-10-03 22:30) [9]


> Rouse_ ©   (03.10.08 22:05) [7]
>
> Мдя... я раньше плакал - теперь привык...
> Да кто-ж вас учил то WParam в виде WORD-а делать, да еще
> к тому-же ShowMessage на обработчике WH_CBT поднимать?
> Фленов что-ли? :)


Ну глобальный хук ставить в этой ситуации я ему посетовал ставить, но не думал что его использовать будут ТАК.


 
MasDen ©   (2008-10-04 11:52) [10]

Спасибо всем кто откликнулся, да для вас всех этот код оказался туп до невозможности, но что сделать если этот код писал человек, который занимается разработкай web-приложений? Я не пишу Windows приложения, я не умею толком работать, да и вообще не умею с сообщениями ОС, имено по этому и написал здесь. У меня есть опыт создания приложений для Windows на Delphi. Но писал я в основном программы для работы с БД, но никак уж не системные.

Если не против, может вы поможете мне еще один раз? Я только что понял, что в принципе сделал тпо, когда создал отдельную dll и начал в ней ловить сообщения, так как если я словил нужное мне нужно выполнить одну процедуру из exe файла. Скажите пожалуйста как правильно объявить и с какими параметрами процедуру, чтобы она ловила теже сообщения о закрытии окна, но чтобы она была размещаена просто в exe файле.
Вот как выглядит функция в dll

function SysMsgProc(code: Integer; wParam: word; lParam: longint):Longint; stdcall;
const
 CAPTION = "Заголовок окна"
var
 windtext: array[0..255] of char;
 Wnd:HWND;
begin
 case code of
   HCBT_DESTROYWND:
   begin
     Wnd:=wParam;
     if Wnd<>0 then
       GetWindowText(Wnd, windtext, 255);

     if windtext=CAPTION then
     begin
       Вызываем нужную процедуру
     end;

   end;
 end;

 Result := CallNextHookEx(SysHook, code, wParam, lParam);
end;

Заранее спасибо.


 
DVM ©   (2008-10-04 13:58) [11]


> MasDen ©

если тебе только Top Level окна нужны, то может проще без dll так :

program ShellHookDemo;

uses
 windows, messages, sysutils;

const
 RSH_DEREGISTER = 0;
 RSH_REGISTER = 1;
 RSH_REGISTER_PROGMAN = 2;
 RSH_REGISTER_TASKMAN = 3;

 HSHELL_ACTIVATESHELLWINDOW = 3;
 HSHELL_WINDOWCREATED = 1;
 HSHELL_WINDOWDESTROYED = 2;
 HSHELL_WINDOWACTIVATED = 4;
 HSHELL_GETMINRECT = 5;
 HSHELL_REDRAW = 6;
 HSHELL_TASKMAN = 7;
 HSHELL_LANGUAGE = 8;

var
 wc : TWndClassEx;
 MainWnd : HWND;
 Mesg : TMsg;
 WndListBox:hWnd;
 WM_ShellHook:Integer;
 xPos,yPos,nWidth,nHeight : Integer;
 osInfo:OSVERSIONINFO;

Procedure RegisterShellHook(Wnd:hWnd;n:dword); stdcall;external "shell32.dll" index 181;

//------------------------------------------------------------------------------

function GetTextFromWindow(Wnd: HWND): string;
var
 TextLength: Integer;
 Text: PChar;
begin
 TextLength := SendMessage(Wnd, WM_GETTEXTLENGTH, 0, 0);
 if TextLength = 0 then Result := ""
 else
 begin
   GetMem(Text, TextLength + 1);
   SendMessage(Wnd, WM_GETTEXT, TextLength + 1, Integer(Text));
   Result := Text;
   FreeMem(Text);
 end;
end;

//------------------------------------------------------------------------------

function ListBox_AddString(lb : THandle; txt : String) : integer;
begin
 Result := SendMessage(lb, lb_addString, 0, integer(pchar(@txt[1])));
end;

//------------------------------------------------------------------------------

function WindowProc(wnd:HWND; Msg : Integer; Wparam:Wparam; Lparam:Lparam):Lresult; stdcall;
begin
 if msg=wm_shellhook then
   begin
     case wparam of
       HSHELL_WINDOWCREATED: ListBox_AddString(WndListBox,"Создано окно: HWND="
                    +inttostr(lparam)+" Text=""+GetTextFromWindow(lparam)+""");
       HSHELL_WINDOWDESTROYED: ListBox_AddString(WndListBox,
                                    "Уничтожено окно: HWND="+inttostr(lparam));
       HSHELL_WINDOWACTIVATED: ListBox_AddString(WndListBox,
                          "Активируется окно: HWND="+inttostr(lparam)+" Text=""
                                               +GetTextFromWindow(lparam)+""");
     end;
   end;
 case msg of
   wm_destroy :
     Begin
       postquitmessage(0);
       Result:=0;
       exit;
     End;
 else Result:=DefWindowProc(wnd,msg,wparam,lparam);
 end;
End;

//------------------------------------------------------------------------------

begin
 wc.cbSize:=sizeof(wc);
 wc.style:=cs_hredraw or cs_vredraw;
 wc.lpfnWndProc:=@WindowProc;
 wc.cbClsExtra:=0;
 wc.cbWndExtra:=0;
 wc.hInstance:=HInstance;
 wc.hIcon:=LoadIcon(0,idi_application);
 wc.hCursor:=LoadCursor(0,idc_arrow);
 wc.hbrBackground:=COLOR_BTNFACE+1;
 wc.lpszMenuName:=nil;
 wc.lpszClassName:="ShellHookDemo";
 if RegisterClassEx (wc) = 0 then
   MessageBox (0, "Invalid class registration", "Error", MB_OK)
 else
   begin
     xPos:=100; yPos:=150;
     nWidth:=430; nHeight:=250;
     MainWnd:=CreateWindowEx(
       0,
       "ShellHookDemo",
       "ShellHookDemo",
       ws_overlappedwindow,
       xPos,
       yPos,
       nWidth,
       nHeight,
       0,
       0,
       Hinstance,
       nil
       );
     if MainWnd = 0 then
       MessageBox (0, "Window not created", "Error", MB_OK)
     else
       begin
         ShowWindow(MainWnd,CmdShow);
         WM_ShellHook := RegisterWindowMessage("SHELLHOOK");
         if WM_ShellHook<>0 then
           begin
             osInfo.dwOSVersionInfoSize := sizeof(OSVERSIONINFO);
             GetVersionEx(osInfo);
             RegisterShellHook(0, 1);
             if(osInfo.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS) then
               RegisterShellHook(MainWnd, RSH_REGISTER)
             else
              RegisterShellHook(MainWnd, RSH_REGISTER_TASKMAN);
           end;
         SendMessage(GetDesktopWindow, $400, 0, 0);
         WndListbox:=CreateWindowEx(
                                    ws_ex_clientedge,
                                    "listbox",
                                    "",
                                    lbs_notify
                                    or ws_visible
                                    or ws_child
                                    or ws_vscroll,
                                    10,
                                    10,
                                    400,
                                    200,
                                    MainWnd,
                                    0,
                                    hInstance,
                                    nil
                                    );
         SendMessage(WndListBox,wm_setfont,GetStockObject(ansi_var_font),0);
       end;
   end;

 While GetMessage(Mesg,0,0,0) do
   begin
     TranslateMessage(Mesg);
     DispatchMessage(Mesg);
   end;
end.


 
MasDen ©   (2008-10-04 14:18) [12]

У меня есть Windows программа и в неё просто нужно встроить возможность словить сообщение закрытия дочернего окна с определенной надписью.



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

Текущий архив: 2009.11.29;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.012 c
15-1254148562
xayam
2009-09-28 18:36
2009.11.29
Напомните как называется фильм


15-1254400228
Kerk
2009-10-01 16:30
2009.11.29
Предлагаю наш ОМОН послать учиться в США, демократичнее надо быть


15-1254342609
Юрий
2009-10-01 00:30
2009.11.29
С днем рождения ! 1 октября 2009 четверг


15-1254656776
Denis__
2009-10-04 15:46
2009.11.29
настройки модема D-Link 2500U


2-1255518519
Программер
2009-10-14 15:08
2009.11.29
Перекрывание компонентов