Solved

hiding app from taskbar; forms` icons in alt+tab window

Posted on 2004-10-18
16
388 Views
Last Modified: 2010-04-05
I have an application that runs in background (it's minimized almost all the time). I need to hide it from taskbar:
with Application do SetWindowLong(handle, GWL_EXSTYLE, GetWindowLong(handle, GWL_EXSTYLE) or WS_EX_TOOLWINDOW and not WS_EX_APPWINDOW);

So what's the problem. As I said - application is minimized almost all the time and is not visible. But when I show some window from this application (ToolWindow, if it matters; there are several windows - ToolWindows and windows without caption, just with sizeable border), application (small box with appliction`s caption, 'restore', 'maximize' and 'exit' buttons) appears in the left down corner of display. How to avoid this appearing?

One more problem - when I press alt+tab, there are several icons for this application (one icon for each form; forms do not have caption, if it matters). When some ToolWindow (a form with BorderStyle set to bsToolWindow) is visible, there are no icons at all for this app. How to do so that there's one and only one icon for application, when I press alt+tab (no matter - is any of application`s windows visible or not, is application minimised or not)?

0
Comment
Question by:ZhaawZ
  • 6
  • 3
  • 2
  • +4
16 Comments
 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 12337083
Whenever I need to create applications that have to run in the background, I tend to divide them into two parts. First the background task that becomes a service application. (File/New/Other/Service Application) Put all the code in it that you need to run in the background and add some code for some communication protocol. A TCP/IP server component from Indy would be just fine, bt a simple named pipe could run perfectly too.
The second application would be the configuration tool. This could be a normal application but if you want to be real cool, make it a control applet. (File/New/Other/Control Panel Application) This second application will have to communicate with the service through the communication protocol that you've chosen and could be closed whenever you're done with it.

The advantage of this technique is that your application will keep on running and it will only show up in the task manager and nowhere else. Not even with Alt+Tab. But the second application could even be used to configure your main application from another computer, if you'd like that.

The disadvantage is that this technique is pretty complex at first and quite difficult to debug. The service itself will require Windows NT as a minimum and won't run on Windows 95/98 or ME. But hey, it's just a suggestion since it could be a useful and different approach.
0
 
LVL 11

Author Comment

by:ZhaawZ
ID: 12339347
I'm not able to create Service Application because there's no such 'file --> new --> other --> service application' (I'm using Delphi 6 Personal).
I also need to make an app that will run on both WinNT and Win9x systems.
0
 
LVL 12

Expert Comment

by:Ivanov_G
ID: 12344800
minimize it to system tray (if this is not a problem)
0
 
LVL 11

Author Comment

by:ZhaawZ
ID: 12345147
Yes, there's an icon for an app in try. I also minimize and restore application with this icon.
Restoring:    SendMessage(msg.WParam, WM_SYSCOMMAND, SC_RESTORE, 0);
Minimizing:    SendMessage(msg.WParam, WM_SYSCOMMAND, SC_MINIMIZE, 0);'

The first problem was:
When application is minimized and some window becomes visible (so an application is now minimized, some tool window - visible), there appears a small box with appliction`s caption and 'restore', 'maximize' and 'exit' buttons (I suppose this is minimized window of an application, not a form). I need to do so that this "box" does not appear.
0
 
LVL 12

Expert Comment

by:Ivanov_G
ID: 12347394
try with Application.Minimize instead of send message...
0
 
LVL 11

Author Comment

by:ZhaawZ
ID: 12350527
Doesn't work also with application.minimize.
This problem is now solved - I use ShowWindow(Application.Handle, SW_SHOW) before restoring and ShowWindow(Application.Handle, SW_HIDE) after minimizing.


There are two more problems.


First one (I already wrote about it) - icons in "alt+tab window":
* when application is in normal state (not minimized, without any visible toolwindow), there are one icon for each application`s visible form. For example - if there are 6 visible forms, there are also 6 icons in "alt+tab window".
* when application is not minimized, but there is some toolwindow visible (I use ShowModal to show these toolwindows), there are no icons in "alt+tab window" at all for this application.
* when application is minimized (whether any toolwindow is visible or not), there are no icons in "alt+tab window" at all for this application.
In all of these 3 cases there must be one and only one icon for this application in "alt+tab window".


Second problem (was not mentioned above) - minimizing/restoring/activating an application when clicking on icon in tray.
There's no problem to minimize/restore an application.

procedure TrayIconClick  (var msg : TMessage); message 9753;

procedure TMainForm.TrayIconClick(var msg : TMessage);
const
  tray_button_left_up       : word = 514;
var
  info : WINDOWPLACEMENT;
begin
if msg.LParam = tray_button_left_up then begin
  info.length := SizeOf(info);
  GetWindowPlacement(msg.WParam, @info);
  if (info.showCmd = SW_SHOWMINIMIZED) or (info.showCmd = SW_SHOWMINNOACTIVE) then begin
    ShowWindow(msg.WParam, SW_SHOW);
    SendMessage(msg.WParam, WM_SYSCOMMAND, SC_RESTORE, 0);
  end else begin
    SendMessage(msg.WParam, WM_SYSCOMMAND, SC_MINIMIZE, 0);
    ShowWindow(msg.WParam, SW_HIDE);    
  end;
end;
end;

9753 is a message that a form gets when user clicks or moves a mouse cursor over the icon in tray.
msg.LParam is "action" that user does with icon in tray (in this case there's only 514 - releasing left mouse button).
msg.WParam in this case is a handle to an application (can be also a handle to a form - it doesn't matter this time).

That procedure above only minimizes/restores application. I need to do so that if an application is not active when user clicks on icon in tray, it becomes active (not minimizes). It could be done by using GetForegroundWindow to check if application is active, but there's some problem - when I click on icon in tray, the form (application) is not active anymore. How can I check if it was active before clicking on icon in tray?

0
 
LVL 12

Expert Comment

by:Ivanov_G
ID: 12355336
About ALT + TAB ... It doesn't catch Dialog windows.

Why not using .BringToFront method, combined with SetForegroundWindow ?
0
Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

 
LVL 11

Author Comment

by:ZhaawZ
ID: 12355616
How can I checkt with BringToForm which was the last active window?
BringToFront works only within the application.

About "alt+tab window". It shows one icon (for application, not each form) if there's a visible button for application in taskbar, whether there is some tool window visible or not, whether an application is minimized or not. When I hide this button, it goes totally wrong with these icons.
Maybe there's some other way to hide it from taskbar than this?
with Application do SetWindowLong(handle, GWL_EXSTYLE, GetWindowLong(handle, GWL_EXSTYLE) or WS_EX_TOOLWINDOW and not WS_EX_APPWINDOW);
0
 

Expert Comment

by:krypto2000
ID: 12398277
I've a solution for the minimize event that can hide the application from the taskbar and the ALT+TAB menu

//------------------------------------------------------//
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure minimizeApp(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.minimizeApp(Sender: TObject);
begin
   self.Visible := false;
// make the tray icon visible and more...
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
   Application.OnMinimize := minimizeApp;
end;
//------------------------------------------------------//

but i think the best way for u is to make a windows NT services, and after you make a control panel applet for configuring your services parameters,
if you want some example just say...
0
 
LVL 11

Author Comment

by:ZhaawZ
ID: 12399364
krypto2000:
  As I already said - I need one icon for application in "alt+tab window". Read my comments if you didn't understand what excatly I need.
  I also said that I can't make windows nt service.
0
 

Expert Comment

by:krypto2000
ID: 12399527
okay sorry i'm not english i'm swiss so I make that I can to help some people but something I don't understand exactly...
0
 

Expert Comment

by:carlp42
ID: 12612248
I had exactly the same problem that you did for one of these problems and found a slightly more elegant solution I think.

The reason that whenever you make a form visible the application taskbar icon appears...
In the constructor for TCustomForm the function Screen.AddForm(Self) is called.  This updates Screen.Forms and Screen.CustomForms.
Whenever a form changes visibility the Application.UpdateVisible procedure is called.  This looks through Screen.Forms for any visible forms and sets the application window visible (hence the taskbar button visible) if any are found.

However if you make your forms descend from something other than TForm then you can avoid this.  I use a new class called TDesktopForm = class(TCustomForm) then change my class definitions to inherit from that instead of from TForm.  If you look at the definition of TForm it doesn't do much over and above what TCustomForm does anyway, mainly it just exposes a set of properties, which you can do in your TDesktopForm class too.

I have not used the TOOLWINDOW style myself - it seems to remove windows from the alt+tab list (amongst other things).

I think that if you try modifying the inheritance in the way I suggest then you won't need to use TOOLWINDOW and you'll get no taskbar buttons.  In my tests this system left one and only one icon in the alt+tab list, which is what you wanted I think?  The only other thing is that you'll probably want to disable the minimize button as it behaves strangely - users probably only want the close button from what I understand of your requirements.
0
 
LVL 2

Expert Comment

by:SaLz
ID: 12708242
if I want to hide my application I just use this simple code in the dpr source

Application.ShowMainForm:=false;

which looks like.
{$R *.res}

begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.ShowMainForm:=false;
  Application.Run;
end.

so my app doesn't show, and it will never show unless I call form1.show; which I wont call cos I don't want it to be shown
0
 
LVL 11

Author Comment

by:ZhaawZ
ID: 12957621
SaLz, this doesn't work for me. I need a form to be visible when user clicks on an icon in tray. I use ShowWindow() with SW_SHOW parameter to show a form. If I set ShowMainForm to false, then most of controls on form aren't painted, when a form gets visible (maybe they even aren't created, I don't know actually; do I have to paint/create them manually now?).

I solved this problem by calling ShowWindow with sw_hide parameter in onPaint event when form is painted first time (form`s flashing when application starts, but it`s ok for me this time).

btw, one more thing - sometimes form must be shown when application starts - it depend's on some operations which are done/aren`t done when form is created.



About the problem I mentioned @ 10/19/2004 09:46PM EEST ("minimizing/restoring/activating an application when clicking on icon in tray", actually it's hiding/restoring/showing a window) - I also solved this problem. The problem was that when user clicks on icon in tray, form loses a focus (if it has one), so there's no possibility to check if form is active or not (to know, what to do next - to activate form (if it wasn't active) or to hide it (if it was active)). Procedure 'proc' finds last active visible window and sets it as foreground window.

procedure TMainForm.TrayIconMessages;

  function proc(wnd : cardinal; param : integer) : boolean; stdcall;
  begin
  if IsWindowVisible(wnd) then begin
    if wnd = FindWindow('Shell_TrayWnd', nil) then begin
      proc := true;
    end else begin
      SetForegroundWindow(wnd);
      proc := false;
    end;
  end else proc := true;
  end;

begin                    
case msg.HitTestCode of
  514 : begin              
          if IsWindowVisible(handle) then begin
            EnumWindows(@proc, 0);
            if GetForegroundWindow = handle then begin
              ShowWindow(handle, sw_hide);
            end else begin
              SetForegroundWindow(handle);
            end;
          end else begin
            ShowWindow(handle, sw_show);
            SetForegroundWindow(handle);
          end;
        end;
end;
end;
0
 

Accepted Solution

by:
ee_ai_construct earned 0 total points
ID: 12997023
Question answered by asker or dialog deemed valuable.
Closed, 400 points refunded.
ee_ai_construct (replacement part #xm34)
Community Support Admin
0

Featured Post

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.

Join & Write a Comment

Suggested Solutions

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…
This video explains how to create simple products associated to Magento configurable product and offers fast way of their generation with Store Manager for Magento tool.

747 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

9 Experts available now in Live!

Get 1:1 Help Now