|
|
Comments and Discussions
|
|
 |

|
is there any c# version of this code?
|
|
|
|

|
Are you able to get the drop location address. Like if you try to drop in Desktop can you get the physical address of Desktop like C:\Users\XXX\Desktop ?
|
|
|
|

|
Are you able to get the drop location address. Like if you try to drop in Desktop can you get the physical address of Desktop like C:\Users\XXX\Desktop ?
|
|
|
|

|
Thank you show much,
You are my savior.
For your honor
|
|
|
|

|
I tried to use your code to retrieve the text from a RichEdit control. The following is the code I modified.
char sz[123];
GetWindowText(hwndFoundWindow, sz, 123);
// Display some information on the found window.
wsprintf
(
szText, "Window Handle == 0x%08X.\r\nClass Name : %s.\r\nRECT.left == %d.\r\nRECT.top == %d.\r\nRECT.right == %d.\r\nRECT.bottom == %d.\r\nCaption=%s",
hwndFoundWindow,
szClassName,
rect.left,
rect.top,
rect.right,
rect.bottom,
sz
);
Do you have any idea?
Thanks,
Junlin Xu
|
|
|
|

|
Ok, I figured it out. I need to SendMessage() with WM_GETTEXT since I was trying to retrieve text from a textbox in another process. GetWindowText() does not work in this case.
|
|
|
|

|
I am developing application on smartphone WM5,WM6,WM6.1. I have a problem, I don't know HOW TO GET ACTIVE CONTROL IN ACTIVE WINDOW IN OTHER PROCESS ?
I have tried some solutions:
SOLUTION 1: Subclassing:
Public Class clsSubclass
#Region "DllImport"
Public Const GWL_WNDPROC As Integer = (-4)
Public Const WM_RAFFAEL As Integer = 123456789
Public Const WM_CLOSE As Integer = &H10
Public Const WM_KEYDOWN = &H100
Public Delegate Function WndProcDelegate(ByVal hWnd As IntPtr, ByVal msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
_
Public Shared Function GetWindowLong(ByVal hWnd As IntPtr, ByVal nIndex As Integer) As IntPtr
End Function
_
Public Shared Function SetWindowLongEx(ByVal hWnd As IntPtr, ByVal nIndex As Integer, ByVal newWndProc As WndProcDelegate) As Integer
End Function
_
Public Shared Function SetWindowLong(ByVal hWnd As IntPtr, ByVal nIndex As Integer, ByVal newWndProc As IntPtr) As Integer
End Function
_
Public Shared Function CallWindowProc(ByVal lpPrevWndFunc As IntPtr, ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
End Function
_
Public Shared Function FindWindow(ByVal _ClassName As String, ByVal _WindowName As String) As IntPtr
End Function
_
Public Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As IntPtr
End Function
_
Public Shared Function SetForegroundWindow(ByVal hWnd As IntPtr) As Integer
End Function
_
Private Shared Function RegisterWindowMessage(ByVal lpMessage As String) As Integer
End Function
_
Public Shared Function GetFocus() As IntPtr
End Function
_
Public Shared Function IsWindow(ByVal hWnd As IntPtr) As Boolean
End Function
_
Public Shared Function GetForegroundWindow() As IntPtr
End Function
#End Region
Private oldWndProc As IntPtr
'Private newWndProc As WndProc_WRAPPER = New WndProc_WRAPPER
Private hWndTarget As IntPtr = IntPtr.Zero
Private strClassName = String.Empty
Private strWindowName = String.Empty
Private c_MyMsg As Integer = RegisterWindowMessage("MyMessageCheck")
Public Sub StartSubclass(ByVal a_hWndTarget As IntPtr)
hWndTarget = a_hWndTarget
Dim success As Integer = SetWindowLongEx(hWndTarget, GWL_WNDPROC, AddressOf _NewWndProcMyMsg)
End Sub
Public Sub StopSubclass()
Dim success As Integer = SetWindowLong(hWndTarget, GWL_WNDPROC, oldWndProc)
'MessageBox.Show(success)
End Sub
'SUBCLASSING PROCEDURE
Public Function _NewWndProcMyMsg(ByVal hWnd As IntPtr, ByVal msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
If msg = c_MyMsg Then
Return GetFocus()
Else
Return CallWindowProc(oldWndProc, hWnd, msg, wParam, lParam)
End If
End Function
Function GetFocusEx() As IntPtr
Dim hWnd As IntPtr = GetForegroundWindow()
If (Not IsWindow(hWnd)) Then
Return IntPtr.Zero
End If
StartSubclass(hWnd)
Dim hResult As IntPtr = SendMessage(hWnd, c_MyMsg, 0, 0)
StopSubclass()
Return hResult
End Function
End Class
----------------------------------------------------------------------------------
'In my Main()
Public Sub main()
Dim oSubclass As clsSubclass = New clsSubclass
MessageBox.Show(oSubclass.GetFocusEx().ToString)
End Sub
BUT oSubclass.GetFocusEx() ALWAYS RETURN ZERO. SEEM TO HAVE PROPLEM WITH _NewWndProcMyMsg, IT MAKE SUBCLASSED WINDOW (IN OTHER APPLICATION) TO BE CLOSED OR HANG. WHAT MY WRONG?
========================================================================================
SOLUTION 2: Using AttachThreadInput()
I tried to use this function as the same in Win32 but WinCE don't support this function. HAVE ALTERNATIVE FUNCTION FOR THAT IN WINCE ?
=========================================================================================
SOLUTION 3: Enum all child Windows in Active Window and Check if it is Active by USING GetWindowInfo()
I tried to use this function as the same in Win32 but WinCE don't support. HAVE ALTERNATIVE FUNCTION FOR THAT IN WINCE ?
=========================================================================================
Above are 3 solutions which i have tried but not get successful. Could you help me fixed or show me Other solutions to GET ACTIVE CONTROL IN ACTIVE WINDOW IN OTHER PROCESS ?
Who can help me please, Thanks for your answer!
|
|
|
|

|
When I test your demo,I found that you demo can't find the window what IsEnable()==FALSE.But SPY++ in VS can do that.And I want to know why.
Regards.
LOVEZ3
|
|
|
|

|
I have a little quesion for you: are you sure that MS Spy++ uses the SetCapture()&ReleaseCapture() win32api functions for getting a window by the mouse coordinates? Because I also made a proggy that search for windows to "read" their styles, but instead of these functions I have used SetWindowsHookEx() win32api function with WH_MOUSE and I want to say that *ALL* visible windows was "caputred"...For this kind of applications this is the sollution. In win32 nothing is "greater" than the hooks... Believe me!
|
|
|
|

|
Hello,
need some help. I would like to use SysTreeView32. Do someone know how to identify and iterate through the icons in the SysTreeView32 without using the coordinates xy.Click(x,y)?
Thanks.
|
|
|
|

|
Is it possible to port this to C#?
|
|
|
|

|
I have tried to change the cursor using SetCursor from my MFC CDialog, but the cursor changes when it's outside the dialog. I have checked a don't get the WM_MOUSEMOVE message even when I used SetCapture.
Any idea why it doesn't work fine in MFC?
Thanks in advance.
_Leo_
|
|
|
|

|
In spy++, option to find the windows / all the control IDs.
My Requirement is :
===================
A function with an input argument strCaption(caption of the window) should
1. Check whether the specified window exist or not.
2. If exist, It should return all the belonging control IDs
of the selected window along with all the control captions.
Kindly pass me some idea of "How to achieve this with VC++/MFC/Win32" .
|
|
|
|

|
If I have a custom window with nonrectangular form, they are not highlighted as others when I pass over them with cursor. MS Spy++ does it very well.
Can you tell me how I can find the paint region of every window? I want to know whether some custom window covers some part from my windows.
Thank you in advance,
Alexi
|
|
|
|

|
How do I run the Internet Connection Wizard? if possible example
dadsadasd
|
|
|
|
|

|
Dear all,
I want to develop a tool like winrunner(from mercury interactive), that can help testers automate their testing steps.
The first hurdle i'm facing is this:
Using DOM and VB, I'm able to see all the fields present in any web page.
I want this to happen:
When i move my mouse over a field, I want that field to be highlighted with a box drawn around it and the details of that field in my application's text box. The problem is, i don't know how to capture the mouse events that occur when I move my mouse over these fields on the web page.
This is something like the Spy++ program. Only that, this is for web pages.
Please help me in this regard!
with warm regards,
marcq.
|
|
|
|

|
Hello Lim Bio liong and the code project community,
Since I found this excellent code yesterday, I've started utilizing it in my WTL projects. This code is just what I was looking for.
Lim Bio Liong, thank you for your contribution.
The only problem that I had with the original was a refreshing
windows as Mr. virkrams and some others suggested.
(did not know until I read those comments.)
Nothing is per-fec-to in this world and I guess I am not the only one who's having this problem. But that's what makes the rest of us reading articles eventually do something better for our community, isn't it?
Ok. It appears that this problem occurs when many windows are crammed. (hint: windows may be decendents of another window - that's right. that's Windows.)
Like your MSDEV's toolbar or toolbox in the Paint application can reproduce this problem. (ok, so it's reproducible.)
Anyhow, I summarized three more things that I think you can do yourself. I hope you are glad you did not have to pull your hair after reading this.
If you go through these steps, probably your application will run as expected or better (no guarantee though).
#1 - POINT-FINGER-FREE window selection style
Note: if you stay with SPY++ style window selection style, skip this.
Sample application uses grab-bull's-eye-and-set-focus, that is, you need to hold mouse button down
while moving mouse cursor. (yep, this is called "SPY++ style".)
I wanted to select a window without keeping holding down the mouse button and use a button to engage
window selection. So here's what I did:
1. Add WM_TIMER handler
(the name of the function is most likely to be OnTimer()
when using "Add Windows Message Handler...")
2. Add a new button and Start the timer when the button was pressed.
Set timer interval to 500 or whatever interval you wish to use.
3. In WM_TIMER event handler, throw WM_MOUSEMOVE at yourself
(your Dialog). For example,
LRESULT OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
SendMessage(m_hWnd, WM_MOUSEMOVE, 0, (LPARAM)0);
return 0;
}
You can rebuild and examine now at this point.
#2 - ONE-REFRESH-ONLY please!
(imagine Sean Connery played in the movie Red October)
Note if you stay with SPY++ style window selection, skip this too and proceed to #3, "GETTING RID OF GARBAGE HIGHTLIGHTS"
If you want to go with POINT-FINGER-FREE window selection style as mentioned in #1.
After rebuilding your app, you will see window flickering going on because of timer you set in step #1
and probably want to suppress it as much as you can.
WindowFinder app's StartSearchWindow Dialog calls DoMouseMove(), trying to refresh the OLD window
to get rid of highlight before highlighting the new window found (discovered). In DoMouseMove(),
ORIGINAL CODE
// If there was a previously found window, we must instruct it to refresh itself.
// This is done to remove any highlighting effects drawn by us.
if (g_hwndFoundWindow)
{
RefreshWindow (g_hwndFoundWindow);
}
Here's what you can do:
AFTER
// If there was a previously found window, we must instruct it to refresh itself.
// This is done to remove any highlighting effects drawn by us.
// Refresh the OLD window to get rid of highlight from it
// only when we leave for a new window discovered at current mouse cursor position.
if (g_hwndFoundWindow && g_hwndFoundWindow != hwndFoundWindow) // Got a new window
{
RefreshWindow (g_hwndFoundWindow);
}
This way you don't cause flicker with Timer-driven redrawing because you call RefreshWindow() when you need it.
#3 - GETTING RID OF GARBAGE HIGHTLIGHTS
So what's up with the refreshing problem, eh? you might wonder.
Remember I mentioned about "windows may be decendents of another window" thing?
Well, when I was watching the garbage highlight problem, I noticed that
when I move cursor to select the outer window it can remove the garbage highlights.
This led me to an easy fix after several experiments:
If (Found parent from windowTobeRefreshed)
Pass that instead to RedrawWindow() along with RDW_ALLCHILDREN
The final code of RefreshWindow() may look something like this:
long RefreshWindow (HWND hwndWindowToBeRefreshed)
{
long lRet = 0;
// IMPLEMENTATION NOTES #3 - GET RID OF GARBAGE HIGHLIGHTS
// By using parent, we get the better result in refreshing old drawing window area.
HWND hwndParent = ::GetParent(hwndWindowToBeRefreshed);
if (hwndParent)
{
hwndWindowToBeRefreshed = hwndParent;
ATLTRACE("I am using parent. Handle:%p\n", hwndWindowToBeRefreshed);
}
::InvalidateRect(hwndWindowToBeRefreshed, NULL, TRUE);
::UpdateWindow (hwndWindowToBeRefreshed);
::RedrawWindow (hwndWindowToBeRefreshed, NULL, NULL,
RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASENOW | RDW_ALLCHILDREN);
}
If you have more findings or better solutions, please be constructive and contribute yours as we all respect codeproject community.
Lim Bio Liong, You da man! Keep up the good work!!
Tom
|
|
|
|

|
Open MSDN help from Visual Studio. Go to Index tab. Your program fails to find the edit box, the list below the edit box, or the button below the list. Strangely enough, it works fine on the other tabs.
|
|
|
|

|
Anonymous,
I don't know how you found this but if I think the problem lurking behind this failure is related to window visibility and implementation of WindowFromPoint() API.
It appears that WindowFromPoint() can't always
help us find windows while they are currently visible
to us (user's view point), but not from Windows perspective.
See, if you carefully watch behaviors of two applications,
SPY++ and Window Finder app, interesting enough, WindowFinder app highlights a dialog under Tab control (SysTabControl32) on while SPY++ is not doing it.
And imagine when you are coding with a control like tab, you would typically have to take care of visibility (hide and show) of controls necessary to make tab selection effect, right?
So in this case, I mean the controls on Index tab
of MSDN help, the dialog under the tab control does not have WS_VISIBLE set, which is causing of this problem, I think.
So unless we dig up the controls blocked by
the invisible state dialog (window), we can't get around.
- Tom
|
|
|
|

|
Tom Furuya wrote:
the dialog under the tab control does not have WS_VISIBLE set, which is causing of this problem, I think.
If you are referring to the window whose class is "HH Child" (the immediate parent of the SysTabControl32 window), this window *does* have WS_VISIBLE set, so this cannot be the cause of the problem. Please reply if you were referring to a different window.
|
|
|
|

|
I am not referring to HH Child, but the dialog (identified as #32770), which is the first child of the Tab control.
You are observing "HH Child" and Tab control but I want you to look further at the first child of Tab control, which is a dialog. This is the window that I am talking about.
Interestingly, SPY++ does not spot (highlight) this dialog placed under Tab control (SysTabControl32)
when you are on the Index tab.
Let me try to get you (and readers) there.
I suppose you are familiar with SPY++ tool but just in case there are many other readers who might want to be on the same page here.
1. Open MSDN Library and click Index tab.
2. Launch MS SPY++, press ctrl+F and move bulls-eye over
the Tab control and the client area of the tab control where we are having a trouble locating controls with
our WindowFinder.
3. You can see all controls highlited
(I know you already know) but you don't see any
dialog there.
This is when SPY++ deceives human eye, I think
So don't trust hightlight, but rather focus on
window hierarchy.
4. Now press ctrl+F again. After selecting
the tab control (SysTabControl32), go back to SPY's
"Find Window" dialog and click OK. Click "Windows" Tab
of "Window Property".
5. Click on window handle (hyperlink, colored in green) of "First Child".
That's all. This is the way I see this symptom.
I am not 100% positive but I would like to hear what you and the silent think because besides MS I know there are people out there who knew why.
Hope this helps.
- Tom@wish there was a WindowFromPointEx()...not
|
|
|
|

|
Yes, this is interesting. There does not seem to be any advantage to hiding the dialog, so perhaps it is just accidental.
Out of curiosity, have you tried EnumWindows on these windows? I wonder if there is any way to get the true hierarchy, instead of just the z-order hierarchy? Perhaps if you could get the entire list, you could temporarily set the WS_VISIBLE bit, so WindowFinder could show what's really there.
Mildly amusing.
|
|
|
|

|
Anonymous wrote:
Perhaps if you could get the entire list, you could temporarily set the WS_VISIBLE bit
you can, but probably you don't want to do it.
Changing the state of window (window style) could cause a bad side-effect; those controls stayed invisible would start appearing while mouse were moving over them. Besides, primary goal is to perform
a good window salvation? or discovery (I don't know how to put this)
as good as SPY++ does.
Anonymous wrote:
have you tried EnumWindows on these windows? I wonder if there is any way to get the true hierarchy, instead of just the z-order hierarchy?
Hmm, I have been thinking about other thing - the WindowFromPoint() API and its window search strategy. I had a hard time reading between lines about the API.
After I slept on it, I am getting ideas. As you said, we need to
walk on a trail of windows. I'd rather not manipulate a child window but just simply checking it like we do with WindowFromPoint():
1. What we need is to get around the blocking window, like the dialog in our case.
2. Don't want to alter any window styles, but just check 'em out
3. Ok. The question is how. No WindowFromPointEx API, and obviously a single call to WindowFromPoint is not good enough to 'dig up' the window which we can't highlight. However, I've found a similar
API which seems to fulfill our desire. ChildWindowFromPointEx() examines child windows like WindowFromPoint does. With this, check the visibility of the window as a 'cue' (to determine whether we are hitting the barrier and therefore prepare to run the search mission).
4. Mostly, we don't have a situation like this. So only if we hit the invisible window, we start the salvation(?) to dig the window, which is supposed to be visible in human eye and also contains the specified point (current mouse-cursor position).
5. If we start scanning the tree, chances are these blocked control windows (from programming viewpoint) are sitting very close to us, as SPY++ shows us. This is because the window hierarchy is actually in the same application, for example, MSDN's HH Child subtree part, correct?
So we don't have to pay too much cost when locating the window we should present.
I don't want to speculate too much on this, but what do you think?
It may not be a silver bullet but it could be a simple remedy?
Hope this helps.
- Tom@one api and our desire
|
|
|
|

|
Tom Furuya wrote:
Changing the state of window (window style) could cause a bad side-effect; those controls stayed invisible would start appearing while mouse were moving over them. Besides, primary goal is to perform
a good window salvation? or discovery (I don't know how to put this)
as good as SPY++ does
I think you have hit the nail on the head here. The primary goal is to to implement a "Windows explorer", which *should* include invisible windows. I have used spy++ when I was trying to reverse-engineer a non-trivial UI, and being able to see non-visible windows would really have helped. Maybe you could have a "Show invisible windows" option? In any case, I think the goal should be to discover what's really there, not just what Windows is showing you. My two cents.
|
|
|
|

|
Ok. Say, provide a better presentation than SPY++ does.
I thought the original question was that there are
windows visible on screen and for some reason they can't be highlighted, however SPY++ manages somehow. That's where I said "as good as SPY++" does.
Anonymous wrote:
being able to see non-visible windows would really have helped. Maybe you could have a "Show invisible windows" option?
if you only need to pick up the invisible dialog, for example, then call ChildWindowFromPointEx with CWP_ALL param to see if child is really there and subsequently call SetWindowLong to check WS_VISIBLE
(0x10000000L) flag. This is what they call 'a nonrestrictive search',
I think.
And about the funky ditched window thing,
There are very important remarks found on MSDN. Just few lines gives
you an implication and insights on how the system performs the window search when using coordinates and because of that this funky situation can be caused.
Quote "If more than one child window contains the specified point, the system returns a handle to the first window in the list that contains the point.".
- Platform SDK: Windows User Interface, ChildWindowFromPoint()
I've never thought about this window search strategy behind these
WindowFrom** API family. But now I figured why.
- Tom
|
|
|
|

|
Well, with ChildWindowFromPointEx you have another problem - what HWND to pass to it? Doing a quick hack to WindowFinder, I was unable to find a suitable HWND, that enabled WindowFinder to see the items on the invisible dialog.
|
|
|
|

|
Anonymous wrote:
what HWND to pass to it? ..., I was unable to find a suitable HWND
Suppose, you are still using MSDN HH Child with Index tab selected.
Then, HWND to pass would be of SysTabControl32.
Did you use CWP_SKIPINVISIBLE when calling it?
If so, that's the pitfall. Use CWP_ALL instead and examine the style out of HWND you obtain. If you are not getting any HWND, I guess
we are not on the same page.
What do you think the next action ChildWindowFromPointEx()
should take when specified SKIP parameter?
Give up or proceed until find the right one??
You need to be able to draw the whole picture of window tree under HH Child or HH Parent using SPY++ before getting your hand dirty.
After all this is the only tool that helps you out, at least for now.
I just said 'figured why', meaning being able to see the behind scenes of this funky situation.
how bout this? It's a static.
// Given a SCREENPOINT, checks to see if the child spotted is visible.
// @return TRUE if visible. FALSE otherwise.
inline BOOL
WndInfoHelper::IsChildWindowVisible(HWND hWnd, const CPoint& screenpoint)
{
ATLASSERT(::IsWindow(hWnd));
// ::ChildWindowFromPointEx takes point in CLIENT coordinate
CPoint clientpoint(screenpoint); ::ScreenToClient(hWnd, &clientpoint);
// Implementation Notes
//
// It is important to call ChildWindowFromPointEx() with CWP_ALL;
// we need to check to see if the child window at this screen point is really
// visible. CWP_SKIPINVISIBLE is not going to help.
// For those who use MFC, use CWnd::ChildWindowFromPoint().
//HWND hwndChild = ::ChildWindowFromPointEx(hWnd, clientpoint, CWP_SKIPINVISIBLE); //d'oh!
HWND hwndChild = ::ChildWindowFromPointEx(hWnd, clientpoint, CWP_ALL);
if (hwndChild)
{
const LONG style = ::GetWindowLong(hwndChild, GWL_STYLE);
return style & WS_VISIBLE;
}
return FALSE;
}
- Tom
|
|
|
|

|
Well, if it's any consolation, the new Winspector by Russ Freeman also fails the "Index" test.
|
|
|
|

|
is that commercial software? You could then expect the fix in the next release.
More interesting issue is the logic of the APIs.
It may deserve another article (well, I have posted to give my perspective in the best way I know how) because I find this hilarious yet thought-provoking.
- Tom
p.s. I am done last week. My speculation was not that bad after all. If you read back my old 2 cents (more than 2??). The key was, again, the presence of the invisible (child) window in MSDN-Help's left pane (see below). And this is what I am most afraid of, since I have yet not seen any other patterns so far...
After all,
It appears that Window search of WindowFrom*** is somehow performed
downward due to container-contained relationship, and
they could care less about those siblings (called spec.)
Consider your mouse movement on the screen when scanning
windows, you go like:
[HH PARENT]
|
V
[HH CHILD]
|
V
[SysTabControl32]->[The Orphans...]
|
V
[INVISIBLE] Oops
It was amuzing, funky and yet another unhealthy programming situation.
Is this another reason why another API called RealChildWindowFromPoint() (Requires Windows NT 4.0 SP4 or later) was born? Afterthought? Think about it
|
|
|
|

|
Yes, I agree. I would not be surprised if there was some secret API like you say. The problem (for people trying to do spy-type utilities) is that a user might suddenly mouse into the middle of the "Index" tab, without first mousing over its parent. Then, you would need a complete windows hierarchy list, in order to determine what window the mouse was *really* over.
I appreciate your candid comments. To be honest with you in return, I have been working with a company that is developing a "super spy++". I found the Index problem by testing this tool on every window I could find, in every application I had. The tool now has no problem with the Index tab. There are several amusing differences between the versions of Windows (98/NT/2000/XP) and how the documented APIs work or don't work.
I know what you're going to ask, but I can't reveal the algorithms that I developed for use in this tool, because they were paid for by my client under contract.
Actually, I think the ease-of-use issues are just as important for a developer's tool like this, and I never liked being forced to drag the "finder" image around, then having to go back and drag it around again - do this several dozen times for several dozen windows, and it gets old real fast.
BTW, the Winspector I mentioned is available here on CodeProject:
http://www.codeproject.com/useritems/winspector.asp
(I am not involved with Winspector in any way.)
|
|
|
|

|
Welcome. I can understand your situation - I have no question to ask.
- Tom@every man has his humor
p.s. not much to say. too bad that I can't upload the image.
The following code is of mine, which will solve Help Index problem and may be something to begin with.
(I will leave further refinements or *anything* up to you (not you anonymous .)
inline HWND
WndInfoHelper::SearchVisibleWindow(HWND hWndToBeginWith, const CPoint& screenpoint, HWND orphan )
{
ATLASSERT(::IsWindow(hWndToBeginWith));
HWND parent = GetParent(hWndToBeginWith); parent = parent ? parent : GetDesktopWindow();
if (parent == GetDesktopWindow()) return orphan;
CPoint clientpoint = screenpoint; ::ScreenToClient(parent, &clientpoint);
for (HWND hwndT = hWndToBeginWith;
hwndT;
hwndT = ::GetWindow(hwndT, GW_HWNDNEXT)) {
if (IsChildWindowVisible(parent, screenpoint))
{
CRect rect; ::GetWindowRect(hwndT, rect);
if (rect.PtInRect(screenpoint))
{
orphan = hwndT;
}
}
}
if (orphan) return orphan;
return SearchVisibleWindow(parent, screenpoint, orphan);}
- Tom
|
|
|
|

|
Tom Furuya wrote:
See, if you carefully watch behaviors of two applications,
SPY++ and Window Finder app, interesting enough, WindowFinder app highlights a dialog under Tab control (SysTabControl32) on while SPY++ is not doing it.
CORRECTION. This is bogus. Neither SPY++ nor the original
Window Finder code highlights the dialog under the Tab control on the Index tab.
- Tom@interesting, some commercial soft has the same limitation
|
|
|
|

|
Hi Lim,
This article comes at the right time. I am working on project with modules that require doing what you just did. Thanks. You just made my day.
I downloaded your code and the demo. It works create. I rated it after trying it out. I did observe that the WindowFinder do not find some controls in certain situations.
IF controls are grouped in GroupBox (Frame that group Controls), the tool does not fine such controls.
After studing the code, I found out that you are using....
// Determine the window that lies underneath
// the mouse cursor.
hwndFoundWindow = WindowFromPoint (screenpoint);
I did face that problem too. If I use WindowFromPoint to locate controls in a GroupBox, it is the GroupBox Button control I get in return.
Have you resolve this issue, or you did not come across it?
Please anyone who reads this message and has a solution, let me know.
I did try using ChildWindowFromPoint and ChildWindowFromPointEx, non return the correct control.
Thanks
We can't stop asking "WHY!!"
|
|
|
|

|
Hello Bobga, Thanks very much for the very encouraging remarks. I'm glad that the sample code has helped you. Concerning the problem with WindowFromPoint() : yes, this is very strange indeed. The following are some points I observed during investigation : 1. The WindowFromPoint() API specifically did not return the appropriate window handle when the window in question is contained within a Group Box as you have also noticed. 2. The MS Spy++ Window Finder seem to have overcome this problem. 3. The windows within a Group Box are NOT children of the Group Box. This can be confirmed via MS Spy++. They are the children of the parent of the Group Box itself. 4. When I used dumpbin.exe to lookup the APIs that MS Spy++ uses, I found that it uses the WindowFromPoint() API and it does not use ChildWindowFromPoint() nor ChildWindowFromPointEx(). In my humble opinion, MS Spy++ probably detects whether a window is a Group Box (via detecting the BS_GROUPBOX style). If so, it may actually Enum the parent of the Group Box for all child windows and may keep information on these children windows in a list. With this list of info, Spy++ can still locate child controls inside a Group Box as the mouse is moved. This is certainly rather complicated but it is a possibility. I'll continue to do a little research on this in my spare time and will revert to all if I manage to find out any clues. Thanks again, Bobga, Bio.
|
|
|
|

|
Hello Lim,
I am looking for a kind of solution where we should write an activex control to monitor another application to see whether it pops up a specific dialog box. If it pops up the
dialog box i should be able to capture that dialog window and kill it.
In Detail:
I have an VB application which uses browser control through which it displays a html page.On one instance when i try to close the browser control window, it pops up a message asking "Are you sure that u want to close ?" where OK and Cancel are the options available for that dialog box.
I want to trap this particular dialog box and make it disappear before the user could see that on the screen.Either i have to destroy it or by default make it OK.
Can you suggest me an idea for this..It would be great if you could send your suggestions in my email suratkumar@hotmail.com
|
|
|
|

|
We have test your tool many times,it's cool!
Jack
Regards
--------------------------------------------
http://www.ucancode.net (Home page of XD++ MFC Library for Visual C++.NET)
|
|
|
|

|
Using spy++ I am able to find a CListBox ( I thought it was a CRichEdit) control and monitor all the updates. I need to be able to hook into that CListBox and have my program read the updates and take appropriate action.
I can use spy++ to log the data to a file and then parse the file in real time. However, this is not an elegant solution. Obviously spy++ is able to do what I need to do, but have been unsuccessful in getting this functionality into my code.
Any pointers you could give me to point me in the right direction?
|
|
|
|

|
RefreshWindow doesn't work in paintbrush Toolbox.. It just paints all the buttons in toolbox
vikram vs
|
|
|
|

|
Like you, it is a long time that I was planning to do it.
Now I just enjoy your work
Marcello
|
|
|
|

|
Hello Marcello, Thanks very much, Marcello, for the very encouraging comments Best Regards, Bio.
|
|
|
|

|
Thank you very much for your code. It is very clear to understand and your documentation is excellent. It is very nice to get so nice sorted example.
Thanks again.
Petr Havlicek
|
|
|
|

|
Hello Petr, Thanks very much, Petr, for the very encouraging comments. I've also written 2 other articles : * WindowFloater - A System Tray Utility To Make A Window Float To The Top. * WindowSnapshot - System Tray Utility To Surgically Capture Bitmaps of Windows/Controls On The Screen which make practicle use of the principles of this article. Hope you'll find them useful as well. Best Regards, Bio.
|
|
|
|

|
How can I make this utility spy on buttons, links etc on a web page in Internet Explorer?
|
|
|
|

|
Hello SAK, This is apparently a very popular concept and I've received another question similar to this one from another developer recently. In short, SAK, I believe this would be very difficult to achieve. The following is a summary of my views on this : 1. Internet Explorer uses the Web Browser Control to diaplay HTML pages. Yes, the entire client window of IE is a single Web Browser ActiveX. 2. Everything displayed on the Web Browser Control is rendered "by hand". That is, all text, bitmaps and even Edit Boxes, Buttons and Radio Buttons are hand-drawn. They are not child windows or controls of the Web Browser. Also, as the user moves the mouse cursor across the web page, the mouse cursor may be changed by the Web Browser Control depending on the HTML object underneath it. 3. Try using Microsoft Spy++ to select this Web Browser window and Spy++ will report that it is of class : "Internet Explorer_Server" and that it has no children windows/controls. 4. The only exceptions to this are : 4.1 ActiveX controls. If the web page contains any ActiveX controls, then this ActiveX would be a control of its own and would be a genuine window. 4.2 Combo Boxes. Combo boxes in an IE Web Browser Control use the "Internet Explorer_TridentCmboBx" class controls. I'm not sure whether only one instance of such a combo box is created and maintained or as many as requested in a HTML page. 5. The above are the reasons why, using this article's WindowFinder or the MS Spy++ Window Finder, we cannot select HTML objects like buttons, links, etc that are displayed on a web page in IE. However, SAK, I have given this question some deep thought and came up with the following suggestions which may be worth further investigation : 1. Research to see if there are any OLE/COM interfaces exposed by the Web Browser control that will allow us to achieve our target. 2. If these interfaces do exist, get a pointer to this interface as follows : 2.1 Develope a Spy application and that somehow gets the HWND of the Web Browser control. 2.2 In our spy application, try to attach the HWND to a CWnd class object using CWnd::Attach(). 2.3 Use the CWnd::GetControlUnknown() method to get a pointer to the IUnknown interface of the Web Browser OLE control. 2.4 Thereafter, use QueryInterface() to navigate to the desired interface. This seems like a pretty interesting project to do by itself. One more important thing is that the Spy application to be developed must be a DLL. Furthermore, this DLL must be loaded into the same process space as Internet Explorer itself. Otherwise, CWnd::GetControlUnknown() will not work. One way we can attempt to break into the process space of IE is to have IE load a HTML file that contains an ActiveX Control. This ActiveX Control can then manouvre itself to get a pointer to the HWND of the containing Web Browser. Another way I can think of is to somehow get the HTML syntax of the web page that is currently displayed by the Web Browser Control, parse it using a DOM Parser, and insert JavaScript or VBScript containing hook code and then have the Web Control refresh using the new modified HTML. Using a good DOM Parser like MSXML might do the trick. We can, for example, attempt to get a list of "INPUT" tags of specific types and insert/augment script code in them. Getting the browser to refresh using the modified HTML requires calling the Navigate() automation method and would require us to get a pointer to the IDispatch interface of the Web Browser. However, SAK, the above ideas are really theoretical. Research work is needed to prove their concept. Let me know if you succeed in achieving your goals.
Thanks and Best Regards, Bio.
|
|
|
|

|
The code is very interesting and gives a lot of ideas.
You have documented it also very well.
Great work. Thanks for sharing it with us.
|
|
|
|

|
Hello Melwyn, Thanks very much, Melwyn. I appreciate it very much. I hope you'll find good use for the code. Best Regards, Bio.
|
|
|
|

|
This is what I have searched for a long time.
Very nice program!
|
|
|
|

|
Hello CKL, Thanks very much ! This is very encouraging. Best Regards, Bio.
|
|
|
|
 |
|
|
General News Suggestion Question Bug Answer Joke Rant Admin
Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.
|
Ever wondered how the cool Microsoft Spy++ Window Finder Tool is created ? Here is one possible implementation.
| Type | Article |
| Licence | CPOL |
| First Posted | 29 Dec 2001 |
| Views | 303,737 |
| Bookmarked | 173 times |
|
|