• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1839
  • Last Modified:

Get the path and filename of the foreground window application

Hi,

I am trying to get the path and filename of the current foreground window application.  I am trying to use the following code, but it doesn't work properly.  It only gives me the path/filename of my delphi application.

Also, please, an explanation of why this function doesn't work.

function TForm1.GetActiveWinFilename():string;
var
  WHndPath : array [0..MAX_PATH] of char;
  CurrentHWnd : HWND;
begin
  CurrentHWnd := GetForegroundWindow;
  GetModuleFileName(CurrentHWnd, WHndPath, MAX_PATH);

  Result := StrPas(WHndPath);
end;



Any help would be appreciated.

DD

0
devilduck
Asked:
devilduck
1 Solution
 
LMuadDIbCommented:
from MSDN when you use GetForegroundWindow the returned HWnd can be Nil
and when you use GetModuleFileName, CurrentHWnd is probably nil and is sending your application which executed the function as the CurrentHWnd

MSDN links:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/windows/windowreference/windowfunctions/getforegroundwindow.asp
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/getmodulefilename.asp

so I would check the CurrentHWnd handle after GetForegroundWindow to make sure its not Nil

function TForm1.GetActiveWinFilename():string;
var
  WHndPath : array [0..MAX_PATH] of char;
  CurrentHWnd : HWND;
begin
  Result := '';
  CurrentHWnd := GetForegroundWindow;
  if CurrentHWnd <> nil then begin
    GetModuleFileName(CurrentHWnd, WHndPath, MAX_PATH);
    Result := StrPas(WHndPath);
  end;
end;
0
 
devilduckAuthor Commented:
Thanks for your reply.

Hmmm...  Nope, not the issue.

Putting CurrentHWnd into a TEdit shows that it isn't nil and I am still getting only the path/filename of my own app.

MSDN says, "The return value is a handle to the foreground window. The foreground window can be NULL in certain circumstances, such as when a window is losing activation."

It returns my app path/filename when I am just sitting on an app, not changing (losing) activation.  

Thanks anyway.

DD
0
 
henrythackerCommented:
This may be a silly question, but I take it when this procedure is called to retreive the window handle, you don't have your application active at the front of the screen? I.E. This procedure is called by something like a Timer instead of you clicking a button?
0
 
Russell LibbySoftware Engineer, Advisory Commented:
DD,

Two things.

1 - You can't use a window handle in a call to GetModuleFIleName. This API requires an HMODULE handle which is something different.
2 - You can't use GetModuleFIleName or similar calls to get another process's filename. You need to resort to using PSAPI calls (for NT systems), or the old toolhelp functions in Win9x systems.

Assuming your dealing with an NT kernel based system, the following will work for you.

Regards,
Russell


// Include psapi in the uses clause
uses
   ..., psapi;

function GetForegroundApp: String;
var  hwndFG:        HWND;
     hProc:         THandle;
     hMod:          Array [0..0] of HMODULE;
     dwPID:         DWORD;
     dwSize:        DWORD;
     dwCount:       DWORD;
begin

  // Set default result
  SetLength(result, 0);

  // Get the foreground window
  hwndFG:=GetForegroundWindow;

  // Check handle
  if (hwndFG <> 0) then
  begin
     // Get process id for the window handle
     if (GetWindowThreadProcessID(hwndFG, @dwPID) <> 0) then
     begin
        // Convert process id to a process handle
        hProc:=OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, True, dwPID);
        // Check handle
        if (hProc <> 0) then
        begin
           // Resource protection
           try
              // Set count
              dwCount:=0;
              // Get the first module, which is the exe
              if EnumProcessModules(hProc, @hMod, SizeOf(HMODULE), dwCount) then
              begin
                 // Allocate memory for file name
                 SetLength(result, Succ(MAX_PATH));
                 // Attempt to get the module file name
                 dwSize:=GetModuleFileNameEx(hProc, hMod[0], Pointer(result), MAX_PATH);
                 // Reset string length
                 SetLength(result, dwSize);
              end;
           finally
              // Close handle
              CloseHandle(hProc);
           end;
        end;
     end;
  end;

end;
0
 
devilduckAuthor Commented:
Hi rllibby,

It works perfectly!

Thank you *very* much.

DevilDuck
0

Featured Post

Vote for the Most Valuable Expert

It’s time to recognize experts that go above and beyond with helpful solutions and engagement on site. Choose from the top experts in the Hall of Fame or on the right rail of your favorite topic page. Look for the blue “Nominate” button on their profile to vote.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now