Thread View: alt.comp.borland-delphi
31 messages
31 total messages
Started by 0BIT
Wed, 30 Apr 2003 10:51
Getting var from dll
Author: 0BIT
Date: Wed, 30 Apr 2003 10:51
Date: Wed, 30 Apr 2003 10:51
145 lines
5484 bytes
5484 bytes
I have this dll and i want to read a var (MouseInfo) from it.
The program wich uses this dll has a messagehandler routine wich uses
the GetMouseInfo function but the data it reads doesn't seem valid.
I also pass the mouse pos in WParam and LParam, these work correctly.
How can I get my prog to read the MouseInfo var ?
Do I need to do something with this var in the DllEntryPoint procedure ?
Greetings,
0BIT
library hookit;
{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }
uses
ShareMem,
SysUtils,
Classes,
Windows,StdCtrls;
{$R *.res}
type
TMouseInfo = record
nCode : Longint;
MHS : MOUSEHOOKSTRUCT;
end;
var
WindowHandle : pHandle;
hObjHandle: THandle;
{ recieve_window : HWND;}
MouseHook : HHOOK = 0;
MouseInfo : TMouseInfo;
function MouseProc(nCode : Longint; wp : WPARAM; lp : LPARAM) : DWORD;
stdcall;
begin
if nCode<0 then begin
Result:=CallNextHookEx(MouseHook,nCode,wp,lp);
Exit;
end;
{ Beep(1000,1);}
MouseInfo.nCode:=nCode;
MouseInfo.MHS:=MOUSEHOOKSTRUCT(Pointer(lp)^);
SendMessage(WindowHandle^,
RegisterWindowMessage('MouseHookMessage'),
MOUSEHOOKSTRUCT(Pointer(lp)^).pt.X,
MOUSEHOOKSTRUCT(Pointer(lp)^).pt.Y);
CallNextHookEx(MouseHook,nCode,wp,lp);
Result:=0;
end;
function GetMouseInfo : TMouseInfo; export;
begin
Result:=MouseInfo;
end;
function HookMouse(ML : TLabel; recieve_win : THandle) : Boolean; export;
begin
if MouseHook=0 then begin
WindowHandle^:=recieve_win;
MouseHook:=SetWindowsHookEx(WH_MOUSE,@MouseProc,hInstance,0);
Result:=MouseHook<>0;
end else
Result:=False;
end;
function UnHookMouse : Boolean; export;
begin
if MouseHook<>0 then begin
if UnHookWindowsHookEx(MouseHook) then begin
MouseHook:=0;
Result:=True;
end else
Result:=False;
end else
Result:=false;
end;
procedure DllEntryPoint(dwReason: dword);
begin
case dwReason of
DLL_PROCESS_ATTACH:
begin
{*** 2DO Alleen 1 keer laden ***}
hObjHandle := 0;
WindowHandle := nil;
hObjHandle := CreateFileMapping($ffffffff, nil,
PAGE_READWRITE, 0, sizeof(hWnd), 'IdleWindowHandle');
if hObjHandle = 0 then
begin
MessageBox(0, 'hookit.dll', 'Could not create file map
object', MB_OK);
exit;
end;
WindowHandle := MapViewOfFile(hObjHandle, FILE_MAP_WRITE, 0,
0, SizeOf(hWnd));
if WindowHandle = nil then
begin
CloseHandle(hObjHandle);
MessageBox(0, 'hookit.dll', 'Could not map file',
MB_OK);
exit;
end;
end;
DLL_PROCESS_DETACH:
begin
if WindowHandle <> nil then
begin
UnMapViewOfFile(WindowHandle);
WindowHandle := NIL;
end;
if hObjHandle > 0 then
begin
CloseHandle(hObjHandle);
hObjHandle := 0;
end;
end;
end;
end;
exports
GetMouseInfo,
HookMouse {name 'HookMouse'},
UnHookMouse {name 'UnHookMouse'};
begin
DLLProc := @DllEntryPoint;
DllEntryPoint(DLL_PROCESS_ATTACH);
end.
Re: Getting var from dll
Author: John Bester
Date: Wed, 30 Apr 2003 12:10
Date: Wed, 30 Apr 2003 12:10
164 lines
6250 bytes
6250 bytes
It might work to change your function to a procedure:
procedure GetMouseInfo(var info: TMouseInfo);
begin
info := MouseInfo;
end;
--
Regards
John Bester
mailto:john.bester@adept.co.za
"0BIT" <someone@123.com> wrote in message
news:9VNra.251483$ZG5.23310542@amsnews02.chello.com...
> I have this dll and i want to read a var (MouseInfo) from it.
> The program wich uses this dll has a messagehandler routine wich uses
> the GetMouseInfo function but the data it reads doesn't seem valid.
> I also pass the mouse pos in WParam and LParam, these work correctly.
>
> How can I get my prog to read the MouseInfo var ?
> Do I need to do something with this var in the DllEntryPoint procedure ?
>
> Greetings,
> 0BIT
>
>
> library hookit;
>
> { Important note about DLL memory management: ShareMem must be the
> first unit in your library's USES clause AND your project's (select
> Project-View Source) USES clause if your DLL exports any procedures or
> functions that pass strings as parameters or function results. This
> applies to all strings passed to and from your DLL--even those that
> are nested in records and classes. ShareMem is the interface unit to
> the BORLNDMM.DLL shared memory manager, which must be deployed along
> with your DLL. To avoid using BORLNDMM.DLL, pass string information
> using PChar or ShortString parameters. }
>
> uses
> ShareMem,
> SysUtils,
> Classes,
> Windows,StdCtrls;
>
> {$R *.res}
>
> type
> TMouseInfo = record
> nCode : Longint;
> MHS : MOUSEHOOKSTRUCT;
> end;
>
> var
> WindowHandle : pHandle;
> hObjHandle: THandle;
>
> { recieve_window : HWND;}
> MouseHook : HHOOK = 0;
> MouseInfo : TMouseInfo;
>
> function MouseProc(nCode : Longint; wp : WPARAM; lp : LPARAM) : DWORD;
> stdcall;
> begin
> if nCode<0 then begin
> Result:=CallNextHookEx(MouseHook,nCode,wp,lp);
> Exit;
> end;
> { Beep(1000,1);}
> MouseInfo.nCode:=nCode;
> MouseInfo.MHS:=MOUSEHOOKSTRUCT(Pointer(lp)^);
>
> SendMessage(WindowHandle^,
> RegisterWindowMessage('MouseHookMessage'),
> MOUSEHOOKSTRUCT(Pointer(lp)^).pt.X,
> MOUSEHOOKSTRUCT(Pointer(lp)^).pt.Y);
>
> CallNextHookEx(MouseHook,nCode,wp,lp);
> Result:=0;
> end;
>
> function GetMouseInfo : TMouseInfo; export;
> begin
> Result:=MouseInfo;
> end;
>
> function HookMouse(ML : TLabel; recieve_win : THandle) : Boolean; export;
> begin
> if MouseHook=0 then begin
> WindowHandle^:=recieve_win;
> MouseHook:=SetWindowsHookEx(WH_MOUSE,@MouseProc,hInstance,0);
> Result:=MouseHook<>0;
> end else
> Result:=False;
> end;
>
> function UnHookMouse : Boolean; export;
> begin
> if MouseHook<>0 then begin
> if UnHookWindowsHookEx(MouseHook) then begin
> MouseHook:=0;
> Result:=True;
> end else
> Result:=False;
> end else
> Result:=false;
> end;
>
> procedure DllEntryPoint(dwReason: dword);
> begin
> case dwReason of
> DLL_PROCESS_ATTACH:
> begin
> {*** 2DO Alleen 1 keer laden ***}
> hObjHandle := 0;
> WindowHandle := nil;
> hObjHandle := CreateFileMapping($ffffffff, nil,
> PAGE_READWRITE, 0, sizeof(hWnd), 'IdleWindowHandle');
> if hObjHandle = 0 then
> begin
> MessageBox(0, 'hookit.dll', 'Could not create file map
> object', MB_OK);
> exit;
> end;
>
> WindowHandle := MapViewOfFile(hObjHandle, FILE_MAP_WRITE,
0,
> 0, SizeOf(hWnd));
> if WindowHandle = nil then
> begin
> CloseHandle(hObjHandle);
> MessageBox(0, 'hookit.dll', 'Could not map file',
> MB_OK);
> exit;
> end;
> end;
> DLL_PROCESS_DETACH:
> begin
> if WindowHandle <> nil then
> begin
> UnMapViewOfFile(WindowHandle);
> WindowHandle := NIL;
> end;
> if hObjHandle > 0 then
> begin
> CloseHandle(hObjHandle);
> hObjHandle := 0;
> end;
> end;
> end;
> end;
>
> exports
> GetMouseInfo,
> HookMouse {name 'HookMouse'},
> UnHookMouse {name 'UnHookMouse'};
>
> begin
> DLLProc := @DllEntryPoint;
> DllEntryPoint(DLL_PROCESS_ATTACH);
> end.
>
>
Re: Getting var from dll
Author: J French
Date: Wed, 30 Apr 2003 12:28
Date: Wed, 30 Apr 2003 12:28
62 lines
3443 bytes
3443 bytes
On Wed, 30 Apr 2003 10:51:49 GMT, "0BIT" <someone@123.com> wrote:
>I have this dll and i want to read a var (MouseInfo) from it.
>The program wich uses this dll has a messagehandler routine wich uses
>the GetMouseInfo function but the data it reads doesn't seem valid.
>I also pass the mouse pos in WParam and LParam, these work correctly.
>
>How can I get my prog to read the MouseInfo var ?
>Do I need to do something with this var in the DllEntryPoint procedure ?
Almost certainly not
Except to initialize them to something daft as a test
begin
// DLLProc := @DllEntryPoint; <- Unused ?
// DllEntryPoint(DLL_PROCESS_ATTACH); < ???
MouseInfo.nCode := -1 ;
MouseInfo.MHS.POINT.X := -1;
MouseInfo.MHS.POINT.Y := -1;
etc
<snip>
Also looking at it I can't see why you are using ShareMem
As a matter of principle I would use the Packed keyword for records
- in this case it does not matter
I can't see what all the stuff in
procedure DllEntryPoint(dwReason: dword);
is doing
- it looks like some sort of derivative of the LibMain procedure that
is core to DLLs, but delphi provides automatically
To test returning the Record, just scrub out the rest of the code and
fill the record with known values
I would use Move() to copy the bytes into your record
- I can't quite see whether
MouseInfo.MHS:=MOUSEHOOKSTRUCT(Pointer(lp)^);
would work
- I would just feel happier moving the bytes
Move( LP, MouseInfo.MHS, SizeOf( MouseInfo.MHS ) )
If you post what you expect this to do, then it would be a lot easier
to figure out what might be happening
BTW Repeatedly doing :
RegisterWindowMessage('MouseHookMessage')
Is a tad pointless
SendMessage(
WindowHandle,
MyMouseHookMessage,
MouseInfo.MHS.pt.X,
MouseInfo.MHS.pt.X )
I am curious what functionality you get from this DLL
Re: Getting var from dll
Author: 0BIT
Date: Wed, 30 Apr 2003 13:08
Date: Wed, 30 Apr 2003 13:08
83 lines
4305 bytes
4305 bytes
"J French" <Bounce_It_jerry@iss.u-net.com_.bin> wrote in message
news:3eafbbb4.18879046@news.u-net.com...
> On Wed, 30 Apr 2003 10:51:49 GMT, "0BIT" <someone@123.com> wrote:
>
> >I have this dll and i want to read a var (MouseInfo) from it.
> >The program wich uses this dll has a messagehandler routine wich uses
> >the GetMouseInfo function but the data it reads doesn't seem valid.
> >I also pass the mouse pos in WParam and LParam, these work correctly.
> >
> >How can I get my prog to read the MouseInfo var ?
> >Do I need to do something with this var in the DllEntryPoint procedure ?
>
> Almost certainly not
> Except to initialize them to something daft as a test
>
> begin
> // DLLProc := @DllEntryPoint; <- Unused ?
> // DllEntryPoint(DLL_PROCESS_ATTACH); < ???
>
> MouseInfo.nCode := -1 ;
> MouseInfo.MHS.POINT.X := -1;
> MouseInfo.MHS.POINT.Y := -1;
> etc
>
> <snip>
>
> Also looking at it I can't see why you are using ShareMem
>
> As a matter of principle I would use the Packed keyword for records
> - in this case it does not matter
>
> I can't see what all the stuff in
> procedure DllEntryPoint(dwReason: dword);
> is doing
> - it looks like some sort of derivative of the LibMain procedure that
> is core to DLLs, but delphi provides automatically
>
> To test returning the Record, just scrub out the rest of the code and
> fill the record with known values
>
> I would use Move() to copy the bytes into your record
> - I can't quite see whether
> MouseInfo.MHS:=MOUSEHOOKSTRUCT(Pointer(lp)^);
> would work
>
> - I would just feel happier moving the bytes
>
> Move( LP, MouseInfo.MHS, SizeOf( MouseInfo.MHS ) )
>
> If you post what you expect this to do, then it would be a lot easier
> to figure out what might be happening
>
> BTW Repeatedly doing :
> RegisterWindowMessage('MouseHookMessage')
>
> Is a tad pointless
>
> SendMessage(
> WindowHandle,
> MyMouseHookMessage,
> MouseInfo.MHS.pt.X,
> MouseInfo.MHS.pt.X )
>
> I am curious what functionality you get from this DLL
Ok i've changed it to:
Move(Pointer(lp)^,MouseInfo.MHS,SizeOf(MOUSEHOOKSTRUCT));
And removed the ShareMem unit.
And add packed for the TMouseInfo
The dll_entry code I got from someone on the newsgroup.
My MouseProc gets called on every mouse signal,
In the procedure wich recieves the messages (in my main program) I call
GetMouseInfo but,
when the mouse moves out of the program's form the data wich GetMouseInfo
returns
is not correct (it doesn't even seem to be updated), but the WParam and the
LParam are the correct mouse coordinates.
But I want all the info from my MouseProc in the main program wich displays
the info on the form...
0BIT
Re: Getting var from dll
Author: J French
Date: Wed, 30 Apr 2003 15:17
Date: Wed, 30 Apr 2003 15:17
117 lines
5107 bytes
5107 bytes
On Wed, 30 Apr 2003 13:08:15 GMT, "0BIT" <someone@123.com> wrote:
>
>"J French" <Bounce_It_jerry@iss.u-net.com_.bin> wrote in message
>news:3eafbbb4.18879046@news.u-net.com...
>> On Wed, 30 Apr 2003 10:51:49 GMT, "0BIT" <someone@123.com> wrote:
>>
<snip>
I think I follow what is going on
What is happening is this:
// Here we have hooked all mouse activity
function MouseProc(nCode : Longint; wp : WPARAM; lp : LPARAM) : DWORD;
stdcall;
begin
// here we handle stuff not meant for us - or our children
// just continue the chain
if nCode<0 then begin
Result:=CallNextHookEx(MouseHook,nCode,wp,lp);
Exit;
end;
// here we have something that is sent to our Handle
// or below
{ Beep(1000,1);}
// here I reckon you inserted some code
MouseInfo.nCode:=nCode;
MouseInfo.MHS:=MOUSEHOOKSTRUCT(Pointer(lp)^);
// here we send the X and Y coordinates off
// to a TOTALLY different application
// (and one that does not exist on your system)
// err... no you had to supply the Window handle
// this is a form of Callback to your own App
// - but no way are you set up to 'listen' for it
SendMessage(WindowHandle^,
RegisterWindowMessage('MouseHookMessage'),
MOUSEHOOKSTRUCT(Pointer(lp)^).pt.X,
MOUSEHOOKSTRUCT(Pointer(lp)^).pt.Y);
// and here we do EXACTLY the same as one does
// if the message is not meant for you
CallNextHookEx(MouseHook,nCode,wp,lp);
Result:=0;
end;
Basically, for you (or what you want) this is a load of cobblers,
somebody kindly posted a 'general purpose' dll that does all sorts of
strange and wonderful things
- it would have been kinder of them to just say :-
'look at SetWindowsHookEx(WH_MOUSE,@MouseProc,hInstance,0); '
What you ACTUALLY want (caps for emphasis) is this :-
function MouseProc(nCode : Longint; wp : WPARAM; lp : LPARAM) : DWORD;
stdcall;
begin
// now we grab data
MouseInfo.nCode:=nCode;
Move( LP, MouseInfo.MHS, SizeOf( MouseInfo.MHS ) )
// now we let Winders do its thing
Result:=CallNextHookEx(MouseHook,nCode,wp,lp);
end;
Of course, because you are sampling from the outside, probably on a
Timer, you will not necessarily be getting ALL the messages
I'm not sure whether this is a 'global' hook
<quote>
nCode
Specifies a code the hook procedure uses to determine how to process
the message. This parameter can be one of the following values:
Value Meaning
HC_ACTION The wParam and lParam parameters contain information
about a mouse message.
HC_NOREMOVE The wParam and lParam parameters contain information
about a mouse message, and the mouse message has not been removed from
the message queue. (An application called the PeekMessage function,
specifying the PM_NOREMOVE flag.)
If nCode is less than zero, the hook procedure must pass the message
to the CallNextHookEx function without further processing and should
return the value returned by CallNextHookEx.
</quote>
Now, whether that stuff means that you are getting other Apps' mouse
messages - or it is just saying 'don't touch' some of the messages is
pretty hard to say.
What is it you really want to do ?
- If it is to 'trace' all mouse activity I am not sure ...
- If it is to locate the Mouse then have a look at TMouse
(I only heard of it a few days ago, before then I was using the API
GetCursorPos)
This is the stuff from Win32 Programmer's Reference :-
Re: Getting var from dll
Author: 0BIT
Date: Wed, 30 Apr 2003 16:38
Date: Wed, 30 Apr 2003 16:38
725 lines
15835 bytes
15835 bytes
I've created an example program so you can see the difference between x y
and wp lp.
They should show the same values...but they don't when the mouse is not
within the form of the program.
I want GetMouseInfo to pass the correct info about the mouse, but I don't
know how.
I am using D7 on WinXP.
Thanks for your help so far,
0BIT
the files:
example.dpr
program example;
uses
Forms,
examplemain in 'examplemain.pas' {Form1};
{$R *.res}
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
examplemain.pas
unit examplemain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
LabelMousePos: TLabel;
Button1: TButton;
Button2: TButton;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
HookWndHandle : THandle;
procedure HookMessageHandler(var Msg : TMessage);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
type
TMouseInfo = record
nCode : Longint;
MHS : MOUSEHOOKSTRUCT;
end;
procedure GetMouseInfo(var MI : TMouseInfo); {export;}
{function GetMouseInfo : TMouseInfo; }external 'hookit.dll' name
'GetMouseInfo';
function HookMouse(ML : TLabel; recieve_win : THandle) : Boolean; external
'hookit.dll' name 'HookMouse';
function UnHookMouse : Boolean; external 'hookit.dll' name 'UnHookMouse';
procedure TForm1.HookMessageHandler(var Msg : TMessage);
var
MouseInfo : TMouseInfo;
begin
if Msg.Msg=RegisterWindowMessage('MouseHookMessage') then begin
GetMouseInfo(MouseInfo);
LabelMousePos.Caption:=
' x:'
+IntToStr(MouseInfo.MHS.pt.X)
+' y:'+IntToStr(MouseInfo.MHS.pt.Y)
+' nCode: '+IntToStr(MouseInfo.nCode)
+' wp:'+IntToStr(Msg.WParam)
+' lp:'+IntToStr(Msg.LParam)
+' random'+IntToStr(Random(2000)){}
;
end;
msg.result := DefWindowProc(HookWndHandle, msg.Msg, msg.wParam,
msg.lParam);
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if HookWndHandle<>0 then begin
DeallocateHWnd(HookWndHandle);
HookWndHandle:=0;
if UnHookMouse then
ShowMessage('UnHookMouse succeeded')
else
ShowMessage('UnHookMouse failed');
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
HookWndHandle:=AllocateHWnd(HookMessageHandler);
if HookMouse(nil,HookWndHandle) then
ShowMessage('HookMouse succeeded')
else
ShowMessage('HookMouse failed');
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
if HookWndHandle<>0 then begin
DeallocateHWnd(HookWndHandle);
HookWndHandle:=0;
end;
if UnHookMouse then
ShowMessage('UnHookMouse succeeded')
else
ShowMessage('UnHookMouse failed');
end;
end.
examplemain.dfm
object Form1: TForm1
Left = 192
Top = 114
Width = 696
Height = 480
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
OnClose = FormClose
PixelsPerInch = 96
TextHeight = 13
object LabelMousePos: TLabel
Left = 72
Top = 72
Width = 76
Height = 13
Caption = 'LabelMousePos'
end
object Button1: TButton
Left = 112
Top = 160
Width = 75
Height = 25
Caption = 'Hook'
TabOrder = 0
OnClick = Button1Click
end
object Button2: TButton
Left = 112
Top = 200
Width = 75
Height = 25
Caption = 'UnHook'
TabOrder = 1
OnClick = Button2Click
end
end
example.dof
[FileVersion]
Version=7.0
[Compiler]
A=8
B=0
C=1
D=1
E=0
F=0
G=1
H=1
I=1
J=0
K=0
L=1
M=0
N=1
O=1
P=1
Q=0
R=0
S=0
T=0
U=0
V=1
W=0
X=1
Y=1
Z=1
ShowHints=1
ShowWarnings=1
UnitAliases=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiE
rrs=BDE;
NamespacePrefix=
SymbolDeprecated=1
SymbolLibrary=1
SymbolPlatform=1
UnitLibrary=1
UnitPlatform=1
UnitDeprecated=1
HResultCompat=1
HidingMember=1
HiddenVirtual=1
Garbage=1
BoundsError=1
ZeroNilCompat=1
StringConstTruncated=1
ForLoopVarVarPar=1
TypedConstVarPar=1
AsgToTypedConst=1
CaseLabelRange=1
ForVariable=1
ConstructingAbstract=1
ComparisonFalse=1
ComparisonTrue=1
ComparingSignedUnsigned=1
CombiningSignedUnsigned=1
UnsupportedConstruct=1
FileOpen=1
FileOpenUnitSrc=1
BadGlobalSymbol=1
DuplicateConstructorDestructor=1
InvalidDirective=1
PackageNoLink=1
PackageThreadVar=1
ImplicitImport=1
HPPEMITIgnored=1
NoRetVal=1
UseBeforeDef=1
ForLoopVarUndef=1
UnitNameMismatch=1
NoCFGFileFound=1
MessageDirective=1
ImplicitVariants=1
UnicodeToLocale=1
LocaleToUnicode=1
ImagebaseMultiple=1
SuspiciousTypecast=1
PrivatePropAccessor=1
UnsafeType=0
UnsafeCode=0
UnsafeCast=0
[Linker]
MapFile=0
OutputObjs=0
ConsoleApp=1
DebugInfo=0
RemoteSymbols=0
MinStackSize=16384
MaxStackSize=1048576
ImageBase=4194304
ExeDescription=
[Directories]
OutputDir=
UnitOutputDir=
PackageDLLOutputDir=
PackageDCPOutputDir=
SearchPath=
Packages=vcl;rtl;vclx;indy;inet;xmlrtl;vclie;inetdbbde;inetdbxpress;dbrtl;ds
nap;dsnapcon;vcldb;soaprtl;VclSmp;dbexpress;dbxcds;inetdb;bdertl;vcldbx;webd
snap;websnap;adortl;ibxpress;teeui;teedb;tee;dss;visualclx;visualdbclx;vclac
tnband;vclshlctrls;IntrawebDB_50_70;Intraweb_50_70;Rave50CLX;Rave50VCL;dclOf
ficeXP;PackApi;TFileMonitor
Conditionals=
DebugSourceDirs=
UsePackages=1
[Parameters]
RunParams=
HostApplication=
Launcher=
UseLauncher=0
DebugCWD=
[Language]
ActiveLang=
ProjectLang=
RootDir=C:\Program Files\Borland\Delphi7\Bin\
[Version Info]
IncludeVerInfo=0
AutoIncBuild=0
MajorVer=1
MinorVer=0
Release=0
Build=0
Debug=0
PreRelease=0
Special=0
Private=0
DLL=0
Locale=1043
CodePage=1252
[Version Info Keys]
CompanyName=
FileDescription=
FileVersion=1.0.0.0
InternalName=
LegalCopyright=
LegalTrademarks=
OriginalFilename=
ProductName=
ProductVersion=1.0.0.0
Comments=
[Excluded Packages]
C:\Program Files\BoldSoft\BfDR40D7Trial\Bin\Bold40D7ComGUI.bpl=Bold for
Delphi 4.0 (COM GUI controls)
C:\Program Files\BoldSoft\BfDR40D7Trial\Bin\Bold40D7OLLE.bpl=Bold for Delphi
4.0 Object Lending Library Extension (OLLE)
example.cfg
-$A8
-$B-
-$C+
-$D+
-$E-
-$F-
-$G+
-$H+
-$I+
-$J-
-$K-
-$L+
-$M-
-$N+
-$O+
-$P+
-$Q-
-$R-
-$S-
-$T-
-$U-
-$V+
-$W-
-$X+
-$YD
-$Z1
-cg
-AWinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;
-H+
-W+
-M
-$M16384,1048576
-K$00400000
-LE"c:\program files\borland\delphi7\Projects\Bpl"
-LN"c:\program files\borland\delphi7\Projects\Bpl"
-LUvcl;rtl;vclx;indy;inet;xmlrtl;vclie;inetdbbde;inetdbxpress;dbrtl;dsnap;ds
napcon;vcldb;soaprtl;VclSmp;dbexpress;dbxcds;inetdb;bdertl;vcldbx;webdsnap;w
ebsnap;adortl;ibxpress;teeui;teedb;tee;dss;visualclx;visualdbclx;vclactnband
;vclshlctrls;IntrawebDB_50_70;Intraweb_50_70;Rave50CLX;Rave50VCL;dclOfficeXP
;PackApi;TFileMonitor
-w-UNSAFE_TYPE
-w-UNSAFE_CODE
-w-UNSAFE_CAST
hookit.dpr
library hookit;
{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }
uses
{ ShareMem,}
SysUtils,
Classes,
Windows,StdCtrls;
{$R *.res}
type
TMouseInfo = packed record
nCode : Longint;
MHS : MOUSEHOOKSTRUCT;
end;
var
WindowHandle : pHandle;
hObjHandle: THandle;
{ recieve_window : HWND;}
MouseHook : HHOOK = 0;
MouseInfo : TMouseInfo;
function MouseProc(nCode : Longint; wp : WPARAM; lp : LPARAM) : DWORD;
stdcall;
begin
if nCode<0 then begin
Result:=CallNextHookEx(MouseHook,nCode,wp,lp);
Exit;
end;
{ Beep(1000,1);}
MouseInfo.nCode:=nCode;
{ MouseInfo.MHS:=MOUSEHOOKSTRUCT(Pointer(lp)^);}
Move(Pointer(lp)^,MouseInfo.MHS,SizeOf(MOUSEHOOKSTRUCT));
SendMessage(WindowHandle^,
RegisterWindowMessage('MouseHookMessage'),
MOUSEHOOKSTRUCT(Pointer(lp)^).pt.X,
MOUSEHOOKSTRUCT(Pointer(lp)^).pt.Y);
CallNextHookEx(MouseHook,nCode,wp,lp);
Result:=0;
end;
procedure GetMouseInfo(var MI : TMouseInfo); export;
begin
Move(MouseInfo,MI,SizeOf(TMouseInfo));
{ Result:=MouseInfo;}
end;
function HookMouse(ML : TLabel; recieve_win : THandle) : Boolean; export;
begin
if MouseHook=0 then begin
WindowHandle^:=recieve_win;
MouseHook:=SetWindowsHookEx(WH_MOUSE,@MouseProc,hInstance,0);
Result:=MouseHook<>0;
end else
Result:=False;
end;
function UnHookMouse : Boolean; export;
begin
if MouseHook<>0 then begin
if UnHookWindowsHookEx(MouseHook) then begin
MouseHook:=0;
Result:=True;
end else
Result:=False;
end else
Result:=false;
end;
procedure DllEntryPoint(dwReason: dword);
begin
case dwReason of
DLL_PROCESS_ATTACH:
begin
{*** 2DO Alleen 1 keer laden ***}
hObjHandle := 0;
WindowHandle := nil;
hObjHandle := CreateFileMapping($ffffffff, nil,
PAGE_READWRITE, 0, sizeof(hWnd), 'IdleWindowHandle');
if hObjHandle = 0 then
begin
MessageBox(0, 'hookit.dll', 'Could not create file map
object', MB_OK);
exit;
end;
WindowHandle := MapViewOfFile(hObjHandle, FILE_MAP_WRITE, 0,
0, SizeOf(hWnd));
if WindowHandle = nil then
begin
CloseHandle(hObjHandle);
MessageBox(0, 'hookit.dll', 'Could not map file',
MB_OK);
exit;
end;
end;
DLL_PROCESS_DETACH:
begin
if WindowHandle <> nil then
begin
UnMapViewOfFile(WindowHandle);
WindowHandle := NIL;
end;
if hObjHandle > 0 then
begin
CloseHandle(hObjHandle);
hObjHandle := 0;
end;
end;
end;
end;
exports
HookMouse index 0 name 'HookMouse',
UnHookMouse index 1 name 'UnHookMouse',
GetMouseInfo index 2 name 'GetMouseInfo';
begin
DLLProc := @DllEntryPoint;
DllEntryPoint(DLL_PROCESS_ATTACH);
end.
hookit.cfg
-$A8
-$B-
-$C+
-$D+
-$E-
-$F-
-$G+
-$H+
-$I+
-$J-
-$K-
-$L+
-$M-
-$N+
-$O+
-$P+
-$Q-
-$R-
-$S-
-$T-
-$U-
-$V+
-$W-
-$X+
-$YD
-$Z1
-cg
-AWinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;
-H+
-W+
-M
-$M16384,1048576
-K$00400000
-LE"c:\program files\borland\delphi7\Projects\Bpl"
-LN"c:\program files\borland\delphi7\Projects\Bpl"
-w-UNSAFE_TYPE
-w-UNSAFE_CODE
-w-UNSAFE_CAST
hookit.dof
[FileVersion]
Version=7.0
[Compiler]
A=8
B=0
C=1
D=1
E=0
F=0
G=1
H=1
I=1
J=0
K=0
L=1
M=0
N=1
O=1
P=1
Q=0
R=0
S=0
T=0
U=0
V=1
W=0
X=1
Y=1
Z=1
ShowHints=1
ShowWarnings=1
UnitAliases=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiE
rrs=BDE;
NamespacePrefix=
SymbolDeprecated=1
SymbolLibrary=1
SymbolPlatform=1
UnitLibrary=1
UnitPlatform=1
UnitDeprecated=1
HResultCompat=1
HidingMember=1
HiddenVirtual=1
Garbage=1
BoundsError=1
ZeroNilCompat=1
StringConstTruncated=1
ForLoopVarVarPar=1
TypedConstVarPar=1
AsgToTypedConst=1
CaseLabelRange=1
ForVariable=1
ConstructingAbstract=1
ComparisonFalse=1
ComparisonTrue=1
ComparingSignedUnsigned=1
CombiningSignedUnsigned=1
UnsupportedConstruct=1
FileOpen=1
FileOpenUnitSrc=1
BadGlobalSymbol=1
DuplicateConstructorDestructor=1
InvalidDirective=1
PackageNoLink=1
PackageThreadVar=1
ImplicitImport=1
HPPEMITIgnored=1
NoRetVal=1
UseBeforeDef=1
ForLoopVarUndef=1
UnitNameMismatch=1
NoCFGFileFound=1
MessageDirective=1
ImplicitVariants=1
UnicodeToLocale=1
LocaleToUnicode=1
ImagebaseMultiple=1
SuspiciousTypecast=1
PrivatePropAccessor=1
UnsafeType=0
UnsafeCode=0
UnsafeCast=0
[Linker]
MapFile=0
OutputObjs=0
ConsoleApp=1
DebugInfo=0
RemoteSymbols=0
MinStackSize=16384
MaxStackSize=1048576
ImageBase=4194304
ExeDescription=
[Directories]
OutputDir=
UnitOutputDir=
PackageDLLOutputDir=
PackageDCPOutputDir=
SearchPath=
Packages=vcl;rtl;vclx;indy;inet;xmlrtl;vclie;inetdbbde;inetdbxpress;dbrtl;ds
nap;dsnapcon;vcldb;soaprtl;VclSmp;dbexpress;dbxcds;inetdb;bdertl;vcldbx;webd
snap;websnap;adortl;ibxpress;teeui;teedb;tee;dss;visualclx;visualdbclx;vclac
tnband;vclshlctrls;IntrawebDB_50_70;Intraweb_50_70;Rave50CLX;Rave50VCL;dclOf
ficeXP;PackApi;TFileMonitor
Conditionals=
DebugSourceDirs=
UsePackages=0
[Parameters]
RunParams=
HostApplication=C:\0BIT processes\processes.exe
Launcher=
UseLauncher=0
DebugCWD=
[Language]
ActiveLang=
ProjectLang=
RootDir=C:\Program Files\Borland\Delphi7\Bin\
[Version Info]
IncludeVerInfo=0
AutoIncBuild=0
MajorVer=1
MinorVer=0
Release=0
Build=0
Debug=0
PreRelease=0
Special=0
Private=0
DLL=0
Locale=1043
CodePage=1252
[Version Info Keys]
CompanyName=
FileDescription=
FileVersion=1.0.0.0
InternalName=
LegalCopyright=
LegalTrademarks=
OriginalFilename=
ProductName=
ProductVersion=1.0.0.0
Comments=
[Excluded Packages]
C:\Program Files\BoldSoft\BfDR40D7Trial\Bin\Bold40D7ComGUI.bpl=Bold for
Delphi 4.0 (COM GUI controls)
C:\Program Files\BoldSoft\BfDR40D7Trial\Bin\Bold40D7OLLE.bpl=Bold for Delphi
4.0 Object Lending Library Extension (OLLE)
Re: Getting var from dll
Author: J French
Date: Thu, 01 May 2003 09:33
Date: Thu, 01 May 2003 09:33
47 lines
3037 bytes
3037 bytes
On Wed, 30 Apr 2003 16:38:59 GMT, "0BIT" <someone@123.com> wrote: >I've created an example program so you can see the difference between x y >and wp lp. >They should show the same values...but they don't when the mouse is not >within the form of the program. >I want GetMouseInfo to pass the correct info about the mouse, but I don't >know how. <snip> Now I know what you want to do - you want to install a System Wide Mouse Hook I have knocked up a stripped down version of your code (A DLL and a Host) It works fine when the Mouse is within the Host, but there is definitely no activity when the Mouse is outside the host. Instead of sending a message back form the DLL to the Host, I set up a simple Callback I've even polled for activity with a Timer - none found. There is definitely more to the story Snip from Win32 Programmer's reference on SetWindowsHookEx :- <quote> hMod Identifies the DLL containing the hook procedure pointed to by the lpfn parameter. The hMod parameter must be set to NULL if the dwThreadId parameter specifies a thread created by the current process and if the hook procedure is within the code associated with the current process. </quote> I detect some weasel words in :- 'if the hook procedure is within the code associated with the current process.' A DLL's code _is_ (albeit loosely) associated with the current process. Perhaps someone else has run into this scenario
Re: Getting var from dll
Author: 0BIT
Date: Thu, 01 May 2003 15:44
Date: Thu, 01 May 2003 15:44
36 lines
2938 bytes
2938 bytes
"J French" <Bounce_It_jerry@iss.u-net.com_.bin> wrote in message news:3eb0e68c.6802147@news.u-net.com... > On Wed, 30 Apr 2003 16:38:59 GMT, "0BIT" <someone@123.com> wrote: > > >I've created an example program so you can see the difference between x y > >and wp lp. > >They should show the same values...but they don't when the mouse is not > >within the form of the program. > >I want GetMouseInfo to pass the correct info about the mouse, but I don't > >know how. > <snip> > > Now I know what you want to do > - you want to install a System Wide Mouse Hook > > I have knocked up a stripped down version of your code > (A DLL and a Host) > > It works fine when the Mouse is within the Host, but there is > definitely no activity when the Mouse is outside the host. > <snip> I have D7 on an XP system, and the Host app with the HookMessageHandler prog responts on every mouse event, even if outside the form. But when outside the form the data doesn't update (the WParam and LParam of each message are correct by the way). I even tried to pass LParam (the pointer to the MOUSEHOOKSTRUCT within the callback) and then copy (the data) where it points to into a var in the HookMessageHandler, but then it crashes. I thought this was because of the mapping stuf of the dll.
Re: Getting var from dll
Author: J French
Date: Thu, 01 May 2003 16:23
Date: Thu, 01 May 2003 16:23
59 lines
3833 bytes
3833 bytes
On Thu, 01 May 2003 15:44:13 GMT, "0BIT" <someone@123.com> wrote:
<snip>
>I have D7 on an XP system, and the Host app with the HookMessageHandler prog
>responts on every mouse event, even if outside the form. But when outside
>the form the data
>doesn't update (the WParam and LParam of each message are correct by the
>way).
>
>I even tried to pass LParam (the pointer to the MOUSEHOOKSTRUCT within the
>callback)
>and then copy (the data) where it points to into a var in the
>HookMessageHandler, but then it crashes.
>
>I thought this was because of the mapping stuf of the dll.
I've had it for today, but I'll have another look
The mapping stuff seems most peculiar, the only thing I can imagine it
does is use 'IdleWindowHandle' as a semaphore of some sort
<quote>
If the function succeeds, the return value is a handle to the
file-mapping object. If the object existed before the function call,
the GetLastError function returns ERROR_ALREADY_EXISTS, and the return
value is a valid handle to the existing file-mapping object (with its
current size, not the new specified size. If the mapping object did
not exist, GetLastError returns zero.
</quote>
ERROR_ALREADY_EXISTS = 183
The routine you have fails if it gets zero back ...
So the thing must exist - interesting
Because the windows message is supposed to belong to the App, it is
possible the LP is pointing to something else's address space
Was the reading of the
MouseInfo.MHS:=MOUSEHOOKSTRUCT(Pointer(lp)^)
part of the original routine ?
Or did you add that in ?
Normally Windows Messages are pretty cagey when it comes to allowing
you to get at the data pointed to by parameters
- this is why one has to go through hoops with WM_COPYDATA
- currently it strikes me that you are getting _notified_ that a mouse
event has happened
- you can easily get the Mouse X and Y from TMouse or GetCursorPos
The other info ... I'm not sure about
GetCapture will tell you who owns the Mouse
I would not mind having a look at the original source of the DLL
- before customization
Tomorrow I think I'll trawl for: 'IdleWindowHandle'
Re: Getting var from dll
Author: 0BIT
Date: Thu, 01 May 2003 17:35
Date: Thu, 01 May 2003 17:35
403 lines
12234 bytes
12234 bytes
"J French" <Bounce_It_jerry@iss.u-net.com_.bin> wrote in message
news:3eb140d1.29914382@news.u-net.com...
> On Thu, 01 May 2003 15:44:13 GMT, "0BIT" <someone@123.com> wrote:
>
> <snip>
> >I have D7 on an XP system, and the Host app with the HookMessageHandler
prog
> >responts on every mouse event, even if outside the form. But when outside
> >the form the data
> >doesn't update (the WParam and LParam of each message are correct by the
> >way).
> >
> >I even tried to pass LParam (the pointer to the MOUSEHOOKSTRUCT within
the
> >callback)
> >and then copy (the data) where it points to into a var in the
> >HookMessageHandler, but then it crashes.
> >
> >I thought this was because of the mapping stuf of the dll.
>
> I've had it for today, but I'll have another look
>
> The mapping stuff seems most peculiar, the only thing I can imagine it
> does is use 'IdleWindowHandle' as a semaphore of some sort
>
> <quote>
> If the function succeeds, the return value is a handle to the
> file-mapping object. If the object existed before the function call,
> the GetLastError function returns ERROR_ALREADY_EXISTS, and the return
> value is a valid handle to the existing file-mapping object (with its
> current size, not the new specified size. If the mapping object did
> not exist, GetLastError returns zero.
> </quote>
>
> ERROR_ALREADY_EXISTS = 183
>
> The routine you have fails if it gets zero back ...
> So the thing must exist - interesting
>
> Because the windows message is supposed to belong to the App, it is
> possible the LP is pointing to something else's address space
>
> Was the reading of the
> MouseInfo.MHS:=MOUSEHOOKSTRUCT(Pointer(lp)^)
> part of the original routine ?
>
> Or did you add that in ?
yes added it myself...
original source at bottom...
>
> Normally Windows Messages are pretty cagey when it comes to allowing
> you to get at the data pointed to by parameters
> - this is why one has to go through hoops with WM_COPYDATA
>
Yes it works using this message : )
Tanks,
0BIT
> - currently it strikes me that you are getting _notified_ that a mouse
> event has happened
> - you can easily get the Mouse X and Y from TMouse or GetCursorPos
>
> The other info ... I'm not sure about
> GetCapture will tell you who owns the Mouse
>
> I would not mind having a look at the original source of the DLL
> - before customization
>
> Tomorrow I think I'll trawl for: 'IdleWindowHandle'
idledetect.dpr:
library idledetect;
uses
Windows, Messages;
{$R *.RES}
var
hKeyboard, hMouse: HHOOK;
WindowHandle: pHandle;
hObjHandle: THandle;
TimeOut: dword;
function IdleKeyboardProc(nCode: integer; wParam: WPARAM; lParam: LPARAM):
longint; stdcall;
begin
SendMessage(WindowHandle^, RegisterWindowMessage('IdleWindowMessage'),
wParam, lParam);
Result := CallNextHookEx(hKeyboard, nCode, wParam, lParam);
end;
function IdleMouseProc(nCode: integer; wParam: WPARAM; lParam: LPARAM):
longint; stdcall;
begin
SendMessage(WindowHandle^, RegisterWindowMessage('IdleWindowMessage'),
wParam, lParam);
Result := CallNextHookEx(hMouse, nCode, wParam, lParam);
end;
procedure SetIdleDetectionHook(hWnd: THandle; TimeOut: dword); stdcall;
begin
WindowHandle^ := hWnd;
hKeyboard := SetWindowsHookEx(WH_KEYBOARD, IdleKeyboardProc, hInstance,
0);
hMouse := SetWindowsHookEx(WH_MOUSE, IdleMouseProc, hInstance, 0);
end;
procedure SetIdleDetectionTimeOut(value: dword); stdcall;
begin
TimeOut := value;
end;
procedure UnhookIdleDetectionHook; export; stdcall;
begin
UnhookWindowsHookEx(hMouse);
UnhookWindowsHookEx(hKeyboard);
end;
procedure DllEntryPoint(dwReason: dword);
begin
case dwReason of
DLL_PROCESS_ATTACH:
begin
hObjHandle := 0;
WindowHandle := nil;
hObjHandle := CreateFileMapping($ffffffff, nil,
PAGE_READWRITE, 0, sizeof(hWnd), 'IdleWindowHandle');
if hObjHandle = 0 then
begin
MessageBox(0, 'idle detection DLL', 'Could not create
file map object', MB_OK);
exit;
end;
WindowHandle := MapViewOfFile(hObjHandle, FILE_MAP_WRITE, 0,
0, SizeOf(hWnd));
if WindowHandle = nil then
begin
CloseHandle(hObjHandle);
MessageBox(0, 'idle detection DLL', 'Could not map
file', MB_OK);
exit;
end;
end;
DLL_PROCESS_DETACH:
begin
if WindowHandle <> nil then
begin
UnMapViewOfFile(WindowHandle);
WindowHandle := NIL;
end;
if hObjHandle > 0 then
begin
CloseHandle(hObjHandle);
hObjHandle := 0;
end;
end;
end;
end;
exports
SetIdleDetectionHook index 1 name 'SetIdleDetectionHook',
SetIdleDetectionTimeOut index 2 name 'SetIdleDetectionTimeOut',
UnhookIdleDetectionHook index 3 name 'UnhookIdleDetectionHook';
begin
DLLProc := @DllEntryPoint;
DllEntryPoint(DLL_PROCESS_ATTACH);
end.
IdleDetector.pas:
unit IdleDetector;
interface
uses Windows, SysUtils, Messages, Classes, Forms;
type
TSetIdleDetectionHook = procedure(hWnd: THandle; TimeOut: dword); stdcall;
TUnhookIdleDetectionHook = procedure; stdcall;
TOnIdleEvent = procedure(Sender: TObject; IdleTime: dword) of object;
EDLLError = class(Exception);
type
TIdleDetector = class
private
FIdleWnd: THandle;
FIsIdle: boolean;
//
FOnIdle: TOnIdleEvent;
FOnTimeOut: TOnIdleEvent;
FOnWakeUp: TNotifyEvent;
//
FTicker: dword;
FTimeOut: dword; // timeout in seconds
// library interfacing
hDLLModule: HModule;
SetIdleDetectionHook: TSetIdleDetectionHook;
UnhookIdleDetectionHook: TUnhookIdleDetectionHook;
function GetDLLInterface: boolean;
procedure IdleWndProc(var msg: TMessage);
procedure SetTimeOut(value: dword);
public
constructor Create;
destructor Destroy; override;
published
property IsIdle: boolean read FIsIdle write FIsIdle;
property OnIdle: TOnIdleEvent read FOnIdle write FOnIdle;
property OnTimeOut: TOnIdleEvent read FOnTimeOut write FOnTimeOut;
property OnWakeUp: TNotifyEvent read FOnWakeUp write FOnWakeUp;
property TimeOut: dword read FTimeOut write SetTimeOut;
end;
implementation
constructor TIdleDetector.Create;
begin
GetDLLInterface;
SetTimeOut(300); // default = 5 minutes
FIsIdle := false;
end;
destructor TIdleDetector.Destroy;
begin
UnhookIdleDetectionHook;
DeallocateHWnd(FIdleWnd);
FreeLibrary(hDLLModule);
end;
function TIdleDetector.GetDLLInterface: boolean;
begin
hDLLModule := LoadLibrary('idledetect.dll');
if hDLLModule <> 0 then
begin
SetIdleDetectionHook := GetProcAddress(hDLLModule,
'SetIdleDetectionHook');
if Assigned(SetIdleDetectionHook) then
begin
UnhookIdleDetectionHook := GetProcAddress(hDLLModule,
'UnhookIdleDetectionHook');
if Assigned(UnhookIdleDetectionHook) then
begin
FIdleWnd := AllocateHWnd(IdleWndProc);
SetIdleDetectionHook(FIdleWnd, FTimeOut);
Result := true;
end
else
Result := false;
end
else
Result := false;
end
else
Result := false;
end;
procedure TIdleDetector.IdleWndProc(var msg: TMessage);
begin
if msg.Msg = RegisterWindowMessage('IdleWindowMessage') then
begin
if FIsIdle and Assigned(FOnWakeUp) then
FOnWakeUp(Self);
FIsIdle := false;
FTicker := GetTickCount;
end
else
if msg.Msg = WM_TIMER then
begin
if not FIsIdle then
begin
if (GetTickCount - FTimeOut >= FTicker) and
Assigned(FOnTimeOut) then
begin
FIsIdle := true;
FOnTimeOut(Self, (GetTickCount - FTicker) div 1000);
end;
end;
if Assigned(FOnIdle) then
FOnIdle(Self, (GetTickCount - FTicker) div 1000);
end;
msg.result := DefWindowProc(FIdleWnd, msg.Msg, msg.wParam, msg.lParam);
end;
procedure TIdleDetector.SetTimeOut(value: dword);
begin
FTimeOut := value * 1000;
SetTimer(FIdleWnd, 0, 1000, nil);
end;
end.
example.dpr:
program example;
uses
Forms,
exampleform in 'exampleform.pas' {Form1},
IdleDetector in 'IdleDetector.pas';
{$R *.RES}
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
exampleform.pas:
unit exampleform;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
IdleDetector,
StdCtrls;
type
TForm1 = class(TForm)
Memo1: TMemo;
Label1: TLabel;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
IdleDetector: TIdleDetector;
procedure IdleDetectionIdle(Sender: TObject; IdleTime: dword);
procedure IdleDetectionTimeOut(Sender: TObject; IdleTime: dword);
procedure IdleDetectionWakeUp(Sender: TObject);
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin
IdleDetector := TIdleDetector.Create;
IdleDetector.TimeOut := 5; // seconds
IdleDetector.OnIdle := IdleDetectionIdle;
IdleDetector.OnTimeOut := IdleDetectionTimeOut;
IdleDetector.OnWakeUp := IdleDetectionWakeUp;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
IdleDetector.Destroy;
end;
procedure TForm1.IdleDetectionIdle(Sender: TObject; IdleTime: dword);
begin
Label1.Caption := Format('user idle time: %d seconds', [IdleTime]);
end;
procedure TForm1.IdleDetectionTimeOut(Sender: TObject; IdleTime: dword);
begin
Memo1.Lines.Add(Format('user was idle for %d seconds', [IdleTime]));
end;
procedure TForm1.IdleDetectionWakeUp(Sender: TObject);
begin
Memo1.Lines.Add('user has woken');
end;
end.
Re: Getting var from dll
Author: KLinZ
Date: Thu, 01 May 2003 20:55
Date: Thu, 01 May 2003 20:55
14 lines
1927 bytes
1927 bytes
J French wrote:
>
> BTW Repeatedly doing :
> RegisterWindowMessage('MouseHookMessage')
>
> Is a tad pointless
>
Well, it's not. It is used to generate a unique message for this
application. RegisterWindowMessage returns an unique message. I could have
stored it in a variable though.
--
www.zenobits.com
Re: Getting var from dll
Author: KLinZ
Date: Thu, 01 May 2003 20:55
Date: Thu, 01 May 2003 20:55
13 lines
2038 bytes
2038 bytes
0BIT wrote: >> >> I would not mind having a look at the original source of the DLL >> - before customization >> > > > <snip a lot of code> Funny, I wrote it :-) So what's the problem? -- www.zenobits.com
Re: Getting var from dll
Author: J French
Date: Fri, 02 May 2003 07:57
Date: Fri, 02 May 2003 07:57
31 lines
2678 bytes
2678 bytes
On Thu, 1 May 2003 22:55:39 +0200, "KLinZ" <klinz@NOSPAMMERTSzenobits.com> wrote: >0BIT wrote: >>> >>> I would not mind having a look at the original source of the DLL >>> - before customization >>> >> >> >> <snip a lot of code> > >Funny, I wrote it :-) So what's the problem? Hi, For the past couple of days (on and off) I have been trying to figure out OBIT's problem - at first I thought the FileMapping was a red herring - now I realize that it was not - rather it is using a 'known' flag - but one that is not documented in my Win32 I think that the problem is down to the LP pointing to different memory 'areas' It is a bit tricky working on 'part modified' code - easier to move from something that works, and build on that. The IdleDetect stuff looks really interesting - where did you find out about it ?
Re: Getting var from dll
Author: J French
Date: Fri, 02 May 2003 07:57
Date: Fri, 02 May 2003 07:57
35 lines
2785 bytes
2785 bytes
On Thu, 1 May 2003 22:55:19 +0200, "KLinZ"
<klinz@NOSPAMMERTSzenobits.com> wrote:
>J French wrote:
>>
>> BTW Repeatedly doing :
>> RegisterWindowMessage('MouseHookMessage')
>>
>> Is a tad pointless
>>
>
>Well, it's not. It is used to generate a unique message for this
>application. RegisterWindowMessage returns an unique message. I could have
>stored it in a variable though.
It is not really unique to the App
- it is unique to the text 'MouseHookMessage'
There must be considerable overhead as Windows makes a 'hash' number
of the String and runs through a table
Personally I would have used GetModuleFileName, or passed a unique
string down to the DLL - it saves defining something in two places.
Actually I would have passed the address of a procedure down to the
DLL and done a straight Callback
- although that relies on the 'host' not doing anything too complex in
the Callback ... maybe a SendMessage is safer ...
Now I've seen your original code I follow what it is up to
BTW you are not using : DLLProc := @DllEntryPoint;
I assume that you are storing that in another Unit, and using the
Finalization to clean up the FileMapping.
Re: Getting var from dll
Author: J French
Date: Fri, 02 May 2003 07:57
Date: Fri, 02 May 2003 07:57
18 lines
2157 bytes
2157 bytes
On Thu, 01 May 2003 17:35:23 GMT, "0BIT" <someone@123.com> wrote: <snip> >original source at bottom... Great - Thanks > >> >> Normally Windows Messages are pretty cagey when it comes to allowing >> you to get at the data pointed to by parameters >> - this is why one has to go through hoops with WM_COPYDATA >> > >Yes it works using this message : ) >Tanks, >0BIT Ah, now how did you implement that ?
Re: Getting var from dll
Author: 0BIT
Date: Fri, 02 May 2003 10:23
Date: Fri, 02 May 2003 10:23
300 lines
8902 bytes
8902 bytes
"J French" <Bounce_It_jerry@iss.u-net.com_.bin> wrote in message
news:3eb21b81.2219420@news.u-net.com...
> On Thu, 01 May 2003 17:35:23 GMT, "0BIT" <someone@123.com> wrote:
>
> <snip>
> >original source at bottom...
>
> Great - Thanks
> >
> >>
> >> Normally Windows Messages are pretty cagey when it comes to allowing
> >> you to get at the data pointed to by parameters
> >> - this is why one has to go through hoops with WM_COPYDATA
> >>
> >
> >Yes it works using this message : )
> >Tanks,
> >0BIT
>
> Ah, now how did you implement that ?
>
>
Happy coding,
0BIT
The modified files
hookit.dpr:
library hookit;
{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }
{%File 'process.inc'}
uses
SysUtils,
Classes,
Windows,
StdCtrls,
Messages;
{$R *.res}
{$I process.inc}
var
WindowHandle : pHandle;
hObjHandle: THandle;
{ recieve_window : HWND;}
MouseHook : HHOOK = 0;
MouseInfo : TMouseInfo;
function MouseProc(nCode : Longint; wp : WPARAM; lp : LPARAM) : DWORD;
stdcall;
var
cp : COPYDATASTRUCT;
begin
if nCode<0 then begin
Result:=CallNextHookEx(MouseHook,nCode,wp,lp);
Exit;
end;
{ Beep(1000,1);}
MouseInfo.nCode:=nCode;
MouseInfo.WP:=wp;
{ MouseInfo.MHS:=MOUSEHOOKSTRUCT(Pointer(lp)^);}
Move(Pointer(lp)^,MouseInfo.MHS,SizeOf(MOUSEHOOKSTRUCT));
{ Move(Pointer(lp)^,p^.MHS,SizeOf(MOUSEHOOKSTRUCT));}
cp.dwData:=0;{dont know what this is...}
cp.cbData:=SizeOf(TMouseInfo);
cp.lpData:=@MouseInfo;
SendMessage(WindowHandle^,WM_COPYDATA,0,Integer(@cp));{should pass current
HWND}
(* SendMessage(WindowHandle^,
RegisterWindowMessage('MouseHookMessage'),
MOUSEHOOKSTRUCT(Pointer(lp)^).pt.X,
lp
{ MOUSEHOOKSTRUCT(Pointer(lp)^).pt.Y});
*)
CallNextHookEx(MouseHook,nCode,wp,lp);
Result:=0;
end;
(*procedure GetMouseInfo(var MI : TMouseInfo); export;
begin
Move(MouseInfo,MI,SizeOf(TMouseInfo));
{ Result:=MouseInfo;}
end;*)
function HookMouse(recieve_win : THandle) : Boolean; export;
begin
if MouseHook=0 then begin
WindowHandle^:=recieve_win;
MouseHook:=SetWindowsHookEx(WH_MOUSE,@MouseProc,hInstance,0);
Result:=MouseHook<>0;
end else
Result:=False;
end;
function UnHookMouse : Boolean; export;
begin
if MouseHook<>0 then begin
if UnHookWindowsHookEx(MouseHook) then begin
MouseHook:=0;
Result:=True;
end else
Result:=False;
end else
Result:=false;
end;
procedure DllEntryPoint(dwReason: dword);
begin
case dwReason of
DLL_PROCESS_ATTACH:
begin
{*** 2DO Alleen 1 keer laden ***}
hObjHandle := 0;
WindowHandle := nil;
hObjHandle := CreateFileMapping($ffffffff, nil,
PAGE_READWRITE, 0, sizeof(hWnd), 'IdleWindowHandle');
if hObjHandle = 0 then
begin
MessageBox(0, 'hookit.dll', 'Could not create file map
object', MB_OK);
exit;
end;
WindowHandle := MapViewOfFile(hObjHandle, FILE_MAP_WRITE, 0,
0, SizeOf(hWnd));
if WindowHandle = nil then
begin
CloseHandle(hObjHandle);
MessageBox(0, 'hookit.dll', 'Could not map file',
MB_OK);
exit;
end;
end;
DLL_PROCESS_DETACH:
begin
if WindowHandle <> nil then
begin
UnMapViewOfFile(WindowHandle);
WindowHandle := NIL;
end;
if hObjHandle > 0 then
begin
CloseHandle(hObjHandle);
hObjHandle := 0;
end;
end;
end;
end;
exports
HookMouse index 0 name 'HookMouse',
UnHookMouse index 1 name 'UnHookMouse';
begin
DLLProc := @DllEntryPoint;
DllEntryPoint(DLL_PROCESS_ATTACH);
end.
examplemain.pas:
unit examplemain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
LabelMousePos: TLabel;
Button1: TButton;
Button2: TButton;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
HookWndHandle : THandle;
procedure HookMessageHandler(var Msg : TMessage);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{$I process.inc}
function HookMouse(recieve_win : THandle) : Boolean; external 'hookit.dll'
name 'HookMouse';
function UnHookMouse : Boolean; external 'hookit.dll' name 'UnHookMouse';
procedure TForm1.HookMessageHandler(var Msg : TMessage);
var
MouseInfo : TMouseInfo;
begin
if Msg.Msg=WM_COPYDATA then begin
{2DO: should check for what data is received...}
Move(
COPYDATASTRUCT(
pointer(
Msg.LParam
)^
).lpData^
,MouseInfo,SizeOf(TMouseInfo)
);
LabelMousePos.Caption:=
' x:'+IntToStr(MouseInfo.MHS.pt.X)
+' y:'+IntToStr(MouseInfo.MHS.pt.Y)
+' wp:'+IntToStr(MouseInfo.WP)
+' nCode: '+IntToStr(MouseInfo.nCode)
+' '+IntToStr(Random(2000))
;
end;
msg.result := DefWindowProc(HookWndHandle, msg.Msg, msg.wParam,
msg.lParam);
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if HookWndHandle<>0 then begin
DeallocateHWnd(HookWndHandle);
HookWndHandle:=0;
if UnHookMouse then
ShowMessage('UnHookMouse succeeded')
else
ShowMessage('UnHookMouse failed');
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
HookWndHandle:=AllocateHWnd(HookMessageHandler);
if HookMouse(HookWndHandle) then
ShowMessage('HookMouse succeeded')
else
ShowMessage('HookMouse failed');
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
if HookWndHandle<>0 then begin
DeallocateHWnd(HookWndHandle);
HookWndHandle:=0;
end;
if UnHookMouse then
ShowMessage('UnHookMouse succeeded')
else
ShowMessage('UnHookMouse failed');
end;
end.
process.inc:
type
TMouseInfo = packed record
nCode : Longint;
WP : WParam;
MHS : MOUSEHOOKSTRUCT;
end;
Re: Getting var from dll
Author: J French
Date: Fri, 02 May 2003 12:14
Date: Fri, 02 May 2003 12:14
88 lines
3953 bytes
3953 bytes
On Fri, 02 May 2003 10:23:41 GMT, "0BIT" <someone@123.com> wrote:
<snip>
Very impressive
- it works a treat under Win95
- so thats another OS version you can tick off
<snip>
> cp.dwData:=0;{dont know what this is...}
Ah, that is a 'user flag' so you can tell the recipient what the data
is - eg: Bitmap, Text, RTF, some obscure creation of ones own
Just 4 bytes of data for one to play with
> cp.cbData:=SizeOf(TMouseInfo);
> cp.lpData:=@MouseInfo;
>
> SendMessage(WindowHandle^,WM_COPYDATA,0,Integer(@cp));{should pass current
>HWND}
Now the real question is 'why did WM_COPYDATA make it work ?'
WM_COPY data 'locks the memory' in a globally accessable block
- is it because the memory in the DLL was not available to the Host?
- not a chance
- is it because the memory in the DLL was getting overwritten?
- if so it would have worked, and one would probably not have
noticed it - AVs would be unlikely
Not sure ...
BTW I would suggest calling:
DllEntryPoint( DLL_PROCESS_DETACH )
At some point - that is why this is set up
begin
DLLProc := @DllEntryPoint; <=======######
DllEntryPoint(DLL_PROCESS_ATTACH);
end.
Having looked at KLinZ's original version, I am pretty sure that he
has a little Unit set up to call it
- rather like this
unit ExitHook;
{ This can be called to set a Close Down Callback
It should be the LAST in the Project/Units Uses list so it is
called LAST on initialization and FIRST on Closedown }
interface
{Uses}
Procedure SetExitHook( Hook:Pointer ) ;
implementation
Var
MyExitHook : Procedure ;
Procedure SetExitHook( Hook:Pointer ) ;
Begin
MyExitHook := Hook ;
End;
Initialization ;
Begin
End;
Finalization ;
Begin
If Assigned( MyExitHook ) Then
MyExitHook ;
End;
end.
There used to be some sort of Finalization thing in DLLs but it got
'broken' in about Delphi 3 - hence the workaround
Many thanks for posting the 'working model'
- it is (like KLinZ's code) really interesting
Later I'll try implementing the same using a Callback to notify the
Host - it might cast some light on things.
Fascinating ....
Re: Getting var from dll
Author: KLinZ
Date: Fri, 02 May 2003 22:33
Date: Fri, 02 May 2003 22:33
58 lines
3447 bytes
3447 bytes
J French wrote:
> On Thu, 1 May 2003 22:55:19 +0200, "KLinZ"
> <klinz@NOSPAMMERTSzenobits.com> wrote:
>
>> J French wrote:
>>>
>>> BTW Repeatedly doing :
>>> RegisterWindowMessage('MouseHookMessage')
>>>
>>> Is a tad pointless
>>>
>>
>> Well, it's not. It is used to generate a unique message for this
>> application. RegisterWindowMessage returns an unique message. I
>> could have stored it in a variable though.
>
> It is not really unique to the App
> - it is unique to the text 'MouseHookMessage'
>
> There must be considerable overhead as Windows makes a 'hash' number
> of the String and runs through a table
>
> Personally I would have used GetModuleFileName, or passed a unique
> string down to the DLL - it saves defining something in two places.
>
> Actually I would have passed the address of a procedure down to the
> DLL and done a straight Callback
> - although that relies on the 'host' not doing anything too complex in
> the Callback ... maybe a SendMessage is safer ...
>
> Now I've seen your original code I follow what it is up to
>
> BTW you are not using : DLLProc := @DllEntryPoint;
>
> I assume that you are storing that in another Unit, and using the
> Finalization to clean up the FileMapping.
No, it's in the case statement:
case
DLL_PROCESS_DETACH:
begin
if WindowHandle <> nil then
begin
UnMapViewOfFile(WindowHandle);
WindowHandle := NIL;
end;
if hObjHandle > 0 then
begin
CloseHandle(hObjHandle);
hObjHandle := 0;
end;
end;
end;
--
www.zenobits.com
Re: Getting var from dll
Author: J French
Date: Sat, 03 May 2003 07:41
Date: Sat, 03 May 2003 07:41
70 lines
3764 bytes
3764 bytes
The code never calls the routine with:
DLL_PROCESS_DETACH
Also:
DLLProc := @DllEntryPoint;
DLLProc is never used
On Sat, 3 May 2003 00:33:24 +0200, "KLinZ"
<klinz@NOSPAMMERTSzenobits.com> wrote:
>J French wrote:
>> On Thu, 1 May 2003 22:55:19 +0200, "KLinZ"
>> <klinz@NOSPAMMERTSzenobits.com> wrote:
>>
>>> J French wrote:
>>>>
>>>> BTW Repeatedly doing :
>>>> RegisterWindowMessage('MouseHookMessage')
>>>>
>>>> Is a tad pointless
>>>>
>>>
>>> Well, it's not. It is used to generate a unique message for this
>>> application. RegisterWindowMessage returns an unique message. I
>>> could have stored it in a variable though.
>>
>> It is not really unique to the App
>> - it is unique to the text 'MouseHookMessage'
>>
>> There must be considerable overhead as Windows makes a 'hash' number
>> of the String and runs through a table
>>
>> Personally I would have used GetModuleFileName, or passed a unique
>> string down to the DLL - it saves defining something in two places.
>>
>> Actually I would have passed the address of a procedure down to the
>> DLL and done a straight Callback
>> - although that relies on the 'host' not doing anything too complex in
>> the Callback ... maybe a SendMessage is safer ...
>>
>> Now I've seen your original code I follow what it is up to
>>
>> BTW you are not using : DLLProc := @DllEntryPoint;
>>
>> I assume that you are storing that in another Unit, and using the
>> Finalization to clean up the FileMapping.
>
>No, it's in the case statement:
>
> case
> DLL_PROCESS_DETACH:
> begin
> if WindowHandle <> nil then
> begin
> UnMapViewOfFile(WindowHandle);
> WindowHandle := NIL;
> end;
> if hObjHandle > 0 then
> begin
> CloseHandle(hObjHandle);
> hObjHandle := 0;
> end;
> end;
> end;
>
>
>--
>www.zenobits.com
Re: Getting var from dll
Author: J French
Date: Sat, 03 May 2003 08:05
Date: Sat, 03 May 2003 08:05
11 lines
1849 bytes
1849 bytes
BTW
Yesterday I searched Google and Microsft for
IdleWindowHandle
and
"IdleWindowHandle" (assuming 'C')
And found nothing, I'm really curious where you picked up this trick.
(and very impressed)
Re: Getting var from dll
Author: KLinZ
Date: Sat, 03 May 2003 09:39
Date: Sat, 03 May 2003 09:39
21 lines
2118 bytes
2118 bytes
J French wrote: > The code never calls the routine with: > > DLL_PROCESS_DETACH > In fact, it does. Put a call to MessageBox in the DLL_PROCESS_DETACH case and see for yourself. > Also: > DLLProc := @DllEntryPoint; > > DLLProc is never used > Please have look in the Delphi help under 'DLLProc variable'. -- www.zenobits.com
Re: Getting var from dll
Author: KLinZ
Date: Sat, 03 May 2003 09:41
Date: Sat, 03 May 2003 09:41
22 lines
2262 bytes
2262 bytes
J French wrote: > BTW > > Yesterday I searched Google and Microsft for > > IdleWindowHandle > and > "IdleWindowHandle" (assuming 'C') > > And found nothing, I'm really curious where you picked up this trick. > It's no trick. I could have called it with 'blaatmaarraak' for instance, it would work too. > (and very impressed) Why should you? -- www.zenobits.com
Re: Getting var from dll
Author: J French
Date: Sat, 03 May 2003 10:26
Date: Sat, 03 May 2003 10:26
13 lines
2131 bytes
2131 bytes
On Sat, 3 May 2003 11:39:50 +0200, "KLinZ" <klinz@NOSPAMMERTSzenobits.com> wrote: > >Please have look in the Delphi help under 'DLLProc variable'. Of course - that was the thing that got broken under IIRC Delphi3 - stupid of me - I should have noticed that it was a Global variable Out of curiousity, why do Handles stored in Mapped Files get activated by all Windows ?
Re: Getting var from dll
Author: KLinZ
Date: Sat, 03 May 2003 11:19
Date: Sat, 03 May 2003 11:19
28 lines
2863 bytes
2863 bytes
J French wrote: > On Sat, 3 May 2003 11:39:50 +0200, "KLinZ" > <klinz@NOSPAMMERTSzenobits.com> wrote: > > >> >> Please have look in the Delphi help under 'DLLProc variable'. > > Of course - that was the thing that got broken under IIRC Delphi3 > > - stupid of me - I should have noticed that it was a Global variable > > Out of curiousity, why do Handles stored in Mapped Files get activated > by all Windows ? It's not the handle that is activated. The entire DLL gets mapped into the target process that has focus (at least when you call SetWindowsHookEx() with WH_MOUSEHOOK or WH_KEYBOARD). The file mapping has nothing to do with it. The file mapping is only to share the data between the instances of the mapped DLL. Note that the filemapping thingie is not entirely correct yet. It doesn't work if you start the same application twice or more. The right thing is to create a linked list with handles of the calling applications in the filemapping memory, and send the messages to all those handles. -- www.zenobits.com
Re: Getting var from dll
Author: Bj�rge S�ther
Date: Mon, 05 May 2003 07:52
Date: Mon, 05 May 2003 07:52
22 lines
2249 bytes
2249 bytes
"KLinZ" <klinz@NOSPAMMERTSzenobits.com> skrev i melding news:N7Msa.4733$KF1.89311@amstwist00... > J French wrote: > > The code never calls the routine with: > > > > DLL_PROCESS_DETACH > > > > In fact, it does. Put a call to MessageBox in the DLL_PROCESS_DETACH case > and see for yourself. I believed it was the DLL_PROCESS_ATTACH that was never seen in the dllproc... ? -- Regards, Bj�rge S�ther bjorge@haha_itte.no ------------------------------------- I'll not spend any money on American Software products until armed forces are out of Iraq.
Re: Getting var from dll
Author: KLinZ
Date: Mon, 05 May 2003 20:22
Date: Mon, 05 May 2003 20:22
22 lines
2377 bytes
2377 bytes
Bj�rge S�ther wrote: > "KLinZ" <klinz@NOSPAMMERTSzenobits.com> skrev i melding > news:N7Msa.4733$KF1.89311@amstwist00... >> J French wrote: >>> The code never calls the routine with: >>> >>> DLL_PROCESS_DETACH >>> >> >> In fact, it does. Put a call to MessageBox in the DLL_PROCESS_DETACH >> case and see for yourself. > > I believed it was the DLL_PROCESS_ATTACH that was never seen in the > dllproc... ? omg. Where is this going to? Anyway, the attach is called 'by hand'. And for that reason J. French thought that the detach was never called. -- www.zenobits.com
Re: Getting var from dll
Author: J French
Date: Tue, 06 May 2003 08:34
Date: Tue, 06 May 2003 08:34
19 lines
2449 bytes
2449 bytes
On Mon, 5 May 2003 22:22:30 +0200, "KLinZ" <klinz@NOSPAMMERTSzenobits.com> wrote: I noticed somewhere that you wanted to make multiple copies of the DLL share the same Mapped File You could probably get round that by using separate File names for the mapped file - perhaps a combination of the EXEs name and the hInstance of the DLL I'm still baffled by how exactly this works The Handle of the Window (recieve_win) in the main app that is to be notified of mouse events is stored in the Mapped File Yet WindowHandle^ which refers to it is in local Data I can't see how Windows is 'aware' of any 'Global' data - yet obviously it is
Re: Getting var from dll
Author: KLinZ
Date: Tue, 06 May 2003 21:51
Date: Tue, 06 May 2003 21:51
36 lines
2784 bytes
2784 bytes
J French wrote: > On Mon, 5 May 2003 22:22:30 +0200, "KLinZ" > <klinz@NOSPAMMERTSzenobits.com> wrote: > > I noticed somewhere that you wanted to make multiple copies of the DLL > share the same Mapped File > Yes, indeed. > You could probably get round that by using separate File names for the > mapped file > - perhaps a combination of the EXEs name and the hInstance of the DLL > No no no. It's all handled by Windows. It does some nasty trick when it encounters a call to SetWindowsHook(Ex). It maps the DLL into every process which receives keyboard or mouse focus. > I'm still baffled by how exactly this works > > The Handle of the Window (recieve_win) in the main app that is to be > notified of mouse events is stored in the Mapped File > > Yet WindowHandle^ which refers to it is in local Data > No. It's in shared mem. > I can't see how Windows is 'aware' of any 'Global' data > - yet obviously it is See above. -- www.zenobits.com
Re: Getting var from dll
Author: J French
Date: Wed, 07 May 2003 08:26
Date: Wed, 07 May 2003 08:26
60 lines
3784 bytes
3784 bytes
On Tue, 6 May 2003 23:51:46 +0200, "KLinZ" <klinz@NOSPAMMERTSzenobits.com> wrote: >J French wrote: >> On Mon, 5 May 2003 22:22:30 +0200, "KLinZ" >> <klinz@NOSPAMMERTSzenobits.com> wrote: >> >> I noticed somewhere that you wanted to make multiple copies of the DLL >> share the same Mapped File >> > >Yes, indeed. > >> You could probably get round that by using separate File names for the >> mapped file >> - perhaps a combination of the EXEs name and the hInstance of the DLL >> > >No no no. It's all handled by Windows. It does some nasty trick when it >encounters a call to SetWindowsHook(Ex). It maps the DLL into every process >which receives keyboard or mouse focus. I can see it 'mapping' the DLL into all processes - however I would assume that the DLLs Data remains part of the EXE's Data area - what is still baffling me is that 'local' variables within the DLL are still there - eg: WindowHandle Yet if I make WindowHandle^ 'local' the DLL only responds to events when they are over the host EXE > >> I'm still baffled by how exactly this works >> >> The Handle of the Window (recieve_win) in the main app that is to be >> notified of mouse events is stored in the Mapped File >> >> Yet WindowHandle^ which refers to it is in local Data >> > >No. It's in shared mem. What is pointed to by WindowHandle is in 'shared/mapped' mem - but what about WindowHandle ? > >> I can't see how Windows is 'aware' of any 'Global' data >> - yet obviously it is > >See above. I still don't follow it, my understanding is that DLLs have just one copy of Code loaded, but multiple instances of Data - for different instances of the DLL - and the Data is mapped in with the Host EXE - you seem to be saying that this is not the case when SetWindowsHookEx is used Obviously I am missing something, do you have any references that explain what is really going on. > >-- >www.zenobits.com >
Re: Getting var from dll
Author: KLinZ
Date: Fri, 09 May 2003 20:20
Date: Fri, 09 May 2003 20:20
76 lines
4598 bytes
4598 bytes
J French wrote: > On Tue, 6 May 2003 23:51:46 +0200, "KLinZ" > <klinz@NOSPAMMERTSzenobits.com> wrote: > > Yet if I make WindowHandle^ 'local' the DLL only responds to events > when they are over the host EXE Yes, this is defined behaviour. The variable in the DLL that is associated with your application is correctly pointing to the app's window handle. In every other (mapped) DLL instance it's pointing nowhere (or at least, not at an useful value). >> >>> I'm still baffled by how exactly this works >>> >>> The Handle of the Window (recieve_win) in the main app that is to be >>> notified of mouse events is stored in the Mapped File >>> >>> Yet WindowHandle^ which refers to it is in local Data >>> Have a better look, WindowHandle^ is not local to the DLL. WindowHandle^ is the handle of the calling application. > What is pointed to by WindowHandle is in 'shared/mapped' mem > - but what about WindowHandle ? WindowHandle *is not* in shared memory. WindowHandle^ *is*. >> >>> I can't see how Windows is 'aware' of any 'Global' data >>> - yet obviously it is >> >> See above. > I still don't follow it, my understanding is that DLLs have just one > copy of Code loaded, but multiple instances of Data > - for different instances of the DLL > - and the Data is mapped in with the Host EXE > Yes, that's the main idea of DLL's. There are exceptions though. You can mark the data as shared (the PE executable format support this). But, Delphi doesn't provide compiler directives for this. So we must do this ourselves with shared memory. > - you seem to be saying that this is not the case when > SetWindowsHookEx is used No, I'm not saying that. I'm saying that when it comes to the usage of SetWindowHookEx, the DLL is automagically mapped into all target processes. This is not the case for normal DLL's. There is absolutely no reason for normal DLL's to get mapped in every process. They only get mapped when an application uses them. > Obviously I am missing something, do you have any references that > explain what is really going on. > Well, I don't have any references close at hand. The above knowledge is gained by searching the MSDN and the web extensively. The main things that are important when using system wide hooks are: 1. The hook must be in a DLL (because of the mapping thing). 2. Because of 1, any variabele is local to the DLL, so you must use shared memory for variables (in my case WindowHandle^, but not WindowHandle) that are relevant to the application. btw: you are a master at confusing things, aren't you? Makes two of us though :-) -- www.zenobits.com
Re: Getting var from dll
Author: J French
Date: Sat, 10 May 2003 11:57
Date: Sat, 10 May 2003 11:57
21 lines
2615 bytes
2615 bytes
On Fri, 9 May 2003 22:20:54 +0200, "KLinZ" <klinz@NOSPAMMERTSzenobits.com> wrote: <snip> >btw: you are a master at confusing things, aren't you? Makes two of us >though :-) Thanks for taking the time to reply I am still very confused by what is going on, which is actually unusual. My hunch is that there is a bit more to this than meets the eye. When I get my ADSL working properly, I intend spending some time 'probing this one to the bottom' However, one thing I am pretty sure of, is that your 'to do' of making more than one instance simply involves making the Mapped File name something unique to the DLL When I do figure out what is really going on, I'll post my findings.
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads