Click here to Skip to main content
Click here to Skip to main content

Capturing Window Controls and Modifying their properties

By , 19 Feb 2005
 

Sample Image - windowspy.gif

Introduction

I was interested to have a tool such as Spy++ in Microsoft Visual Studio, but I'd like that the tool can modify window controls. For instance, some times, we need to enable some inactive controls in a program during run-time. MS Spy++ does not have any facilities to do this, and so I made it by myself.

This program is useful to obtain a window handle, caption, class name, style, and size. Moreover, it facilitates changing caption name, style, and extended style of victim window control in run-time load.

The application is a Win32 project without using MFC. It hooks the target window by WindowFromPoint() user32 API. There is an algorithm to seek on child and parent window to capture child windows inside a program by using GetWindowRect() and GetWindow() in a tricky way. It applies GetWindowLong() to obtain window properties and SetWindowLong() to modify them.

Hooking target window

We can hook victim window through WM_MOUSEMOVE mouse event:

case WM_MOUSEMOVE:
if (bSeeking)
{
  HWND hWindowUnderTheMouse;
  //HWND hWindowUnderTheMouseChild;
  points = MAKEPOINTS(lParam); 
  point.x=points.x;
  point.y=points.y;
  ClientToScreen(hDlg,&point);
  hWindowUnderTheMouse = WindowFromPoint(point);
  if((hwndMain==hWindowUnderTheMouse)||
    (hwndMain==GetParent(hWindowUnderTheMouse)))
  {
    break;
  }
  //------------------------------
  hChildFound=NULL;
  SeekDumpWindow(hWindowUnderTheMouse,point);
  if((IsWindow(hChildFound))&&(hChildFound!=NULL))
  {
    hWindowUnderTheMouse=hChildFound;
  }
  //------------------------------
  if(hWindowUnderTheMouse != hSeekedWindow)
  {
    //
    FrameWindow(hSeekedWindow);
    hSeekedWindow = hWindowUnderTheMouse;
    FrameWindow(hSeekedWindow);
    // update the twin window
    strcpy(szSeekedWindow,"0x");
    _itoa((DWORD)hSeekedWindow,szSeekedWindow+2,16);
    CharUpperBuff(szSeekedWindow+2,(DWORD)strlen(szSeekedWindow));
    SetDlgItemText(hDlg,IDC_WINDOWHANDLE,szSeekedWindow);
    GetWindowInfo(hSeekedWindow);
  }
}
else
{
  points = MAKEPOINTS(lParam); 
  point.x=points.x;
  point.y=points.y;
}
break;

It seeks the correct window target by searching through its parent and its children by SeekDumpWindow() which is defined in <DumpSeek.h> inside the program.

Modifying target window

It is very easy to modify the victim window by its handle. If you have the window handle, you can obtain and change styles very easily by GetWindowLong() and SetWindowLong() and also window caption by using SetWindowText() and SendDlgItemMessage(). By looking inside UpdateFlags() in the program, you will find the code which performs this to modify the target window:

if(TopMost) 
{
  dwExtendedStyle|=WS_EX_TOPMOST; 
  SetWindowPos(hHandle, 
  HWND_TOPMOST, 0, 0, 0, 0,
  SWP_NOSIZE|SWP_NOMOVE);
}
else
{
  dwExtendedStyle&=~WS_EX_TOPMOST;
  SetWindowPos(hHandle, 
  HWND_NOTOPMOST, 0, 0, 0, 0,
  SWP_NOSIZE|SWP_NOMOVE);
}
//----------------------------------------------
if(BACKdwID!=dwID) SetWindowLong(hHandle, GWL_ID, dwID);
if(BACKdwStyle!=dwStyle)SetWindowLong(hHandle, GWL_STYLE, dwStyle);
if(BACKdwExtendedStyle=dwExtendedStyle)
SetWindowLong(hHandle, GWL_EXSTYLE, dwExtendedStyle);
if(Visible)
{
  ShowWindow(hHandle,SW_HIDE);
  ShowWindow(hHandle,SW_SHOW);
}
else
{
  ShowWindow(hHandle,SW_SHOW);
  ShowWindow(hHandle,SW_HIDE);
}
UpdateWindow(GetParent(hHandle));

The code to change caption depends on the type of window control. To change caption of Edit Control and Box Control, it has to use SendDlgItemMessage() instead of SetWindowText() in other window controls:

if((strstr(_szClassName,"EDIT")==NULL)&&(strstr(_szClassName,"BOX")==NULL))
{
  SetWindowText(hHandle,szTitle);
}
else
{
  HWND hWndParent=GetParent(hHandle);
  SendDlgItemMessage(hWndParent,dwID,WM_SETTEXT,0,(LPARAM)szTitle);
}

Conclusion

I hope this tool clarifies window classes and their manipulation for people who are beginners in this field. This would be an introduction to make window Spy tools and work with handles.

Eventually, I should appreciate you if you would kindly take the time to mention your ideas, suggestions, and any bugs you may find in this program.

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)

About the Author

Ashkbiz Danehkar
Other
Australia Australia
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 5memberYiannis Spyridakis10-May-12 1:06 
Very helpful
QuestionGood job!memberDH00081-Mar-12 3:53 
That is a very nice program, I really enjoyed reading the source code. Well done.
 
Question: Would it be possible to modify a sub-window so that I can move it outside of the main window?
 
Thanks.
GeneralInstance of ClassNamemembercharleslambert1424-Mar-11 5:12 
Hi,
 
very good work you did with this.
 
I'd like to know if it is possible to get the instance of the ClassName on a form.
 
Example there is 3 TButtons on a form, I'd like to get the instance of each of them.
 
Just like: TButton1, TButton2, TButton3.
 
Regards,
 
- Charles
GeneralGreat!memberyulinxie16-May-10 4:22 
thx
GeneralOne PblmmemberNaveen.R10-Sep-07 18:23 
Hi,
 
Me too was trying to create some application like this and in between I had a problem in finding the window just below the mouse. So I searched the net and finally reached here. But your application also have same problem. Check the following secnario.
 
In a dialog place a frame and label control one over the other( the label should be kep inside the frame ).
Arrange the tab order so that frame is first and label is second. Now your application cannot identify the label which is inside the frame. But SPY++ does. I have found some other applications like WinID also finds this window. Do you have any solutions?
 

QuestionSpy++memberBourtree7-Mar-07 9:26 
Is it possible to programatically access the functionality of Spy++ - is there an interface to it that I could access. I would like to write an application that integrates at the UI level with a standard 'out of the box' application and was looking to use the content returnd by Spy++ to do so.
 
Thanks

GeneralNice article, but cannot compile with VS.Net 2005memberyjagota18-Feb-07 9:38 
Can u help me out. There were some errors, I did removed them but the executable doesnt executes, in debug or release configuration and even as a release standalone exe. Sigh | :sigh:
QuestionCan it capture a label in vb6 program?memberpctimhk30-Sep-06 8:24 
I can get the textbox caption. However, I cannot get a label caption in a form. It only can get the caption from a form. How can i get a caption of a label within a form?
 
Thank you for you help.
 
Tim
GeneralGoogle Earth ToolbarmemberTodd Wilder22-Jul-06 16:55 
I am trying to disable the google earth toolbar, and when I click "disable" on the toolbar it goes invisible (assuming thats showwindow()), but when you click the area the toolbar is still active. what other API functions go into your disable? great tool though
 

GeneralExtra OrdinarymemberAsheshVashi9-May-06 19:56 
OMG | :OMG:
Blush | :O
GeneralMsDosmemberroberto1979es8-Feb-06 4:15 
Hello, Do you know if there are any application similar that, for msdos operating system?
 
I want to capture a data for a msdos windows. I have installed windows xp, and the vmware. I want to capture some data in it, have you any idea how can I do that?
 
Excuseme but my english is very bad.
Generalvb.netmemberroberto1979es7-Feb-06 11:10 
Have you this application in vb.net?
I want to do something similar for another application and I want to use your idea, but I don't anything about Visual C++.
 
Excuse but my english is very very bad.
GeneralRe: vb.netmemberAshkbiz Danehkar7-Feb-06 12:07 
Hi,
You can write the similar code in vb. net, unfortunately I am not so perfect to write vb. net code, so I can not help you. In order to rewrite in vb, you should pay attention to the API functions which were used in sample code.
Regard,
Ashkbiz
GeneralRe: vb.netmemberTutu7-Jun-06 20:51 
For .Net you can use the Runtime Object Editor: http://www.codeproject.com/csharp/RuntimeObjectEditor.asp[^].
Tutu.
 
http://www.acorns.com.au
Generalwindows controlsmemberB!Z16-Jan-06 22:13 

hye,I visit codeproject.com very often and there I saw your programme
ZERO DUMP.It certainly helped me in learning windows handle.Smile | :)
Actually I want to make a programme which modifies windows
controls (minimize, max, and close options on the upper right corner of a window)
whenever LEFTMOUSEBUTTON is clicked on THEM and i m stuck in how to do it.
Is there any method which gives me this option to send any other msg in responce
to a that like if user clicks minimize the application closes instead minimizing.
Can u help me in this regard?Confused | :confused:
I hope i'll be having ur answer very soon
THANKU.



 
B!Z
GeneralModifing Window Title namememberVitoto7-Dec-05 11:10 
Hi, is posible modify window title name ?
 
Is posible when appz is running or is posible when my Program launch the external .exe program ?
 

You know some issue, How make code for Hook Alert or Protect the hook Specify .exe program in memory ?
 

Thank you.

GeneralRe: Modifing Window Title namememberAshkbiz Danehkar7-Feb-06 12:19 
Hi,
Regarding modify window title name, you are seeing that it is possible by this win spy tools.
Regarding second question, during running , you can change by spying the windows handle and change the title name. Before running time, you can modify it by tracing the position of title name in .data section by an appropriate debugger like ollydbg (http://www.ollydbg.de) and modify the data... or maybe the .rsrc section and changing the string table ...
 
Regarding third question, there is some issues, but it is beyond to explain in some sentences, probably if I had time, I would explain them in a complete text. However, you can find so much information on Web, just look at the sites related to reverse engineering and you will find the answer...
 
Regards,
Ashkbbiz
GeneralFound bug and fix - nice appmemberdrudru2-Aug-05 19:54 

Hey, nice app.
 
On line 276 of TabCtrl.cpp there is:
 
if(BACKdwExtendedStyle=dwExtendedStyle)
 
This needs to be:
 
if(BACKdwExtendedStyle!=dwExtendedStyle)
 
Otherwise, when I try to turn off all the extended styles (as I did), nothing happens since the expression evaluates to zero.
 
Cheers.
Wink | ;)
GeneralRe: Found bug and fix - nice appmemberAshkbiz Danehkar7-Feb-06 12:09 
Hi,
Many Thanks for taking your time to find bug. I will update the code as soon as possible.
Best Regards,
Ashkbiz
Generalmay be a bugmemberAmilan29-Jun-05 6:17 
Hi Ashkbiz,
I like the ability to capture the disabled windows, but there seems to be a bug in the code; when you try to enable or disable a Textbox control, it fails.
If you have some spare time please update the code ... I didn't get time to see the code ... I have downloded a lot of tools and codes from CP, and i am just testing them one by one ...
 
Regards

GeneralJust what I wantmemberispring24-Jun-05 0:30 
this tool save me from the boring "tuning-compile-tuning" work, and It's a good way to study Windows GUI programming.
 
thanks
 

GeneralXP related questionmemberCodeBuddy2612-Jun-05 7:59 
Hi there,
The article is really nice and knowledge enhancer. I saw one problem though. I tried to run this utility on WinXP and changed the "Start" button caption to "START" just to check out.
But the windows sets its style back to what it was originally. i.e. "start" (all lower case).
 
Is there any reason why does it happen?
 
Your information will be a great help.
 
Thanks
GeneralRe: XP related questionmemberJackyFrost26-Aug-05 14:02 
I noticed this also. It seems that after you modify the Start button and then move onto another application to modify, the Start button goes back to it's original state. Almost as if Windowspy is losing hold of the control it has on the start button after it modifies another application. Just a guess.
GeneralPorting to WindowsCEmemberhgode9-Jun-05 0:55 
Hello
 
I like your application, great work. Unfortunately, many features you used in coding are not supported on Windows CE. After I have removed and changed some of your code, I got it running and the main dialog shows me the handle and so on. Now I am stuck with the properties dialog. As I am a beginner, I dont really understand your code here. I inserted a GetLastError() and it says 'invalid parameter' after in this:
HWND WINAPI OnSelChanged(HWND hwndDlg)
{
DLGHDR *pHdr = (DLGHDR *) GetWindowLong(hwndDlg, GWL_USERDATA);
int iSel = TabCtrl_GetCurSel(pHdr->hwndTab);

// Destroy the current child dial!og box, if any.
if (pHdr->hwndDisplay != NULL)
DestroyWindow(pHdr->hwndDisplay);

// Create the new child dialog box.
HWND hChild=NULL;
hChild = CreateDialogIndirect(hInst, pHdr->apRes[iSel], hwndDlg,(DLGPROC) ChildDialogProc);
if (hChild != NULL)
pHdr->hwndDisplay = hChild;
else
ShowError(GetLastError());
return(pHdr->hwndDisplay);
}
 
So I only get an empty tabbed dialog, but no prop pages Sniff | :^)
 
Can you help?
 
Thanks
 
Josef
GeneralRe: Porting to WindowsCEmemberhgode9-Jun-05 2:40 
Uuups
 
I found the eror myself: I replaced so much things and one too much. In
 
DLGTEMPLATE * WINAPI DoLockDlgRes(LPTSTR lpszResName)
{
HRSRC hrsrc = FindResource(hInst, lpszResName, RT_DIALOG);
HGLOBAL hglb = LoadResource(hInst, hrsrc);
return (DLGTEMPLATE *) LockResource(hglb);
}
I replaced the first hInst by NULL and therefor no resource was loaded.
 
If anyone is interested, I will post the Windows CE code.
 
Josef
GeneralRe: Porting to WindowsCEmemberfoobar715-Oct-05 5:57 
Yes, it would interesting to look at it, please post!

GeneralRe: Porting to WindowsCEmemberAshkbiz Danehkar7-Feb-06 12:22 
Hi,
Thanks for updating it in Win CE. I am thankful if you would post yout code which works inside Win CE.
Best Regards,
Ashkbiz
GeneralRe: Porting to WindowsCE [modified]memberPrabhat.Singh30-Sep-07 1:01 
Hello ,
It's Very Urgent.
please can you send me code.
my Email address prabhat.singh@webdunia.net

 
Prabhat Singh
 

 
-- modified at 7:28 Sunday 30th September, 2007
QuestionWhere is the input focus?memberFree to Go21-Mar-05 9:35 
Pls help!
 
I am interested in knowing whether there are any chances to locate the "keyboard cursor" location. Finding the top most window is not difficult but I have no idea which control within a child window that got the keyboard focus nor where is the keyboard cursor location.
 
I wonder whether you have any ideas on
1) which child windows got the keyboard focus,
2) which control within this child window got the keyboard focus and
3) where is the exact location (x,y) the input cursor or keyboard cursor is
 

 
Regards,
 
Joe

GeneralTiz the sweet nectar...memberMark (Code6) Belles15-Mar-05 11:54 
Gotta give you props. 5 Stars. You beat me to the punch. lol, just this weekend I was messing around with one of my other articles, and someone wanted to do Spy++ like window finding/highlighting, so I code up that feature. To let them spy on a window, and then capture it. Since you like this sort of thing, but mine's in C#.
 
http://www.codeproject.com/useritems/Screen_Capturing.asp
 
While I was working on it, I was looking at Spy thinking, you know, it'd be fun to make it edit the style bits of a window... and just today I stumble on your article!
 
I dig the MFC style property box. Good stuff. You did a better job of the cursors, I swiped them from another cursor I found on here. Pretty good stuff man, I like your style.
 
-Mark
 
Si vic pacem para bellum - If you want peace, prepare for war
GeneralSend Messages plansmemberPeter Ritchie12-Feb-05 6:39 
Hi,
 
Great little application. What are you plans for Send Messages?

 
-- Peter
PeterRitchie.com
GeneralRe: Send Messages plansmemberAshkbiz Danehkar13-Feb-05 5:59 
Only for using SendMessage() and PostMessage() API!
 
LRESULT SendMessage(          HWND hWnd,
    UINT Msg,
    WPARAM wParam,
    LPARAM lParam
);
 
BOOL PostMessage(          HWND hWnd,
    UINT Msg,
    WPARAM wParam,
    LPARAM lParam
);
Cool | :cool:
 
Ashkbiz
GeneralWell, I must say, something innovative!memberPolite Programmer11-Feb-05 7:47 
Well, I would like to thank you personally for developing such a usefull utility for us, and taking your time to write an article...
Now CS_GUESSWHATIAM and WS_ANOTHERWNDSTYLE will be no more cryptic and mysterious for me!
 
Thanking you again.
Regards,
Mohsin
 
Polite Programmer


More Object Oriented then C#
GeneralRe: Well, I must say, something innovative!memberThatsAlok11-Feb-05 17:54 
Polite Programmer wrote:
CS_GUESSWHATIAM and WS_ANOTHERWNDSTYLE
 
Big Grin | :-D
 

"I Think this Will Help"
[Vote One Here,.....]
 visit me at http://www.thisisalok.tk

GeneralRe: Well, I must say, something innovative!memberAshkbiz Danehkar13-Feb-05 6:19 
Thank you for your attention. It is not so excellent as your description. But your comment inspire me to write more article here.Cool | :cool:
 
Ashkbiz
GeneralGreat Article!memberThatsAlok10-Feb-05 18:23 
Really, your Utility is very useful, especially the feature which lacks in MSSpy (i.e. changing of window Style), as it can help me to change Window style/button style at runtime without recompiling or extra coding
 
Thanks!
 

However, before ending the post I like to point some problem related design, you can find more about it here[^] and here[^]
 

"I Think this Will Help"
 visit me at http://www.thisisalok.tk

GeneralRe: Great Article!memberAshkbiz Danehkar13-Feb-05 6:14 
This is not very professional article in my idea. I made it for my first article in CodeProject.Com. I think it is in elementary (near to intermediateRoll eyes | :rolleyes: ) level in win32 programming. But it is good for learning windows handle.
Nevertheless, There is a different between it and other same article in web. It is able to capture Disable Window Control and Child Windows control same as MSSPY++. Have you ever seen an open src article which can do it? You can test the other related design in CodeProject. Does it capture disable button? and Does it write only in Win32 project (no MFC)?
Indeed I seldom use MFC Dead | X| .
Thank you for your comment and your rateBig Grin | :-D . My next article will be about PE protector;).
 
Regards,
 
Ashkbiz
GeneralRe: Great Article!memberf211-Apr-05 6:10 
u're too humbled.. Smile | :) thanks for your PE protector! after PE protector will be... haha, PE header repairer..
i have been hearing a lot on yoda, is that u?
 
from,
-= aLbert =-

GeneralRe: Great Article!memberAshkbiz Danehkar12-Apr-05 7:00 
f2 wrote:
thanks for your PE protector! after PE protector will be... haha, PE header repairer..
 
PE header repairerConfused | :confused: !? I don't think so! Might be port monitor...
 
Ashkbiz

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130617.1 | Last Updated 19 Feb 2005
Article Copyright 2005 by Ashkbiz Danehkar
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid