Link to home
Start Free TrialLog in
Avatar of nrico
nrico

asked on

Hide my program?

How can I make programs OR disappear from any bar OR appear only in the system tray but still have them remain in memory?
I.e: How do I write a TSR in Delphi?

(I can increase the points if necessary)
Avatar of BoRiS
BoRiS

nrico

What you need to do to run the app in the system tray is download a component for www.torry.ru or the delphi super page for a tray icon or you can use this piece of code if you like....

public
    { Public declarations }
  procedure IconCallBackMessage( var Mess : TMessage ); message WM_USER
  + 100;//important add this
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
var
   Icd : TNotifyIconData;
begin
     ShowWindow(Application.handle, SW_HIDE);
     Self.Hide;
     with Icd do
     begin
           cbSize := SizeOf( TNotifyIconData );
           Wnd := Form1.Handle;
           uID := 1;
           uFlags := NIF_ICON or NIF_MESSAGE or NIF_TIP;
           uCallbackMessage := WM_USER + 100;
           hIcon := Application.Icon.Handle;
           szTip := 'Cool I got it right Wooooo Weeeee';
     end;
     Shell_NotifyIcon( NIM_ADD, @Icd );
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
   Icd : TNotifyIconData;
begin
     with Icd do
     begin
           cbSize := SizeOf( TNotifyIconData );
           Wnd := Form1.Handle;
           uID := 1;
           uFlags := NIF_ICON or NIF_MESSAGE or NIF_TIP;
           uCallbackMessage := WM_USER + 100;
           hIcon := Application.Icon.Handle;
           szTip := 'Cool I got it right Wooooo Weeeee';
// All the above is probably not needed.
     end;
     Shell_NotifyIcon( NIM_DELETE, @Icd );
end;

procedure TForm1.IconCallBackMessage( var Mess : TMessage );
var
   sEventLog : String;
begin
     case Mess.lParam of
// Do whatever you wish here. For example popup up a menu on a right click.
          WM_LBUTTONDBLCLK  : sEventLog := 'Left Double Click';
          WM_LBUTTONDOWN    : sEventLog := 'Left Down';
          WM_LBUTTONUP      : sEventLog := 'Left Up';
          WM_MBUTTONDBLCLK  : sEventLog := 'M Dbl';
          WM_MBUTTONDOWN    : sEventLog := 'M D';
          WM_MBUTTONUP      : sEventLog := 'M U';
          WM_MOUSEMOVE      : sEventLog :=  'movement';
          WM_MOUSEWHEEL     : sEventLog := 'Wheel';
          WM_RBUTTONDBLCLK  : sEventLog := 'r dbl';
          WM_RBUTTONDOWN    : sEventLog := 'r down';
          WM_RBUTTONUP      : sEventLog := 'r up';
     end;
end;

end.

to hide the program for the taskbar (startbar) use this
ShowWindow(Application.Handle, SW_HIDE);//to hide it
ShowWindow(Application.Handle,SW_SHOW);//to show it again

to hide the mainform on start up if you wish to do this is
Application.ShowMainForm := False;//on the on create event if you like...

to hide it for the Ctrl, Alt, Del you can do this....

create a function....
function RegisterServiceProcess(ThreadID: THandle; Flags: Integer):Integer; stdcall; external kernel32 name 'RegisterServiceProcess';

const
  RSP_SIMPLE_SERVICE = 1;
  RSP_UNREGISTER_SERVICE = 0;

//then call the function on the formcreate again if you wish

RegisterServiceProcess(0, RSP_SIMPLE_SERVICE);//to hide form task list

if you are not sure of what to do leave your e-mail address and I'll mail you an example for D3 or D4...

Later
BoRiS
Almost perfect answer...   :-)

Just one hint: If you use "Application.ShowMainForm:=false" like BoRiS suggested, the program will stop right after starting. If this problem happens to you, add such a message loop in the end of your project file (*.dpr), right after Application.Run:

  while true do begin
    if PeekMessage(Msg,0,0,0,PM_REMOVE) then begin
      TranslateMessage(Msg);
      DispatchMessage(Msg);
    end else WaitMessage;
  end;

And one short explanation about TSRs: In 32bit Windows each and every program is a kind of TSR, since you have real multitasking there. You can start 100 programs and run them at the same time. So a TSR (you're thinking of) is just a normal application that is not visible to the user. To make it unvisible use what BoRiS suggested.

Regards, Madshi.
Madshi is correct although this is not a common problem if you are using the systray (Tray Icon area),but what Madshi proposed if the program doesn't run after start up is correct.

I must agree with Madshi there on the TSR stuff on multitasking enviroments.

Later
BoRiS
Avatar of nrico

ASKER

Okay. Now how can I make it intercept keystrokes, even those that are not meant for the program?
Avatar of nrico

ASKER

I'm sorry, but I had to reject the answer. I'll give you the points if my other question is answered, too.
nrico
you will have to evaluate this question first.

Then post a seperate question about the key strokes, but you may let us know so long as to what you mean, keystrokes as in capturing what the person types or to disable the keys system wide.

You are not written a password catcher or something are you ;-)

Later
BoRiS  
Avatar of simonet
First, there are no such things as TSR under Windows, except for the device drivers.

TSR applications are triggered through interrupt calls. This is, their main loop terminates, but they stay resident until a defined interrupt is triggered. Win32 doesn't allow programming of interrupt calls on Ring 3 (user). Only on Ring 0 (and 1 too, I believe), which is device driver. Under Windows, and useing Delphi, the most similar program you have that is close to a TSR is a program that runs hidden, but its main loop is still going on. If a Delphi program has it's main loop terminated, the program itself terminates. That also goes for all services (win9x and NT) written on Delphi (3 or 4). The real TSR concept is lost in the "deep depths" (!) of DOS.

An example of what I said (a completely hidden application), is the program below. It runs totally hidden. What it does is: everytime the user opens a Windows Explorer window, the program finds that window and makes it "shake". This program is more of a joke I played on a friend of mine, but it illustrates the calls involved in hiding an application:

program Shaker;

uses
  Windows;

var
  tm1, tm2 : longint;
  hExp : HWND = 0;
  nn : integer = 1;
  SaveExit : pointer;
  msg : TMsg;

function RegisterAsService : boolean;
const
      RSP_SIMPLE_SERVICE = 1;
type
      TRegisterServiceProcess = function (dwProcessID, dwType : DWORD) : DWORD; stdcall;
var
      RSP : TRegisterServiceProcess;
  hMod : THandle;
begin
      Result := false;
      hMod := LoadLibrary('KERNEL32.DLL');
  if hMod=0 then  exit;
  @RSP := GetProcAddress(hMod, 'RegisterServiceProcess');
  if @RSP=nil then exit;
  try
        if RSP(0, RSP_SIMPLE_SERVICE)=1 then
              Result := true;
  finally
        FreeLibrary(hMod);
  end;
end;

procedure LibExit;
begin
      Killtimer(0, tm1);
  try
        KillTimer(0, tm2);
  except
  end;
  ExitProc := SaveExit;      { Restore exit procedure chain }
end;



procedure ShakeWindow(hWin : HWND;  uMsg, idEvent : longint ; dwTime : DWORD) stdcall;
var
  wp : PWindowPlacement;
begin
      if IsWindowVisible(hExp) then
  begin
        GetMem(wp, sizeof(TWindowPlacement));
     wp^.length := sizeof(TWindowPlacement);
        GetWindowPlacement(hExp, wp);
     with wp^.rcNormalPosition do
     begin
           if (Left + Right + Top + Bottom)=0 then
        begin
                 FreeMem(wp);
           hExp := 0;
           KillTimer(0, tm2);
           exit;
        end;
           Left := Left + (30 * nn);
           Right := Right + (30 * nn);
           nn := nn * -1;
           Top := Top + (15 * nn );
           Bottom := Bottom + (15 * nn );
     end;
     SetWindowPlacement(hExp, wp);
     FreeMem(wp);
  end
  else
  begin
        hExp := 0;
     KillTimer(0, tm2);
  end;
end;


procedure SearchWindow(hWin : HWND;  uMsg, idEvent : longint ; dwTime : DWORD) stdcall;
begin
      if hExp <> 0 then exit;
      hExp := FindWindow('ExploreWClass', nil);
      if hExp<>0 then
        tm2 := SetTimer(0, 5001, 30, @Shakewindow);
end;


begin
  If not RegisterAsService then
     MessageBox(0, 'Cannot register application as a service', 'Window Shaker', MB_OK);
  tm1 := SetTimer(0, 5000, 2000, @SearchWindow);

  SaveExit := ExitProc;      { Save exit procedure chain }
  ExitProc := @LibExit;      { Install LibExit exit procedure }

      while GetMessage(msg, 0, 0, 0 ) do
  begin
    TranslateMessage(msg );
    DispatchMessage(msg );
  end;
end.

The function you'll have to focus here is the RegisterAsService function, which hides the application. You can simply copy and paste it in your own application, although I don't know what happens if your application has a window. The application above has no Windows.

Let me know if I can be of further help.

Yours,

Alex
do you know a program called wintop ? it comes with kernel toys from microsoft..  even if you hide your program from task bar and ctrl+alt+del , or make ur program run as a service it will still be shown in wintop..  is there any way of completely hiding ? or hide services..
Not without very serious hacks deep into the system...   :-(
If you think in terms of security, no programs should be invisible to the kernel... only to users. Even though there are ways to totally hide it from wintop, I agree w/ Madshi here: some hack will be necessary, and, sincerely, I don't think one willing to do it have good intentions. Even if I had the code for that (which I don't).

Madshi:
I finally made the top 15, did you see that?! Cool!

Alex
Hi Alex, hey, congratulations!! It was about time! And I'm quite sure you'll be in the top10 in no time...   :-)

Regards, Madshi.
Avatar of nrico

ASKER

BoRiS, please answer my question again and I'll give you the points. You were the first to answer it.

(And no, I'm not writing a password catcher. I just want to make a TSR (oops ;-) that "pops up" when the user presses a key combination. So that's why I have to intercept keystrokes)
ASKER CERTIFIED SOLUTION
Avatar of BoRiS
BoRiS

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial