From 02daae6c3ca46723029e9f320b764fc1f100e423 Mon Sep 17 00:00:00 2001 From: Ximi1970 Date: Wed, 26 Feb 2020 22:44:06 +0100 Subject: [PATCH] Add find window by pid --- app/SysTray-X/windowctrl-win.cpp | 183 ++++++++++++++++++------------- app/SysTray-X/windowctrl-win.h | 56 +++++++--- app/SysTray-X/windowctrl.cpp | 3 + 3 files changed, 152 insertions(+), 90 deletions(-) diff --git a/app/SysTray-X/windowctrl-win.cpp b/app/SysTray-X/windowctrl-win.cpp index eab9a07..8d9c545 100644 --- a/app/SysTray-X/windowctrl-win.cpp +++ b/app/SysTray-X/windowctrl-win.cpp @@ -5,8 +5,14 @@ /* * System includes */ +#include #include +/* + * Qt includes + */ +#include + /* * Statics */ @@ -23,13 +29,44 @@ WindowCtrlWin::WindowCtrlWin( QObject *parent) : QObject( parent ) /* - * Find the window with title + * Get the parent pid of SysTray-X, TB hopefully + */ +qint64 WindowCtrlWin::getPpid() +{ + HANDLE h = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ); + PROCESSENTRY32 pe; + pe.dwSize = sizeof( PROCESSENTRY32 ); + + qint64 ppid = -1; + qint64 pid = QCoreApplication::applicationPid(); + + if( Process32First( h, &pe ) ) + { + do + { + if( pe.th32ProcessID == pid ) + { + ppid = pe.th32ParentProcessID; + break; + } + } + while( Process32Next( h, &pe ) ); + } + + CloseHandle( h ); + + return ppid; +} + + +/* + * Find the window by title */ bool WindowCtrlWin::findWindow( const QString& title ) { m_tb_windows = QList< quint64 >(); - EnumWindows( &EnumWindowsProc, (LPARAM)(LPSTR)( title.toStdString().c_str() ) ); + EnumWindows( &enumWindowsTitleProc, (LPARAM)(LPSTR)( title.toStdString().c_str() ) ); if( m_tb_windows.length() == 0 ) { @@ -40,6 +77,76 @@ bool WindowCtrlWin::findWindow( const QString& title ) } +/* + * Callback for the window enumaration title find. + */ +BOOL CALLBACK WindowCtrlWin::enumWindowsTitleProc( HWND hwnd, LPARAM lParam ) +{ + char buffer[ 128 ]; + int written = GetWindowTextA( hwnd, buffer, 128 ); + if( written && strstr( buffer, (char*)lParam ) != NULL ) + { + m_tb_windows.append( (quint64)hwnd ); + } + + return TRUE; +} + + +/* + * Find the window by pid + */ +bool WindowCtrlWin::findWindow( qint64 pid ) +{ + HandleData data; + data.pid = pid; + data.hwnd = 0; + EnumWindows( &enumWindowsPidProc, (LPARAM)&data ); + + if( data.hwnd == 0 ) + { + return false; + } + + /* + * Store it + */ + m_tb_windows.append( (quint64)data.hwnd ); + + return true; +} + + +/* + * Callback for the window enumaration pid find. + */ +BOOL CALLBACK WindowCtrlWin::enumWindowsPidProc( HWND hwnd, LPARAM lParam ) +{ + HandleData& data = *(HandleData*)lParam; + unsigned long pid = 0; + + GetWindowThreadProcessId( hwnd, &pid ); + + if( data.pid != pid || !isMainWindow( hwnd ) ) + { + return TRUE; + } + + data.hwnd = hwnd; + + return FALSE; +} + + +/* + * Check for main window + */ +BOOL WindowCtrlWin::isMainWindow( HWND hwnd ) +{ + return GetWindow( hwnd, GW_OWNER ) == (HWND)0 && IsWindowVisible( hwnd ); +} + + /* * Display the window elements */ @@ -54,22 +161,6 @@ void WindowCtrlWin::displayWindowElements( const QString& title ) } -/* - * Callback for the window enumaration - */ -BOOL CALLBACK WindowCtrlWin::EnumWindowsProc( HWND hwnd, LPARAM lParam ) -{ - char buffer[ 128 ]; - int written = GetWindowTextA( hwnd, buffer, 128 ); - if( written && strstr( buffer, (char*)lParam ) != NULL ) - { - m_tb_windows.append( (quint64)hwnd ); - } - - return TRUE; -} - - /* * Get the Thunderbird window ID */ @@ -138,60 +229,4 @@ void WindowCtrlWin::deleteWindow( quint64 window ) SendMessageA( (HWND)window, WM_CLOSE, 0, 0 ); } - - -/* -LRESULT CALLBACK WindowCtrlWin::mySubClassProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData ) -{ - MessageBoxA( NULL, "Test", "Test", MB_OK ); - - switch(uMsg) - { - case WM_LBUTTONDOWN: - MessageBoxA( NULL, "Button down!", "Debug", MB_OK ); - break; - - case WM_NCDESTROY: - RemoveWindowSubclass( hWnd, &mySubClassProc, 1 ); - break; - } - - return DefSubclassProc(hWnd, uMsg, wParam, lParam); -} -*/ - -/* - * Callback for the window enumaration - */ -LRESULT CALLBACK WindowCtrlWin::WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) -{ - MessageBoxA( NULL, "Test", "Test", MB_OK ); - - return TRUE; - - if( uMsg == WM_CLOSE ) - { - return TRUE; - } - -// return CallWindowProc( prev, hwnd, uMsg,wParam, lParam); - - return DefWindowProc( hwnd, uMsg, wParam, lParam ); -} - - -/* - * Close experiment - */ -void WindowCtrlWin::closeWindow( HWND hwnd ) -{ - emit signalConsole("Close Window intercept"); - -// SetWindowSubclass( hwnd, &mySubClassProc, 1, 0); - - MessageBoxA( NULL, "Start test", "Test", MB_OK ); - - WNDPROC prev = (WNDPROC)SetWindowLongPtr( hwnd, GWLP_WNDPROC, (LONG_PTR)&WindowCtrlWin::WindowProc ); -} - #endif // Q_OS_WIN diff --git a/app/SysTray-X/windowctrl-win.h b/app/SysTray-X/windowctrl-win.h index f2a60a2..2f31b4b 100644 --- a/app/SysTray-X/windowctrl-win.h +++ b/app/SysTray-X/windowctrl-win.h @@ -21,6 +21,14 @@ class WindowCtrlWin : public QObject { Q_OBJECT + private: + + struct HandleData + { + unsigned long pid; + HWND hwnd; + }; + public: /** @@ -30,20 +38,31 @@ class WindowCtrlWin : public QObject */ explicit WindowCtrlWin( QObject *parent = nullptr ); - - void closeWindow( HWND hwnd ); - - + /** + * @brief getPpid. Get the parent process id. + * + * @return The ppid + */ + qint64 getPpid(); /** - * @brief findWindow. Find window with title. + * @brief findWindow. Find window by title. * - * @param title The title to find. + * @param title The (part)title to find. * * @return State of the find. */ bool findWindow( const QString& title ); + /** + * @brief findWindow. Find window by pid. + * + * @param pid The pid to find. + * + * @return State of the find. + */ + bool findWindow( qint64 pid ); + /** * @brief displayWindowElements. Display window elements. * @@ -98,28 +117,33 @@ class WindowCtrlWin : public QObject void hideWindow( HWND hwnd ); /** - * @brief EnumWindowsProc. Callback for window enumaration. + * @brief EnumWindowsTitleProc. Callback for window enumaration by title. * * @param hwnd Handle of window. * @param lParam Argument passed by EnumWindows. * * @return State of callback. (TRUE = continue / FALSE = stop) */ - static BOOL CALLBACK EnumWindowsProc( HWND hwnd, LPARAM lParam ); + static BOOL CALLBACK enumWindowsTitleProc( HWND hwnd, LPARAM lParam ); /** - * @brief WindowProc + * @brief EnumWindowsPidProc. Callback for window enumaration by pid. * - * @param hwnd - * @param uMsg - * @param wParam - * @param lParam + * @param hwnd Handle of window. + * @param lParam Argument passed by EnumWindows. * - * @return + * @return State of callback. (TRUE = continue / FALSE = stop) */ - static LRESULT CALLBACK WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); + static BOOL CALLBACK enumWindowsPidProc( HWND hwnd, LPARAM lParam ); - static LRESULT CALLBACK mySubClassProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData ); + /** + * @brief isMainWindow. Check for main window. + * + * @param hwnd The window handle. + * + * @return Result of the check. + */ + static BOOL isMainWindow( HWND hwnd ); signals: diff --git a/app/SysTray-X/windowctrl.cpp b/app/SysTray-X/windowctrl.cpp index 767b29f..2e024c0 100644 --- a/app/SysTray-X/windowctrl.cpp +++ b/app/SysTray-X/windowctrl.cpp @@ -67,6 +67,9 @@ void WindowCtrl::slotWindowTest2() // Do something. + findWindow( m_ppid ); + emit signalConsole( QString( "Hwnd ppid: %1" ).arg( getWinIds()[0] ) ); + emit signalConsole("Test 2 done"); }