Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. EnumWindows not finding hWnd from PID if program is started using QProcess

EnumWindows not finding hWnd from PID if program is started using QProcess

Scheduled Pinned Locked Moved Solved General and Desktop
qprocesswin32enumwindowshwnd
17 Posts 3 Posters 2.9k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • W Offline
    W Offline
    Waoweens
    wrote on 22 Apr 2022, 03:43 last edited by Waoweens
    #1

    I am trying to get a hWnd from a process id with Win32 APIs.

    HWND myHWND;
    static BOOL CALLBACK enumWindowCallback(HWND hWnd, LPARAM lparam) {
        DWORD pid;
        GetWindowThreadProcessId(hWnd, &pid);
    
        if (pid == lparam) {
            myHWND = hWnd;
            qDebug() << pid << myHWND;
            return FALSE;
        }
        return TRUE;
    }
    
    ProgramStarter::ProgramStarter(QObject *parent)
        : QObject{parent}
    {
        QProcess *qpr = new QProcess(this);
    
        QString executable = "C:\\Path\\to\\program.exe";
        qpr->start(executable);
        qpr->waitForStarted(-1);
    
        qDebug() << qpr->processId();
        EnumWindows(enumWindowCallback, qpr->processId());
    
        qpr->terminate();
    }
    

    But this does not seem to work. However, if I manually start the program and type in the PID instead of using QProcess then it works.

    // this works
    EnumWindows(enumWindowCallback, 12345);
    // this does not work
    EnumWindows(enumWindowCallback, qpr->processId());
    

    What am I doing wrong? How can I make it work?

    1 Reply Last reply
    0
    • W Offline
      W Offline
      Waoweens
      wrote on 22 Apr 2022, 07:23 last edited by
      #17

      Looks like using the QProcess::stateChanged signal (and removing terminate()) works.
      It uses QThread::msleep() so its not ideal, but its fine for me.

      HWND myHWND;
      static BOOL CALLBACK enumWindowCallback(HWND hWnd, LPARAM lparam) {
          DWORD pid;
          GetWindowThreadProcessId(hWnd, &pid);
      
          if (pid == lparam) {
              myHWND = hWnd;
              return FALSE;
          }
          return TRUE;
      }
      
      ProgramStarter::ProgramStarter(QObject *parent)
          : QObject{parent}
      {
          QProcess *qpr = new QProcess(this);
      
          connect(qpr, &QProcess::stateChanged, this, [=](QProcess::ProcessState newState){
              if (newState == QProcess::Running) {
                  QThread::msleep(250);
                  EnumWindows(enumWindowCallback, qpr->processId());
              }
          });
      
          QString executable = "C:\\path\\to\\program.exe";
          qpr->start(executable);
      
          qDebug() << myHWND;
      }
      
      1 Reply Last reply
      0
      • H Online
        H Online
        hskoglund
        wrote on 22 Apr 2022, 05:11 last edited by
        #2

        Hi, qpr->processId() and qpr->programId() are not the same, try changing programId to processId.

        W 1 Reply Last reply 22 Apr 2022, 05:26
        0
        • W Offline
          W Offline
          Waoweens
          wrote on 22 Apr 2022, 05:16 last edited by Waoweens
          #3
          This post is deleted!
          1 Reply Last reply
          0
          • H hskoglund
            22 Apr 2022, 05:11

            Hi, qpr->processId() and qpr->programId() are not the same, try changing programId to processId.

            W Offline
            W Offline
            Waoweens
            wrote on 22 Apr 2022, 05:26 last edited by
            #4

            @hskoglund Sorry, that was a typo (I did not copy paste everything). But this typo does not exist on my actual program. I will edit my post

            1 Reply Last reply
            0
            • C Offline
              C Offline
              Christian Ehrlicher
              Lifetime Qt Champion
              wrote on 22 Apr 2022, 05:46 last edited by
              #5

              @Waoweens said in EnumWindows not finding hWnd from PID if program is started using QProcess:

              // this works
              EnumWindows(enumWindowCallback, 12345);
              // this does not work
              EnumWindows(enumWindowCallback, qpr->processId());

              Then check what qpr->processId() returns, also take a look in the TaskManager to see if you can find qpr->processId() there.

              Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
              Visit the Qt Academy at https://academy.qt.io/catalog

              W 1 Reply Last reply 22 Apr 2022, 05:59
              0
              • C Christian Ehrlicher
                22 Apr 2022, 05:46

                @Waoweens said in EnumWindows not finding hWnd from PID if program is started using QProcess:

                // this works
                EnumWindows(enumWindowCallback, 12345);
                // this does not work
                EnumWindows(enumWindowCallback, qpr->processId());

                Then check what qpr->processId() returns, also take a look in the TaskManager to see if you can find qpr->processId() there.

                W Offline
                W Offline
                Waoweens
                wrote on 22 Apr 2022, 05:59 last edited by
                #6

                @Christian-Ehrlicher qpr->processId() returns 16228 and task manager also says 16228

                qDebug() << qpr->processId()
                

                12e67743-24f4-4c12-bb15-f101b1e2e3b9-image.png

                1 Reply Last reply
                0
                • C Offline
                  C Offline
                  Christian Ehrlicher
                  Lifetime Qt Champion
                  wrote on 22 Apr 2022, 06:02 last edited by Christian Ehrlicher
                  #7

                  @Waoweens said in EnumWindows not finding hWnd from PID if program is started using QProcess:

                  GetWindowThreadProcessId

                  So this doesn't seem to return what you're expecting. Don't think Qt and the task manager lies...

                  See e.g. https://stackoverflow.com/questions/61246529/pid-returned-from-getwindowthreadprocessid-call-doesnt-match-the-pid-from-taskm

                  Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                  Visit the Qt Academy at https://academy.qt.io/catalog

                  W 1 Reply Last reply 22 Apr 2022, 06:19
                  0
                  • C Christian Ehrlicher
                    22 Apr 2022, 06:02

                    @Waoweens said in EnumWindows not finding hWnd from PID if program is started using QProcess:

                    GetWindowThreadProcessId

                    So this doesn't seem to return what you're expecting. Don't think Qt and the task manager lies...

                    See e.g. https://stackoverflow.com/questions/61246529/pid-returned-from-getwindowthreadprocessid-call-doesnt-match-the-pid-from-taskm

                    W Offline
                    W Offline
                    Waoweens
                    wrote on 22 Apr 2022, 06:19 last edited by
                    #8

                    @Christian-Ehrlicher I modified it to list every open window

                    static BOOL CALLBACK enumWindowCallback(HWND hWnd, LPARAM lparam) {
                        DWORD pid;
                        GetWindowThreadProcessId(hWnd, &pid);
                        qDebug() << hWnd << pid
                        return TRUE;
                    }
                    //...
                    EnumWindows(enumWindowCallback, 0);
                    

                    If the program is launched manually, it appears on the list.
                    If the program is started with QProcess, it does not appear on the list.

                    C 1 Reply Last reply 22 Apr 2022, 06:21
                    0
                    • W Waoweens
                      22 Apr 2022, 06:19

                      @Christian-Ehrlicher I modified it to list every open window

                      static BOOL CALLBACK enumWindowCallback(HWND hWnd, LPARAM lparam) {
                          DWORD pid;
                          GetWindowThreadProcessId(hWnd, &pid);
                          qDebug() << hWnd << pid
                          return TRUE;
                      }
                      //...
                      EnumWindows(enumWindowCallback, 0);
                      

                      If the program is launched manually, it appears on the list.
                      If the program is started with QProcess, it does not appear on the list.

                      C Offline
                      C Offline
                      Christian Ehrlicher
                      Lifetime Qt Champion
                      wrote on 22 Apr 2022, 06:21 last edited by
                      #9

                      @Waoweens said in EnumWindows not finding hWnd from PID if program is started using QProcess:

                      If the program is launched manually, it appears on the list.

                      How do you know the PID in this case? Also from the task manager?

                      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                      Visit the Qt Academy at https://academy.qt.io/catalog

                      W 1 Reply Last reply 22 Apr 2022, 06:32
                      0
                      • H Online
                        H Online
                        hskoglund
                        wrote on 22 Apr 2022, 06:25 last edited by
                        #10

                        Hi, it could be that QProcess launches your program not as a top-level window but as a child, and then EnumWindows() never sees it :-(
                        Perhaps QProcess startDetached() works better?

                        C 1 Reply Last reply 22 Apr 2022, 06:29
                        0
                        • H hskoglund
                          22 Apr 2022, 06:25

                          Hi, it could be that QProcess launches your program not as a top-level window but as a child, and then EnumWindows() never sees it :-(
                          Perhaps QProcess startDetached() works better?

                          C Offline
                          C Offline
                          Christian Ehrlicher
                          Lifetime Qt Champion
                          wrote on 22 Apr 2022, 06:29 last edited by
                          #11

                          @hskoglund said in EnumWindows not finding hWnd from PID if program is started using QProcess:

                          Hi, it could be that QProcess launches your program not as a top-level window but as a child

                          How should it work otherwise - the Qt process is starting the process and therefore it's the creator. startDetached might work but must not.

                          The msdn documentation also tells which windows are evaluated: "Retrieves the identifier of the thread that created the specified window and, optionally, the identifier of the process that created the window."

                          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                          Visit the Qt Academy at https://academy.qt.io/catalog

                          1 Reply Last reply
                          0
                          • C Christian Ehrlicher
                            22 Apr 2022, 06:21

                            @Waoweens said in EnumWindows not finding hWnd from PID if program is started using QProcess:

                            If the program is launched manually, it appears on the list.

                            How do you know the PID in this case? Also from the task manager?

                            W Offline
                            W Offline
                            Waoweens
                            wrote on 22 Apr 2022, 06:32 last edited by
                            #12

                            @Christian-Ehrlicher said in EnumWindows not finding hWnd from PID if program is started using QProcess:

                            @Waoweens said in EnumWindows not finding hWnd from PID if program is started using QProcess:

                            If the program is launched manually, it appears on the list.

                            How do you know the PID in this case? Also from the task manager?

                            Yes, task manager.

                            @hskoglund said in EnumWindows not finding hWnd from PID if program is started using QProcess:

                            Hi, it could be that QProcess launches your program not as a top-level window but as a child, and then EnumWindows() never sees it :-(
                            Perhaps QProcess startDetached() works better?

                            using startDetached() makes processId() return 0.

                            C 1 Reply Last reply 22 Apr 2022, 06:34
                            0
                            • W Waoweens
                              22 Apr 2022, 06:32

                              @Christian-Ehrlicher said in EnumWindows not finding hWnd from PID if program is started using QProcess:

                              @Waoweens said in EnumWindows not finding hWnd from PID if program is started using QProcess:

                              If the program is launched manually, it appears on the list.

                              How do you know the PID in this case? Also from the task manager?

                              Yes, task manager.

                              @hskoglund said in EnumWindows not finding hWnd from PID if program is started using QProcess:

                              Hi, it could be that QProcess launches your program not as a top-level window but as a child, and then EnumWindows() never sees it :-(
                              Perhaps QProcess startDetached() works better?

                              using startDetached() makes processId() return 0.

                              C Offline
                              C Offline
                              Christian Ehrlicher
                              Lifetime Qt Champion
                              wrote on 22 Apr 2022, 06:34 last edited by
                              #13

                              @Waoweens said in EnumWindows not finding hWnd from PID if program is started using QProcess:

                              using startDetached() makes processId() return 0.

                              As properly documented...

                              I don't understand the need at all for this.

                              Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                              Visit the Qt Academy at https://academy.qt.io/catalog

                              W 1 Reply Last reply 22 Apr 2022, 06:43
                              0
                              • C Christian Ehrlicher
                                22 Apr 2022, 06:34

                                @Waoweens said in EnumWindows not finding hWnd from PID if program is started using QProcess:

                                using startDetached() makes processId() return 0.

                                As properly documented...

                                I don't understand the need at all for this.

                                W Offline
                                W Offline
                                Waoweens
                                wrote on 22 Apr 2022, 06:43 last edited by
                                #14

                                @Christian-Ehrlicher said in EnumWindows not finding hWnd from PID if program is started using QProcess:

                                I don't understand the need at all for this.

                                I want to embed an external program in a QWidget, but to do that you need the hWid of the program.

                                QWindow *embed = QWindow::fromWinId(hWid);
                                QWidget *widget = QWidget::createWindowContainer(embed)
                                
                                1 Reply Last reply
                                0
                                • C Offline
                                  C Offline
                                  Christian Ehrlicher
                                  Lifetime Qt Champion
                                  wrote on 22 Apr 2022, 06:45 last edited by
                                  #15

                                  Then you've to find another WinAPI function or modify the external program to return the winId to the caller.

                                  Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                                  Visit the Qt Academy at https://academy.qt.io/catalog

                                  1 Reply Last reply
                                  0
                                  • W Offline
                                    W Offline
                                    Waoweens
                                    wrote on 22 Apr 2022, 06:53 last edited by
                                    #16

                                    Looks like adding a delay of 1 second makes it works, so maybe it was too fast?
                                    But now the external program closes after 1 second. I removed qpr->terminate but now the QMainWindow wont start unless the external program is closed first.
                                    Is there a way to make them both run at the same time?

                                    1 Reply Last reply
                                    0
                                    • W Offline
                                      W Offline
                                      Waoweens
                                      wrote on 22 Apr 2022, 07:23 last edited by
                                      #17

                                      Looks like using the QProcess::stateChanged signal (and removing terminate()) works.
                                      It uses QThread::msleep() so its not ideal, but its fine for me.

                                      HWND myHWND;
                                      static BOOL CALLBACK enumWindowCallback(HWND hWnd, LPARAM lparam) {
                                          DWORD pid;
                                          GetWindowThreadProcessId(hWnd, &pid);
                                      
                                          if (pid == lparam) {
                                              myHWND = hWnd;
                                              return FALSE;
                                          }
                                          return TRUE;
                                      }
                                      
                                      ProgramStarter::ProgramStarter(QObject *parent)
                                          : QObject{parent}
                                      {
                                          QProcess *qpr = new QProcess(this);
                                      
                                          connect(qpr, &QProcess::stateChanged, this, [=](QProcess::ProcessState newState){
                                              if (newState == QProcess::Running) {
                                                  QThread::msleep(250);
                                                  EnumWindows(enumWindowCallback, qpr->processId());
                                              }
                                          });
                                      
                                          QString executable = "C:\\path\\to\\program.exe";
                                          qpr->start(executable);
                                      
                                          qDebug() << myHWND;
                                      }
                                      
                                      1 Reply Last reply
                                      0

                                      8/17

                                      22 Apr 2022, 06:19

                                      • Login

                                      • Login or register to search.
                                      8 out of 17
                                      • First post
                                        8/17
                                        Last post
                                      0
                                      • Categories
                                      • Recent
                                      • Tags
                                      • Popular
                                      • Users
                                      • Groups
                                      • Search
                                      • Get Qt Extensions
                                      • Unsolved