Solved

Detecting change on another app

Posted on 2000-02-28
12
258 Views
Last Modified: 2010-04-04
Hi,
How can I detect a an edit box change on another app? e.g. If calc was running and somebody put a value in, I would like my app to detect and act on it. Please help
Thanks
0
Comment
Question by:smurff
  • 7
  • 4
12 Comments
 
LVL 17

Expert Comment

by:inthe
Comment Utility
i think the only way would be a keyboard hook ..but this would be in effect for all others apps unless you know the handle of the program with the edit and if it running then use loadlibrary etc...
0
 
LVL 7

Accepted Solution

by:
ahalya earned 50 total points
Comment Utility
Here is a sample code that updates an EditBox & Memo as Keys are pressed in Calc.

You need to create TWO projects; one a DLL for hooking the keyboard & the other the EXE that calls the DLL.

Run the EXE, start Calc and try it :-)

================== Code For DLL ===========
Create a new project.  Delete all units and copy the following code to the DPR & save it as KBHook.dpr
---------------------------------

library KBHook;

uses Windows, Messages;

const
YourFormClass  = 'TKeyHookForm';
YourFormTitle  = 'Calc Key trap';

var
   KeyState : TKeyboardState;
   CharCode : LPARAM;

function KeyHookProc(nCode: integer; wp: WPARAM; lp: LPARAM): LRESULT; stdcall;

begin
Result := CallNextHookEx(0, nCode, wp, lp);
if not (nCode < 0) then
   begin
   if (lp and (1 shl 31)) = 0 then
     begin
     CharCode := 0;              
     GetKeyboardState(KeyState);
     if ToASCII(wp, HiWord(lp), KeyState, @CharCode, 0) = 1 then
        PostMessage( FindWindow(YourFormClass, YourFormTitle),
                     WM_User + 1, 0, CharCode);

     end;
   end;
Result := CallNextHookEx(0, nCode, wp, lp);
end;

exports KeyHookProc;
end.

==================Code for EXE ============
Drop a TEdit and a TMemo in your form.  Define the FormCreate & FormDestroy events:  Put the DLL & EXE in the same directory:

Set your Form's Name to "KeyHookForm" (*IMPORTANT* DLL uses this name to get back to you)
finally:
-Replace your unit's source with the following-
-----------------------------------------------

unit junk1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,  StdCtrls;

type
  TKeyHookForm = class(TForm)
    Edit1: TEdit;
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
  { Private declarations }
    LibHandle,
    HHookProc : THandle;
    HookProc  : function(nCode: integer; wp: WPARAM; lp: LPARAM): LRESULT; stdcall;

    function  InstallHook:boolean;

    procedure WMUser_KeyPressedGlobal(var Message : TMessage); message WM_User + 1;
  public
  { Public declarations }
  end;

var
  KeyHookForm: TKeyHookForm;

implementation

{$R *.DFM}

function TKeyHookForm.InstallHook:boolean;

var ok : boolean;

begin;
ok := false;
try
LibHandle := LoadLibrary('KBLib.dll');
if LibHandle <> 0 then
   begin
   @HookProc := GetProcAddress(LibHandle, 'KeyHookProc');
   if @HookProc <> nil then
      begin;
      HHookProc := SetWindowsHookEx(WH_KEYBOARD, HookProc, LibHandle, 0);
      ok := true;
      end
   else Application.MessageBox('Failed to get HookProc address', 'Error', mb_ok);
   end;
except on Exception do end;
InstallHook := ok;
end;


procedure TKeyHookForm.WMUser_KeyPressedGlobal(var Message : TMessage);

var
    ch : char;
    b  : boolean;
    p : array[0..255] of char;

begin
ch := Chr(LoByte(LoWord(Message.lParam)));
FillChar(p[0], 255, 0);
GetWindowText(GetForeGroundWindow,  p, 255);
b := (StrPos(StrLower(p), 'calculator') <> nil);
if b then
   begin;
     if ch > #31 then
        begin;
        Edit1.Text := Edit1.Text + ch;
        Memo1.SetSelTextBuf(pchar(Format('%s', [ch])));
        end
   else
     begin;
     Memo1.SetSelTextBuf(pchar(Format('[Char Code : %d]', [ord(ch)])));
     if ch = #13 then
        begin;
        Memo1.Lines.Add('');
        Edit1.Text := '';
        end;
     end;
   end;
end;


procedure TKeyHookForm.FormCreate(Sender: TObject);

begin
if not InstallHook then Application.Terminate;
end;


procedure TKeyHookForm.FormDestroy(Sender: TObject);

begin
if LibHandle <> 0 then
   begin
   if HHookProc <> 0 then UnhookWindowsHookEx(HHookProc);
   FreeLibrary(LibHandle);
   end;
end;

end.



0
 
LVL 7

Expert Comment

by:ahalya
Comment Utility
btw, as inthe noted this hook is active for all apps, and fills in your memo if Calculator is the forground window.

There are two ways to overcome this:
(1) Theoretically You can "install" the hook when Calc becomes the forgroundwindow, and then "Uninstall" it, when calc loses focus; but finding the focus change then becomes the issue (& would need another Hook i guess :-) -or a timer -

(2) Better alternative: You can find the ThreadID of the Calculator, and set the Hook with the ThreadID as the third parameter -instead of zero-); I have never done this. It shd work as per MS's docs..

As long as the Code in the DLL isn't very complex, having a system Hook shouldn't be an issue i'd think.



and btw, While we are at it, here is another proc that could be handy:
if you're interested in the contents of the edit box in the "Calc" then this code does it. (Drop in another TEdit. It'll correctly show the content in Calculator's Edit Box)


procedure TKeyHookForm.GetCalcText;

var h, c : HWND;
    p : array[0..100] of char;

begin;
h := FindWindow('SciCalc', 'Calculator');
c := GetDlgItem(h, 414);
SendMessage(c, WM_GetText, 100, longint(@p));
Edit2.Text := string(p);
end;


0
 
LVL 7

Expert Comment

by:ahalya
Comment Utility
..and btw, it appears that i have written too much for a 50-point question :-)
0
 
LVL 3

Author Comment

by:smurff
Comment Utility
ahalya,

Ive been working on this for far too long. Thank you for your reply, I can now get to work on this and sleep at night :)
0
 
LVL 3

Author Comment

by:smurff
Comment Utility
It didnt run, it just terminated... Ive copied exactly what you out. Where am I going wrong?
0
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 
LVL 7

Expert Comment

by:ahalya
Comment Utility
I have checked this on my computer and it works fine. (compiled in D2).

You have to make sure that you have the "correct" classname & title for your window. Look at the constants declared in the DLL.

DO NOT assign the 'YourFormTitle' to your form in designtime, rather assign it in runtime (in the FormCreate event, Caption := YourFormTitle;)  This is to make sure that the DLL finds the correct HWND.

Give me more details of the problem; put a breakpoint in the event handler for the message to see whether you get there.  [Also you can try "F7" and step through to find where it terminates]

0
 
LVL 7

Expert Comment

by:ahalya
Comment Utility
oops, there is one mistake in the code i copied for you.  The name of the DLL should be KBLib.dpr (and not KBHook.DPR).
0
 
LVL 3

Author Comment

by:smurff
Comment Utility
Yes found it, that was it. Thank you once again :)

This app will be the death of me!!
can every resourse on a form be monitored for change, e.g. listbox or colour of the form....?
0
 
LVL 7

Expert Comment

by:ahalya
Comment Utility
well, the answer is Yes, but obviously it'll get tricky, and you'll need to spend considerable effort to make them work.

if you have a specific problem, then post it.
0
 
LVL 3

Author Comment

by:smurff
Comment Utility
Ive been playing about with this for quite some time. Theres a network monitoring program on a server and when one of the 6 servers is down then the name turns to red. I was trying to code something that would email me or notify me over udp to tell me. Now because its not my program im having to build something that will monitor the form on the display, hence thats where my question came in.
I cant seem to get the code you helped me with to work in NT, I have looked at PSAPI.DLL but its not as straight forward as the win95 code you gave me. If you can point me in the right direction or give any help that would be great. maybe girls and Delphi dont mix well :)
0
 
LVL 7

Expert Comment

by:ahalya
Comment Utility
Well, AFAIK, my code should work on NT without any modifications.

PSAPI.DLL is needed ONLY if you want to use the ToolHelp32 functions. (and we didn't use any ToolHelp functions in the above.)

About detecting the info on the other program:
The only way i could think of is to track all the messages, the other program is getting and find out what message does it get when there is an error.  Then you can write a MessageHook (similar to our KeyboradHook), and you program will get the info whenever the error occurs.

It will be more earsier if the text in the other program changes when an error occurs. Then you can monitor the text to decide  whether there is an error.
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.
This tutorial demonstrates a quick way of adding group price to multiple Magento products.

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

6 Experts available now in Live!

Get 1:1 Help Now