?
Solved

How do I determine the name or exe of the app that currently has focus?

Posted on 2005-03-03
4
Medium Priority
?
633 Views
Last Modified: 2013-12-03
Hi.

I want to code a function that will find out the name of the app that has focus.
For example, if the user is using Notepad or Minesweeper, and the function is called at that time (by a timer, for instance), it will display a message box that says "Notepad" or "Minesweeper". If instead of the name, it displays the exe ("notepad.exe" or "winmine.exe"), that's also acceptable.
I would like the implementation of that function, preferably in C# or VB.NET.

Thanks!
0
Comment
Question by:Daniel Cardozo
  • 2
  • 2
4 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 13451877
Dunno C# or VB, but you can do that using

char acName [ MAX_PATH];
HWND hWnd = GetForegroundWindow ();
GetWindowText ( hWnd, acName, MAX_PATH);

0
 

Author Comment

by:Daniel Cardozo
ID: 13452088
No good.
GetWindowText returns the caption of the window that has focus, not the name of the app.
Meaning, in Notepad for instance, it will get "Readme - Notepad" instead of "Notepad".
0
 
LVL 86

Accepted Solution

by:
jkr earned 750 total points
ID: 13452137
Oh, in this case, you can

#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include "psapi.h"

void PrintProcessName( DWORD processID )
{
    TCHAR szProcessName[MAX_PATH] = TEXT("<unknown>");

    // Get a handle to the process.

    HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
                                   PROCESS_VM_READ,
                                   FALSE, processID );

    // Get the process name.

    if (NULL != hProcess )
    {
        HMODULE hMod;
        DWORD cbNeeded;

        if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod),
             &cbNeeded) )
        {
            GetModuleBaseName( hProcess, hMod, szProcessName,
                               sizeof(szProcessName)/sizeof(TCHAR) );
        }
    }

    // Print the process name and identifier.

    _tprintf( TEXT("%s\n"), szProcessName);

    CloseHandle( hProcess );
}

DWORD dwPID;
HWND hWnd = GetForegroundWindow ();
GetWindowThreadProcessId ( hWnd, &dwPID);
PrintProcessName ( dwPID);
0
 

Author Comment

by:Daniel Cardozo
ID: 13458803
Cool!
Thanks.

For those who care, the translation to C# (with minor modifications, so it returns the name instead of printing it) goes like this:

using System;
using System.Runtime.InteropServices;

namespace Focus
{
    public class Focus
    {
        const int PROCESS_QUERY_INFORMATION = 0x0400;
        const int PROCESS_VM_READ = 0x0010;

        [StructLayout(LayoutKind.Sequential)] public struct StringBuffer
        {
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=256)] public string text;
        }

        [DllImport("kernel32.dll")] private static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
        [DllImport("kernel32.dll")] private static extern bool CloseHandle(IntPtr hObject);
        [DllImport("user32.dll")] private static extern IntPtr GetForegroundWindow();
        [DllImport("user32.dll")] public static extern int GetWindowThreadProcessId(IntPtr hWnd, out int lpdwProcessId);
        [DllImport("psapi.dll")] private static extern bool EnumProcessModules(IntPtr hProcess, out IntPtr lphModule, int cb, out int lpcbNeeded);
        [DllImport("psapi.dll")] private static extern int GetModuleBaseName(IntPtr hProcess, IntPtr hModule, out StringBuffer lpBaseName, int nSize);

        public string GetCurrentProcessName()
        {
            int dwPID;
            IntPtr hWnd = GetForegroundWindow();
            GetWindowThreadProcessId(hWnd, out dwPID);

            StringBuffer szProcessName;
            szProcessName.text = "<unknown>";

            // Get a handle to the process.

            IntPtr hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |
                PROCESS_VM_READ, false, dwPID);

            // Get the process name.

            if (hProcess != IntPtr.Zero)
            {
                IntPtr hMod = IntPtr.Zero;
                int cbNeeded;

                if (EnumProcessModules(hProcess, out hMod, Marshal.SizeOf(hMod), out cbNeeded))
                    GetModuleBaseName(hProcess, hMod, out szProcessName, Marshal.SizeOf(szProcessName));
            }

            CloseHandle(hProcess);
            return szProcessName.text;
        }
    }
}
0

Featured Post

Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

Question has a verified solution.

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

This article shows a few slightly more advanced techniques for Windows 7 gadget programming, including how to save and restore user settings for your gadget and how to populate the "details" panel that is displayed in the Windows 7 gadget gallery.  …
As more and more people are shifting to the latest .Net frameworks, the windows presentation framework is gaining importance by the day. Many people are now turning to WPF controls to provide a rich user experience. I have been using WPF controls fo…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
Is your organization moving toward a cloud and mobile-first environment? In this transition, your IT department will encounter many challenges, such as navigating how to: Deploy new applications and services to a growing team Accommodate employee…

594 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