Re: FindWindow is hanging....
From: Joseph M. Newcomer (newcomer_at_flounder.com)
Date: 06/11/04
- Next message: Joseph M. Newcomer: "Re: Pointer of Reference ?"
- Previous message: Joseph M. Newcomer: "Re: TrackPopupMenu leave open?"
- In reply to: Wes Jones: "FindWindow is hanging...."
- Next in thread: KS: "Re: FindWindow is hanging...."
- Reply: KS: "Re: FindWindow is hanging...."
- Messages sorted by: [ date ] [ thread ]
Date: Fri, 11 Jun 2004 17:27:55 -0400
Personally, I believe this is not only the worst possible way to find another window, but
it is so unreliable that it cannot be trusted. Not because the call is unreliable, but
because any string you have depends on the fact that you are looking for a specific window
in a specific version of the app, in a spectic language. So while the call works reliably,
the program that uses it would have to take all of these conditions into account, and
therefore the chances that it will work correctly in all conditions is minimal. For
example, it is possible to edit the resource segment of an app and merely change the
language strings (our European distributors do this all the time), so another app that
expects to find English language strings would be doomed. I've had to fix these problems
in many of my clients' programs, which is one reason I never do anything that has the
potential to be language-specific, and I never hardwire an English-language string
anywhere in my apps.
Since you are on CE, you could have additional problems that we don't see in desktop
systems.
But if you are writing both apps, there are a number of things you can do. For example, a
shared data segment in a DLL where the app that is the "service" puts its handle, and the
app that is the "client" can read the handle, would be a more reliably approach. Of
course, the "server" should, on its ExitInstance, set this handle to NULL, and the
"client" should occasionaly do an ::IsWindow, just to be sure everything is valid
If you are looking for some other app that you didn't write, you are probably in trouble.
If you use "Dialog", this gives you an 8-bit character string. This will not work on CE,
which uses Unicode. You could explicitly say L"Dialog", and it would only work in Unicode
versions, which would be fine for CE but if you wanted a desktop version, this might be an
annoyance. _T("Dialog") says "Make this an 8-bit or 16-bit literal depending on the
compilation mode", and is the preferred method.
Since I don't trust FindWindow as far as I can throw a mainframe, I can't answer the
question about whether or not there would be any difference in the nature of the calls.
And I've never written a CE program, so I'm not sure what other properties of CE differ
from desktop systems (CE is a totally separate code base, written from scratch, and shares
only the abstract API interface with the desktop systems. There are substantial
differences, some necessary, some merely gratuitous).
joe
On Fri, 11 Jun 2004 10:49:16 -0700, Wes Jones <nospam@spam.com> wrote:
>Hi all,
>
>I have an app that uses FindWindow to find the window handle to another
>app's window, and it looks like it is hanging. It doesn't do it every
>time, but from my logging statements, I can tell that FindWindow is the
>last thing called when it's hung up.
>
>I've seen the various articles/comments about the dangers of using
>FindWindow, ie: uses SendMessage internally & can hang if another app's
>thread is waiting/hung, etc.
>
>I have written an alternative function for some other purpose that works
>similarly to FindWindow but checking all the top level windows, starting
>w/ the desktop window, but that too uses GetWindowText (ie:
>SendMessage()) & I think will have the same liability.
>
>My question is: What's a good alternative to using FindWindow ?
>
>I would alter my similar function to use SendMessageTimeout, but I am
>using Windows CE, and that function is not supported.
>
>Please help, won't you?
>
>What are the alternatives to using FindWindow?
>
>Here are some details about how I'm using FindWindow:
>-------------
>LPCTSTR szPossibleNames[] = { _T("name1"), _T("name2"),...,_T("nameN") };
>for(int i=0; i < X; ++i){
> if( FindWindow(NULL, szPossibleNames[i]) )
> break;
>}
>//other stuff...
>-------------
>
>
>Is using FindWindow in a loop like this just asking for trouble? It's
>like I'm making it do risky things over & over again....
>
>
>Just for fun, and in the case it can help somebody point out an
>alternative to me, here's the code for my 'alternative func':
>
>-----------------------------------
>HWND FindChildAmongManyChildDialogs(
>HWND hWndMain,
>LPCTSTR szClassName,
>LPCTSTR szWindowTitle)
>//
>//This function was written to
>//find a child window when there is a main
>//window, and then several dialogs that
>//are children, and the window we want
>//is on one of those dialogs.
>//
>//This is based on the AirCard 555 watcher program,
>//and Remote Spy++
>//
>//
>//
>{
> CString str, strTitle;
> TCHAR szClass[ 200 + 1 ] = {0};
> CWnd * pChild = CWnd::FromHandle(::GetWindow(hWndMain, GW_CHILD)
>); CWnd * pLast = NULL;
> if( pChild )
> pLast = pChild->GetWindow(GW_HWNDLAST);
> if( !pChild )
> return NULL;
>
> do{
> GetClassName(pChild->GetSafeHwnd(), szClass, 200);
> pChild->GetWindowText(strTitle);
> if(_tcsicmp(szClass, _T("Dialog")) == 0 )
> {
> HWND hChild = FindChildWindow(pChild,
> szClassName,
> szWindowTitle);
> if( hChild )
> return hChild;
> }
> pChild = pChild->GetWindow(GW_HWNDNEXT);
> }while( pChild && (pChild != pLast) );
>
> return NULL;
>}
>
>HWND FindChildWindow(CWnd * pParent,
> LPCTSTR szClassName,
> LPCTSTR szWindowTitle)
>{
> ASSERT( szClassName || szWindowTitle );
> ASSERT( pParent );
> CString strTitle;
> TCHAR szClass[ 200 + 1] = {NULL};
>
> CWnd * pChild = pParent->GetWindow(GW_CHILD);
> ASSERT( pChild );
> CWnd * pLast = NULL;
> if( pChild )
> pLast = pChild->GetWindow(GW_HWNDLAST);
> if( !pChild )
> return NULL;
> do
> {
> GetClassName(pChild->GetSafeHwnd(), szClass, 200);
> pChild->GetWindowText(strTitle);
>
> if( (!szClassName || _tcsicmp(szClass, szClassName) == 0)
> && (!szWindowTitle || strTitle.CompareNoCase(szWindowTitle)
> == 0) )
> {
> return pChild->GetSafeHwnd();
> }
> pChild = pChild->GetWindow(GW_HWNDNEXT);
> }while( pChild && (pChild != pLast) );
>
> return NULL;
>}
>-----------------------------------
>
>
>Last question:
>Is using FindWindow(_T("dialog"), )
>better than using FindWindow("dialog", ) ?
>Does specifying the class name prevent it from using the sendmessage
>call internally for those cases where the window is obviously not a dialog?
>
>
>
>Thanks for any help...
>Wes
Joseph M. Newcomer [MVP]
email: newcomer@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
- Next message: Joseph M. Newcomer: "Re: Pointer of Reference ?"
- Previous message: Joseph M. Newcomer: "Re: TrackPopupMenu leave open?"
- In reply to: Wes Jones: "FindWindow is hanging...."
- Next in thread: KS: "Re: FindWindow is hanging...."
- Reply: KS: "Re: FindWindow is hanging...."
- Messages sorted by: [ date ] [ thread ]
Relevant Pages
|