c# - Find window with specific text for a Process -
i'm trying find if window specific has been open process. process spawns multiple windows, , need check them all.
i have no trouble finding process, with
foreach (process p in process.getprocesses()) { if (p.mainmodule.filename.tolower().endswith("foo.exe")) findchildwindowwithtext(p); //do work
the problem next. cannot use process' mainwindowtext
, because changes whichever window activated.
then i've tried use windows function enumchildwindows
, getwindowtext
, not sure if i'm passing correct handle enumchildwindows. enumchildwindows
works expected when passed mainwindowhandle, of course mainwindowhandle changes active window. passed process.handle
, different handles , different results when switching app's windows. (i understand enumchildwindows returns handles not windows, controls in .net speak, that's no problem if caption of window too)
maybe doing wrong way , need different approach - again, problem simple finding window text matches specific regular expression. need function enumerates windows, visible in taskbar or so.
thanks
once have process, can enumerate windows in process , test if of them match window looking for.
you need following p/invoke declarations
[dllimport("user32", setlasterror=true)] [return: marshalas(unmanagedtype.bool)] private extern static bool enumthreadwindows(int threadid, enumwindowsproc callback, intptr lparam); [dllimport("user32", setlasterror = true)] [return: marshalas(unmanagedtype.bool)] static extern bool enumchildwindows(intptr hwndparent, enumwindowsproc lpenumfunc, intptr lparam); [dllimport("user32", setlasterror = true, charset = charset.auto)] private extern static int getwindowtext(intptr hwnd, stringbuilder text, int maxcount);
the followng example of pair of functions can used find windows in specific process, understood question have process, problem enumerating windows.
public static intptr findwindowinprocess(process process, func<string, bool> comparetitle) { intptr windowhandle = intptr.zero; foreach (processthread t in process.threads) { windowhandle = findwindowinthread(t.id, comparetitle); if (windowhandle != intptr.zero) { break; } } return windowhandle; } private static intptr findwindowinthread(int threadid, func<string, bool> comparetitle) { intptr windowhandle = intptr.zero; enumthreadwindows(threadid, (hwnd, lparam) => { stringbuilder text = new stringbuilder(200); getwindowtext(hwnd, text, 200); if (comparetitle(text.tostring())) { windowhandle = hwnd; return false; } return true; }, intptr.zero); return windowhandle; }
then can call findwindowinprocess function find window that's title ends "abc" example.
intptr hwnd = findwindowinprocess(p, s => s.endswith("abc")); if (hwnd != intptr.zero) { // window found.... }
of course can replace s => s.endswith("abc") expression satisfy search criteria window, regex etc.
here version of findthreadwindow check first level of child windows. take further , make recursive function if windows deeper down in hierarchy.
private static intptr findwindowinthread(int threadid, func<string, bool> comparetitle) { intptr windowhandle = intptr.zero; enumthreadwindows(threadid, (hwnd, lparam) => { stringbuilder text = new stringbuilder(200); getwindowtext(hwnd, text, 200); if (comparetitle(text.tostring())) { windowhandle = hwnd; return false; } else { windowhandle = findchildwindow(hwnd, comparetitle); if (windowhandle != intptr.zero) { return false; } } return true; }, intptr.zero); return windowhandle; } private static intptr findchildwindow(intptr hwnd, func<string, bool> comparetitle) { intptr windowhandle = intptr.zero; enumchildwindows(hwnd, (hchildwnd, lparam) => { stringbuilder text = new stringbuilder(200); getwindowtext(hchildwnd, text, 200); if (comparetitle(text.tostring())) { windowhandle = hchildwnd; return false; } return true; }, intptr.zero); return windowhandle; }
Comments
Post a Comment