PhrAtoR
asked on
finding last focused application
Hi!
I have to write a program, that allows the user to insert stationaries (text) into every app (word, outlook,..)
What i do is copy the text to the clipboard and paste it in the app via WM_PASTE. The problem is, that the user has to click a button in program, so my program gets the focus.
How do i get the handle of the app/window the focus was before?
Thanks
Bastian (PhrAtoR)
I have to write a program, that allows the user to insert stationaries (text) into every app (word, outlook,..)
What i do is copy the text to the clipboard and paste it in the app via WM_PASTE. The problem is, that the user has to click a button in program, so my program gets the focus.
How do i get the handle of the app/window the focus was before?
Thanks
Bastian (PhrAtoR)
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Hi!
what robpitt says is right. WM_ACTIVATE only works in the current process.
The sample in the zip works fine.
I ported the focusmonitor (focus.dll) from focuslog.zip to Delphi. Now i have the same problem as with WM_ACTIVATE. I'm not a expert in windowshook-programming. So maybe you can help me again. There are Thread or system hooks. But how do i set what type is uses. At the moment it seems that my ported dll only installs a hook for the current
thread.
( has it something to do with the line "#pragma data_seg (".shared")" ? )
Maybe this is a delphi specific question, so if you can't help me this time, i'll give you the points anyway.
what robpitt says is right. WM_ACTIVATE only works in the current process.
The sample in the zip works fine.
I ported the focusmonitor (focus.dll) from focuslog.zip to Delphi. Now i have the same problem as with WM_ACTIVATE. I'm not a expert in windowshook-programming. So maybe you can help me again. There are Thread or system hooks. But how do i set what type is uses. At the moment it seems that my ported dll only installs a hook for the current
thread.
( has it something to do with the line "#pragma data_seg (".shared")" ? )
Maybe this is a delphi specific question, so if you can't help me this time, i'll give you the points anyway.
Your dll sould be loaded in each process. Can you show your code where you set hook?
ASKER
I can't load it in every process, because i'm also going to monitor windows of other applications (ms word, excel,...).
here is the code:
library focus;
uses
SysUtils,
Classes,
windows,
messages;
{$R *.RES}
var FocusedWindow,
NotifyWindow :hwnd;
NotifyMessage :uint;
mhook:HHOOK;
dllinst:LongWord;
function HookProc(code: Integer; wparam: WPARAM; lparam: LPARAM): LRESULT stdcall;
begin
if code = HCBT_SETFOCUS then begin
FocusedWindow:= hwnd(wparam);
if NotifyWindow <> 0 then SendMessage(NotifyWindow,N otifyMessa ge,wparam, lparam);
end;
result:= CallNextHookEx(mhook,code, wparam,lpa ram);
end;
function startFocusMonitor(notifyw: hwnd; notifym:uint) : Integer; stdcall;
begin
if mhook <> 0 then UnhookWindowsHookEx(mhook) ;
mhook:=SetWindowsHookEx(WH _CBT, HookProc, dllinst, 0);
NotifyWindow:=notifyw;
NotifyMessage:=notifym;
result:=1;
end;
function stopFocusMonitor: Integer; stdcall;
begin
if mhook <> 0 then UnhookWindowsHookEx(mhook) ;
NotifyWindow:=0;
NotifyMessage:=0;
result:=1;
end;
function getCurrentFocus: hwnd; stdcall;
begin
result:=FocusedWindow;
end;
exports
startFocusMonitor index 10 name 'startMonitor',
stopFocusMonitor index 11 name 'stopMonitor',
getCurrentFocus index 12 name 'getCFocus';
// main
begin
dllinst:=HInstance;
end.
here is the code:
library focus;
uses
SysUtils,
Classes,
windows,
messages;
{$R *.RES}
var FocusedWindow,
NotifyWindow :hwnd;
NotifyMessage :uint;
mhook:HHOOK;
dllinst:LongWord;
function HookProc(code: Integer; wparam: WPARAM; lparam: LPARAM): LRESULT stdcall;
begin
if code = HCBT_SETFOCUS then begin
FocusedWindow:= hwnd(wparam);
if NotifyWindow <> 0 then SendMessage(NotifyWindow,N
end;
result:= CallNextHookEx(mhook,code,
end;
function startFocusMonitor(notifyw:
begin
if mhook <> 0 then UnhookWindowsHookEx(mhook)
mhook:=SetWindowsHookEx(WH
NotifyWindow:=notifyw;
NotifyMessage:=notifym;
result:=1;
end;
function stopFocusMonitor: Integer; stdcall;
begin
if mhook <> 0 then UnhookWindowsHookEx(mhook)
NotifyWindow:=0;
NotifyMessage:=0;
result:=1;
end;
function getCurrentFocus: hwnd; stdcall;
begin
result:=FocusedWindow;
end;
exports
startFocusMonitor index 10 name 'startMonitor',
stopFocusMonitor index 11 name 'stopMonitor',
getCurrentFocus index 12 name 'getCFocus';
// main
begin
dllinst:=HInstance;
end.
mhook:=SetWindowsHookEx(WH _CBT, HookProc, dllinst, 0);
sould be
mhook:=SetWindowsHookEx(WH _CALLWNDPR OC, HookProc, dllinst, 0);
sould be
mhook:=SetWindowsHookEx(WH
The default for a DLL is for all global variables to be allocated on a per process basis. That is each process that loads a DLL gets its own versions of the global variables.
However we actually want some variables (hHook etc) to be common/shared between all DLL instances. In MSVC this is easily achieved using a shared data_seg.
I don't know whether there is an equivalent construct in Delphi.
If not you can do it all manually, see http://msdn.microsoft.com/library/en-us/dllproc/hh/winbase/dll_9khl.asp
However we actually want some variables (hHook etc) to be common/shared between all DLL instances. In MSVC this is easily achieved using a shared data_seg.
I don't know whether there is an equivalent construct in Delphi.
If not you can do it all manually, see http://msdn.microsoft.com/library/en-us/dllproc/hh/winbase/dll_9khl.asp
I think the only way you will get the info on the old focus window is with a CBT hook which monitors focus changes. If interested heres a sample of mine http://website.lineone.net/~codebox/focuslog.zip
this could easily be adapted to maintain a focus history.
Rob