Solved

My program looses focus

Posted on 2002-06-03
7
470 Views
Last Modified: 2007-12-19
Hi Experts,

A question about one of my programs that's running on a Citrix server:

This program looses focus once it has started. Probably because Citrix starts some process just after my program has started. I can't find out what process, but a fact is that my program is not the active windows once it has started.
Because my program starts with a login window, the user must click on my program first before typing anything in the login window; rather annoying.

When I run my program locally or in the IDE there's no problem; once started my program is the active program. So, it's rather difficult to track and solve this problem.

What I like to know is: is there perhaps a way to force my program to become the active program. I could for instance progam a TTimer event, that runs some code 1 second after the program has been started. This code must force my program to become the active program.

Is there a way to achieve this?
Or is there perhaps another solution for this problem?

Thanks,
JDN
0
Comment
Question by:JDN
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
7 Comments
 
LVL 3

Expert Comment

by:tongalite
ID: 7054440
Hi JDN

This is a long shot...
Try this code in your on create....

-----------------------------------
SendMessage(Application.Handle,WM_ACTIVATE,WA_CLICKACTIVE,0);

//Maybe switch the Application.Handle with the mainforms handle, usually Form1.Handle
-----------------------------------
Good luck
T.
0
 
LVL 1

Expert Comment

by:czechmate
ID: 7054548
What about old      
 Application.BringToFront;

cj
0
 

Accepted Solution

by:
paulmoun earned 50 total points
ID: 7054826
You used to be able to use the Windows API call 'SetForegroundWindow' but they changed it's behaviour in Windows98/2000 to stop you grabbing focus.
Here is a workaround(The fuction is fired by a timer..see bottom of code, also you need to change the name 'form1' to the name of your form):


function ForceForegroundWindow(hwnd: THandle): boolean;
const
  SPI_GETFOREGROUNDLOCKTIMEOUT = $2000;
  SPI_SETFOREGROUNDLOCKTIMEOUT = $2001;
var
  ForegroundThreadID: DWORD;
  ThisThreadID      : DWORD;
  timeout           : DWORD;
begin
  if IsIconic(hwnd) then ShowWindow(hwnd, SW_RESTORE);

  if GetForegroundWindow = hwnd then Result := true
  else begin

    // Windows 98/2000 doesn't want to foreground a window when some other
    // window has keyboard focus

    if ((Win32Platform = VER_PLATFORM_WIN32_NT) and (Win32MajorVersion > 4))
or
      ((Win32Platform = VER_PLATFORM_WIN32_WINDOWS) and
      ((Win32MajorVersion > 4) or ((Win32MajorVersion = 4) and
(Win32MinorVersion > 0)))) then
    begin

      // Code from Karl E. Peterson, www.mvps.org/vb/sample.htm 
      // Converted to Delphi by Ray Lischner
      // Published in The Delphi Magazine 55, page 16

      Result := false;
      ForegroundThreadID :=
GetWindowThreadProcessID(GetForegroundWindow,nil);
      ThisThreadID := GetWindowThreadPRocessId(hwnd,nil);
      if AttachThreadInput(ThisThreadID, ForegroundThreadID, true) then
begin
        BringWindowToTop(hwnd); // IE 5.5 related hack
        SetForegroundWindow(hwnd);
        AttachThreadInput(ThisThreadID, ForegroundThreadID, false);
        Result := (GetForegroundWindow = hwnd);
      end;
      if not Result then begin

        // Code by Daniel P. Stasinski  

        SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, @timeout, 0);
        SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, TObject(0),
SPIF_SENDCHANGE);
        BringWindowToTop(hwnd); // IE 5.5 related hack
        SetForegroundWindow(hWnd);
        SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0,
TObject(timeout), SPIF_SENDCHANGE);
      end;
    end
    else begin
      BringWindowToTop(hwnd); // IE 5.5 related hack
      SetForegroundWindow(hwnd);
    end;

    Result := (GetForegroundWindow = hwnd);
  end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
 if GetForegroundWindow<>Form1.handle then
   ForceForegroundWindow(Form1.handle);
end;

end.
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Expert Comment

by:paulmoun
ID: 7054833
Oh and I forgot, remove the minimize button from the form, otherwise the user will think windows has siezed up.
0
 
LVL 1

Author Comment

by:JDN
ID: 7054865
Tongalite, Czechmate,

Both solutions you proposed don't work.

You can test it yourself:

Start a compiled Delphi application and, when this application is launched, click the Windows taskbar or desktop. Your application becomes inactive (the title bar of your application becomes gray).
Now this is in fact my problem. I like to execute some code to force my application (that is inactive now) become active. Once the user has logged on, this TTimer event can stop.
I've tried both your code (in a TTimer event) but my application stays inactive in Windows 2000.

Paulmon, I will try your solution tomorrow (it's sleeping time in the Netherlands now).

Thanks,
JDN
0
 
LVL 1

Author Comment

by:JDN
ID: 7057279
This works.
Thanks.
0
 

Expert Comment

by:eant
ID: 8968473
Hi, I have the same problem but I tried to use the code of Paulmon and it don't work..
How did you do?

thanks
luca
lcaruso@anacomp.it
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

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 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…

735 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