Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2009.11.29;
Скачать: [xml.tar.bz2];

Вниз

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

 
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 вся ветка

Форум: "WinAPI";
Текущий архив: 2009.11.29;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.51 MB
Время: 0.006 c
4-1205738499
kuzulis
2008-03-17 10:21
2009.11.29
SetWaitableTimer не срабатывает


15-1254576288
vrem
2009-10-03 17:24
2009.11.29
Windows: странные задержки


15-1254121019
Григорьев Антон
2009-09-28 10:56
2009.11.29
Наука на службе университета


2-1255599480
ford
2009-10-15 13:38
2009.11.29
Получить последнюю папку из пути


15-1254238851
Суслик_
2009-09-29 19:40
2009.11.29
Идея борьбы со спамом





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