When cells are not visible on a worksheet, you can watch those cells and their formulas in the Watch Window toolbar. The Watch Window makes it convenient to inspect, audit, or confirm formula calculations and results in large worksheets. By using the Watch Window, you don't need to repeatedly scroll or go to different parts of your worksheet.
This toolbar can be moved or docked like any other toolbar. For example, you can dock it on the bottom of the window. The toolbar keeps track of the following properties of a cell: workbook, sheet, name, cell, value, and formula.
Note: You can only have one watch per cell.
Add cells to the Watch Window
Important: On a Mac, perform step 2 of this procedure before you perform step 1; that is, click Watch Window and then select the cells to watch.
Select the cells that you want to watch.
To select all cells on a worksheet with formulas, on the Home tab, in the Editing group, click Find & Replace, click Go To Special, and then click Formulas.
On the Formulas tab, in the Formula Auditing group, click Watch Window.
Click Add Watch Button image.
Click Add.
Move the Watch Window toolbar to the top, bottom, left, or right side of the window.
To change the width of a column, drag the boundary on the right side of the column heading.
To display the cell that an entry in Watch Window toolbar refers to, double-click the entry.
Remove cells from the Watch Window
If the Watch Windowtoolbar is not displayed, on the Formulas tab, in the Formula Auditing group, click Watch Window.
Select the cells that you want to remove.
To select multiple cells, press Ctrl and then click the cells.
Click Delete Watch Button image.
Observe variables with a Watch window
You can open more than one Watch window, and observe more than one variable in a Watch window.
For example, to set a watch on the values of a, b, and c in the following code:
C++
Copy
int main()
{
int a, b, c;
a = 1;
b = 2;
c = 0;
for (int i = 0; i < 10; i++)
{
a++;
b *= 2;
c = a + b;
}
return 0;
}
Set a breakpoint on the c = a + b; line by clicking in the left margin, selecting Debug > Toggle Breakpoint, or pressing F9.
Start debugging by selecting the green Start arrow or Debug > Start Debugging, or press F5. Execution pauses at the breakpoint.
Open a Watch window by selecting Debug > Windows > Watch > Watch 1, or pressing Ctrl+Alt+W > 1.
You can open additional Watch windows by selecting windows 2, 3, or 4.
In the Watch window, select an empty row, and type variable a. Do the same for b and c.
Continue debugging by selecting Debug > Step Into or pressing F11 as needed to advance. The variable values in the Watch window change as you iterate through the for loop.
Use expressions in a Watch window
You can observe any valid expression recognized by the debugger in a Watch window.
For example, for the code in the preceding section, you can get the average of the three values by entering (a + b + c) / 3 in the Watch window:
The rules for evaluating expressions in the Watch window are generally the same as the rules for evaluating expressions in the code language. If an expression has a syntax error, expect the same compiler error as in the code editor. For example, a typo in the preceding expression produces this error in the Watch window:
A circle with two wavy lines icon may appear in the Watch window. This icon means the debugger doesn't evaluate the expression because of a potential cross-thread dependency. Evaluating the code requires other threads in your app to run temporarily, but since you are in break mode, all threads in your app are usually stopped. Allowing other threads to run temporarily can have unexpected effects on the state of your app, and the debugger may ignore events such as breakpoints and exceptions on those threads.
Note that I am using Windows 7; if the Windows Calculator Acesssory in Windows 8 is different and/or cannot be used in the manner it is used here then I hope you can find another program to use.
The first thing to do is to determine what button to click and the circumstances of when to click it. Execute the Windows Calculator Acesssory. Type "2+2=" into it. The result should be 4 of course. Then click the "=" button. Each time "=" is clicked, the value will be increased by 2. So that is something very simple to automate. We can "manually" execute Calculator and type "2+2=" into it. Then when we execute our sample application it can just click the "=" button and we can see the result.
The next thing to do is to determine the identity of the button to be clicked so our program can click it. With the Windows Calculator Acesssory executing, go to Visual Studio. In the "Tools" menu is "Spy++". If your system is a 64-bit system then you might need to use the 64-bit version of Spy++. Basically I have to use the same while developing an app for
ios development agency. The Spy++ toolbar will look like:With the mouse button down, drag from the Finder Tool icon to the "=" button and release the mouse. The Find Window dialog will be filled in with the "=" button's handle and other data. Click on "OK". You will then get a "Window Properties" window with a tab control with five tabs. The five tabs are General, Styles, Windows, Class and Process. The wndow will look like:
Look for "Contol ID" near the botom of the first (General) tab. It will probably have the value "00000079". It is a hexadecimal value. Whatever the value is, it will probably be that value every time you execute that program. At the Windows API level, controls are often identified by a control id. We can use the Contol ID shown in the Window Properties window in our program.
We are ready to write the application. I assume you can create a console application. If your system is 64-bit then you will need to change the "Platform Target" to "x64". The .Net Process class cannot do everything we need it to do when our application is not the same as the other application in terms of bits (32-bits and 64-bits). The "Platform Target" property is in the Build tab of the project's properties. If you need to automate a 32-bit application from a 64-bit application or 64-bit from 32-bit then you can do that but you will need to use the Windows API directly to do the equivalent of what we are using the .Net Process class to do.
You need to add a "using" for the "System.Diagnostics" and "System.Runtime.InteropServices" namespaces. You will also need to add the following to the "Program" class:
const int WM_COMMAND = 0x0111;
const int BN_CLICKED = 0;
const int ButtonId = 0x79;
const string fn = @"C:\Windows\system32\calc.exe";
[DllImport("user32.dll")]
static extern IntPtr GetDlgItem(IntPtr hWnd, int nIDDlgItem);
[DllImport("user32.dll")]
static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, IntPtr lParam);
The sample program will first look at the processes to find Calculator. We will assume the exe is at:
C:\Windows\system32\calc.exe
When we find a process that is executed from there, we know for sure it is the one we are looking for. Note that there are very many processes in a system; many more than most people are aware of. Each Windows Service is a process. Windows Services and other processes that we need to ignore do not have a window, so we can ignore all processes without a window. The following code will do all that:
IntPtr handle = IntPtr.Zero;
Process[] localAll = Process.GetProcesses();
foreach (Process p in localAll)
{
if (p.MainWindowHandle != IntPtr.Zero)
{
ProcessModule pm = GetModule(p);
if (pm != null && p.MainModule.FileName == fn)
handle = p.MainWindowHandle;
}
}
if (handle == IntPtr.Zero)
{
Console.WriteLine("Not found");
return;
}
The GetModule function is shown later in this article.
We are ready to click the button from within our application. To click the button we will send a BN_CLICKED notification message to the button's parent, the Calculator main window. To do that we will need both the button id (as in the preceding) and the handle of the button. The handle varies for each execution but we can determine the handle based on the handle of its parent and the control id. The Windows API function GetDlgItem does that, as in:
IntPtr hWndButton = GetDlgItem(handle, ButtonId);
Windows messages are sent to a window as determined by the window handle. Messages also have a message id that specifies what the message is for. We will send a WM_COMMAND message. The other two parameters we need to send the message is a wParam and a lParam. The value of those depend on what the message is (the message id). For a WM_COMMAND message doing what we are doing, the control id is passed as the high word of wParam and the low word of wParam is the notification code (BN_CLICKED). The lParam is the handle of the control. It seems unnecessary to pass both the control id and the control window's handle but that is the way it works. The following sends the message:
int wParam = (BN_CLICKED << 16) | (ButtonId & 0xffff);
SendMessage(handle, WM_COMMAND, wParam, hWndButton);
When the processes are being searched, since some modules might be restricted from access for security purposes, we catch errors using the GetModule function. It is very simple, as in the following:
private static ProcessModule GetModule(Process p)
{
ProcessModule pm = null;
try { pm = p.MainModule; }
catch
{
return null;
}
return pm;
}
To test the program, execute Calculator and type in "2+2=". Then execute the sample program. Every time it executes, 2 will be added to the Calculator value.
Hope this article helps you.