Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Проблемы с CreateFileMapping и MapViewOfFile [D7, Win95/98, Win2k, WinXP]


Страницы:   1 2

pmm ©   (2005-01-24 08:34:00) 

Ставлю хук в длл. Прога на всех платформах выдает ошибку типа "память не может быть рид" и проч. Сначала, правда работает 1-2 минуты. Делал по примеру из инета, пример также глючит. Почему так? А нельзя ли другой способ сделать - обратится к общей ячеи памяти разными экземплярами дллек.
И глучит на 98 на 2000 на ХП.


pmm   (2005-01-26 13:31:00) [1]


> тему "calling conventions" в станд.справке изучал ?

почитал, написано мало, и основных принципов при работе с АПИфункцими я там так и не нашел


> ой не верю.

сам возьми, проверь. лист программы приводиться, заодно и stdcall проставь где нужно.

Такое глубокое системное программирование - не мой профиль, и в каком порядке передаются параметры в процедуру, мне честно говоря все равно; поэтому то я сюда и обратился, а нужно то было только отследить бездействие пользователя за компом. а досПриложений у нас на предприятии давно нет


Digitman   (2005-01-26 12:33:00) [2]


> забыл немного


"Так не бывает - тут помню, а тут не помню" (с)

это как ? чуть-чуть беременный что ли ?)


> что-то не могу нигде полноценную статью найти


тему "calling conventions" в станд.справке изучал ?


> Гонял и с консолью, все норамльно работает


ой не верю.

а кроме консолей, заметь, есть еще и ntvdm-процессы, эмулирующие ДОС-среду для ДОС-задач.. какие нафих в ДОС  GetMessage или PeekMessage ?

ты не в ту степпь подался ... если уж решать задачу с пом.хук-механизма, то ставить нужно хуки  WH_LL_KEYBOARD и WH_LL_MOUSE


pmm   (2005-01-26 12:24:00) [3]

Только не везде нужно было убрать stdcall. Всё же наверное следует разобраться что есть stdcall и вообще соглашения о вызовах.
Да, с stdcall у меня большие пробелы, что-то не могу нигде полноценную статью найти, может подкинет кто ссылку грамотную :-), как бы разобраться. А подключал через LoadLibrary/GetProcAddress так просто, а про Free.. забыл немного.  (Совсем Без stdcall 98ой падает напроч.).


> и что будет делать "добрый ppm", если фокусом в течение
> длит.времени обладает некое консольное приложение, не вызывающее
> ни GetMessage ни PeekMessage ?

Гонял и с консолью, все норамльно работает.


Digitman   (2005-01-26 08:38:00) [4]


> pmm ©   (24.01.05 20:42) [17]
> злым (Digitman)


"злой Digitman" иногда справку стандартную почитывает, знаешь ли.
а "добрый ppm" не удосуживается.
а в справке той написано :

The WH_MOUSE hook enables you to monitor mouse messages about to be returned by the GetMessageor PeekMessagefunction

и что будет делать "добрый ppm", если фокусом в течение длит.времени обладает некое консольное приложение, не вызывающее ни GetMessage ни PeekMessage ?


GuAV   (2005-01-25 23:44:00) [5]


> Ну вощем я тут переделал, типа думаю, что правильно
> исправил :-/


Да. SysHook должен быть общим для всех экземпляров dll.

Только не везде нужно было убрать stdcall. Всё же наверное следует разобраться что есть stdcall и вообще соглашения о вызовах.

Смысла перехода от импорта к LoadLibrary/GetProcAddress не вижу, однако если уже LoadLibrary неплохо бы и проверить результат. Также следует вызывать FreeLibrary.


pmm   (2005-01-25 11:09:00) [6]

Соглаасен, что так.
Я большой новичок в этом деле, плохо еще соображаю.

Почему приходится использовать MMF для Znach ?
А как мне сохранять Тик от разных экземляров DLL??? чтоб его потом мой ехе смог взять?
Ну вощем я тут переделал, типа думаю, что правильно исправил :-/

library hookdll;
uses
 Windows, Messages, SysUtils, Classes;
{$R *.res}

type
 PGlobalDLLData = ^TGlobalDLLData;
 TGlobalDLLData = packed record
   SysHook : HWND;
   Znach   : DWord;
 end;

const
 MMFName: PChar = 'KeyMMFDrozd';

var
 GlobalData  : PGlobalDLLData;
 MMFHandle   : THandle;

//-------------------------------------------------------------------------
function hookm(c0de, wParam, lParam : integer): Lresult;
begin
 If c0de >= 0 Then
   Begin
     GlobalData^.Znach := GetTickCount();
   End;
 result := CallNextHookEx(GlobalData^.SysHook, c0de, wParam, lParam);
end;
//-------------------------------------------------------------------------
function ShowMeTick:DWord; export;
begin
 result := GlobalData^.Znach;
end;
//-------------------------------------------------------------------------
procedure SetHook; export;
begin
 GlobalData^.SysHook := SetWindowsHookEx(WH_MOUSE, @hookm, hInstance, 0);
 if GlobalData^.SysHook = 0 then
   messagebox(0,'Error SetWindowsHookEx WH_MOUSE','ERROR',mb_iconhand);
end;
//-------------------------------------------------------------------------
procedure RemoveHook; export;
begin
 UnhookWindowsHookEx(GlobalData^.SysHook);
end;
//--------------------------------------------------------------------------
procedure OpenGlobalData();
begin
 MMFHandle:= CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE, 0, SizeOf(PGlobalDLLData), MMFName);
 if MMFHandle = 0 then
   begin
     MessageBox(0, 'Can''t create FileMapping', 'from dll', 0);
     Exit;
   end;

 GlobalData:= MapViewOfFile(MMFHandle, FILE_MAP_WRITE, 0, 0, SizeOf(PGlobalDLLData));
 if GlobalData = nil then
   begin
     CloseHandle(MMFHandle);
     MessageBox(0, 'Can''t make MapViewOfFile', 'from dll', 0);
     Exit;
   end;
end;
//-----------------------------------------------------------------------------
procedure CloseGlobalData();
begin
 UnmapViewOfFile(GlobalData);
 CloseHandle(MMFHandle);
end;
//-----------------------------------------------------------------------------
procedure DLLEntryPoint(dwReason: DWord);
begin
 case dwReason of
   DLL_PROCESS_ATTACH: OpenGlobalData;
   DLL_PROCESS_DETACH: CloseGlobalData;
 end;
end;
//*************************************
exports
 SetHook     name 'myhookset',
 RemoveHook  name 'myhookrem',
 ShowMeTick  name 'showmetick';
//*************************************
begin
 DLLProc:= @DLLEntryPoint;          
 DLLEntryPoint(DLL_PROCESS_ATTACH);

 GlobalData^.Znach := 0;
end.

EXE

unit Unit1;
interface
uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls, ExtCtrls, DateUtils, ComCtrls;

type
 TForm1 = class(TForm)
   Button1: TButton;
   Button2: TButton;
   Edit1: TEdit;
   Timer1: TTimer;
   procedure Button1Click(Sender: TObject);
   procedure Button2Click(Sender: TObject);
   procedure Timer1Timer(Sender: TObject);

 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

 SetHook:procedure;
 UnSetHook:procedure;
 ShowMeTick:function:DWord;

 fhand:Thandle;

implementation
{$R *.dfm}
//---------------------------------------------------
procedure TForm1.Button1Click(Sender: TObject);
begin
 @SetHook    := nil;
 @UnSetHook  := nil;
 @ShowMeTick := nil;

 fhand       := LoadLibrary('hookdll.dll');
 @SetHook    := GetProcAddress(fhand,'myhookset');
 @UnSetHook  := GetProcAddress(fhand,'myhookrem');
 @ShowMeTick := GetProcAddress(fhand,'showmetick');

 SetHook;
 Timer1.Interval := 1000;
end;
//---------------------------------------------------
procedure TForm1.Button2Click(Sender: TObject);
begin
 UnSetHook;
end;
//---------------------------------------------------
procedure TForm1.Timer1Timer(Sender: TObject);
var
 Period: DWord;
begin
 Period := (GetTickCount() - ShowMeTick);
 Edit1.Text := IntToStr(Period);
end;
//---------------------------------------------------
end.


GuAV   (2005-01-25 08:25:00) [7]

pmm ©   (25.01.05 7:35) [19]

Это ещё не значит что ошибок нет.

хинт:
Почему приходится использовать MMF для Znach ?
Чему равен Hm для разных экземпляров библиотеки, если он не в GlobalData ?

В 9х надо передавать в CallNextHookEx именно Hm. Иначе могут быть проблемы, причём не с твоим хуком, а с другими.

И вот не-согласование:
в dll

> procedure sethook;export; stdcall;

в ехе

> procedure SetHook; External 'hookdll.dll' name
> 'myhookset';

работает только потому что параметров нет вообще.


pmm   (2005-01-25 07:35:00) [8]

Полдня гоняю уже, все путем работает, на всех платформах. :-)


GuAV   (2005-01-24 21:51:00) [9]

Надеюсь это тоже учтено


> Плюс есть ещё проблемы, с stdcall которые пока не
> сказываются на работу, но тем не менее следует
>разобраться и испавить.
>
> И ещё, в 9х могут быть проблемы с CallNextHookEx, т.к.
> там перый параметр CallNextHookEx не игнорируется.


pmm   (2005-01-24 20:42:00) [10]

Все теперь работает [16].
Спасибо люди добрые, и злым (Digitman) тоже спасибо.


GuAV   (2005-01-24 17:23:00) [11]


>pmm ©
>я сомневаюсь что дело в нем.
> Я тоже ;-))

А я таки вижу проблему

> procedure DLLEntryPoint(dwReason: DWord); stdcall;

См справку по DLLProc. где там stdcall ?

Плюс есть ещё проблемы, с stdcall которые пока не сказываются на работу, но тем не менее следует разобраться и испавить.

И ещё, в 9х могут быть проблемы с CallNextHookEx, т.к. там перый параметр CallNextHookEx не игнорируется.


Eraser   (2005-01-24 16:59:00) [12]

pmm ©
я сомневаюсь что дело в нем.

Я тоже ;-))


pmm   (2005-01-24 16:54:00) [13]

Так, понятно, что ничего не понятно.
Мне то что делать? Я никогда не интересовался, что такое stdcall, но что то я сомневаюсь что дело в нем.


Eraser   (2005-01-24 16:53:00) [14]

BiN ©
Да.


BiN   (2005-01-24 16:22:00) [15]

Я имею ввиду, что функция обратного вызова обязана вызываться с соглашением о вызовах stdcall

Вероятно, имеется ввиду все-таки функция обратного вызова функции   SetWindowsHookEx?


Eraser   (2005-01-24 16:09:00) [16]

BiN ©
Я имею ввиду, что функция обратного вызова обязана вызываться с соглашением о вызовах stdcall, а экспортируемые функции не обязаны, правда если их объявлять без stdcall их будет проблемотично использовать например из MSVC++.


BiN   (2005-01-24 15:41:00) [17]

Вообще stdcall должен быть только около функции обратного вызова, но по идеи что плохого, если и не только возле неё.

Ты хоть сам понял, что сказал?


Eraser   (2005-01-24 15:02:00) [18]

Вообще stdcall должен быть только около функции обратного вызова, но по идеи что плохого, если и не только возле неё.
Я одно время ко всем экспортируемым функциям приписывал stdcall (тоже содрал где-то ;-))- работало. Правда не знаю как насчёт hookdll...


Digitman   (2005-01-24 14:25:00) [19]


> pmm ©   (24.01.05 13:44) [7]


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


pmm   (2005-01-24 13:44:00) [20]

2Eraser

Такой же абсолютно пример я и взял из инета, только он был с сообщениями и я его "упростил под себя". Так вот он ту же ошибку выдает, хотя примерчик этот опубликован на многих сайтах и примерно один и тот же, и автор утверждает что все работает круто. Я на всех платформах проверял и на нескольких компьютерах -- выдает ошибку.
А бездействие в ХР или 2к очень просто отследить, там функция АПИшная есть, а вот в 98 нет такой функции - нужно ловушкой.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо