4

At the moment, I can get a list of running processes with a main window using System.Diagnostics.Process.GetProcesses() and executing a simple LINQ query.

Then, I can import user32.dll and the SetWindowPos function and I manipulate other processes' window parameters.

Ok, it works. Now I'd like to select a window of a process, let's say calc.exe, by clicking it. In other words, I'd like to obtain a Process object (and then the MainWindowHandle) with a hook that catches the process name when I click on its window.

How can I achieve this?

2 Answers 2

5

I don't know how this is done in C#, but you have also tagged this question WinAPI so I can help there. In WinAPI, it can be done like so:

#include <stdio.h>
#include <Windows.h>
#include <Psapi.h>
#pragma comment(lib, "Psapi.lib")

int main(void)
{
  /* Hacky loop for proof of concept */
  while(TRUE) {
    Sleep(100);

    if(GetAsyncKeyState(VK_F12)) {
      break;
    }

    if(GetAsyncKeyState(VK_LBUTTON)) {
      HWND  hwndPt;
      POINT pt;

      if(!GetCursorPos(&pt)) {
        wprintf(L"GetCursorPos failed with %d\n", GetLastError());
        break;
      }

      if((hwndPt = WindowFromPoint(pt)) != NULL) {
        DWORD  dwPID;
        HANDLE hProcess;

        GetWindowThreadProcessId(hwndPt, &dwPID);

        hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, dwPID);

        if(hProcess == NULL) {
          wprintf(L"OpenProcess failed with error: %d\n", GetLastError());
        } else {
          wchar_t lpFileName[MAX_PATH];
          DWORD   dwSize = _countof(lpFileName);

          QueryFullProcessImageName(hProcess, 0, lpFileName, &dwSize);
          wprintf(L"%s\n", lpFileName);

          CloseHandle(hProcess);
        }
      }
    }
  }

  return EXIT_SUCCESS;
}

Example result:

result

In this case, I am simply polling to get the mouse click. A more proper way would be to use some sort of windows hook.

Sign up to request clarification or add additional context in comments.

11 Comments

You probably need to capture the mouse to be able to receive the click on another window.
@MartinLiversage: GetAsyncKeyState can be used for that.
I'm having some problems getting the cursor position. I'm calling GetCursorPos but I get the X coordinate as something like 6,47208716579385E-312 and the Y coordinate as 0. What's going on?
@MikeKwan: But if I move the mouse pointer to another window and click on it my application looses focus and doesn't get the mouse click event. That is, unless I have captured the mouse.
@MartinLiversage: You don't need to capture the mouse for GetAsyncKeyState as far as I'm aware.
|
1

As Mike Kwan said, you'll be better of writing a hook though both approaches have their own drawbacks, but bjarneds already did a good work on this. Have a look @ DotNET Object Spy. It's written in C# and will serve for your needs and more.

You should also note that using hooks are becoming redundant by the day. Depending on what you want to do, other winapis like GetForegroundWindow might serve better.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.