Zum Inhalt

VB.NET – Enable Buttons in Applications with API calls

Every once in a while I stumble across some applications that have disabled control buttons without (for me) any reason. As a primary web developer I would like to have an easy way to enable these buttons. There exist some tools for firefox which you can enable buttons easily. For windows applications its a bit different. There are some win32 unlocker tools, but my virusscan doesn’t like those tools at all and I would like to learn how to do it on my own. I finally ended up with my IDE and some ideas on how to achieve this.
I found some tutorials on how to solve this problem with C#.net, but I haven’t installed C#.net on my box. I therefore tried to find a way to get through this with visual basic.net.

The Problem

There is a small, well known tool, that comes with Windows 7, that I use from time to time: The Calculator.
I like the windows calculator but my girlfriend mentioned that the „%“ button is disabled if you change the calculator from standard to scientific. For me, there is no reason why this button should be disabled, so I tried to find a way to enable it. Here we go.

First of all we have to find out, what the name of this control (window) is. I use a little tool called spy++ to get into the application window structure. This tool lists all running applications with its elements and displays them in a tree structure. The easiest way to find the % button is to click on find (spy++) and aim at any application element. If you release your mousebutton spy++ selects the wanted element in the treeview. In this case I aim at the windows calculator (the disabled % button) and here you can see what it looks like:

spy++

It is a bit cryptic, but if you play around with it you will find out how applications and elements are grouped.

You can see that there is no caption for this button (… 000310D0 „“ Button …) so we can’t use a „find“ call to get the element we want. We have to find an other way.

First of all we need some api calls to get the handle of our main window.

After we have declared our API calls we need to know, how to use them. As you can see in the image above, our button is a subelement of the second #32770 (Dialog). This is itself a subelement of calcframe, which in turn is a subelement of calcframe (weird, isn’t it?).

This is important, because we have to go all the way down to get a handle of our button, so we just start to find the calculator window with the following call:

With this call, we search the root tree and get the first entry of an window that matches our „search request“. I used the classname parameter to identify the calculator. You can use the second parameter „lpWindowName“ to get the handle by its window name, but in this case, the calculator window can have different names based on the language of windows installation, so „CalcFrame“ is the more unique identifier for this particular scenario.
After we get the handle of our calculator, we have to drill down to the next subelements.

Here we drill down to the groupbox which has all the button elements as subelements. The second parameter of FindWindowEx can be used as a startpointer, so you can iterate among elements within the same hierarchy.

Now, after we get the roothandle of our buttonholder, we can start with enabling the % button. As mentioned above, the button window itself has no caption, so we cannot get a direct handle to the window but, after some testing I found out, that the button we are looking for is always the 26st subelement. I was a bit lazy, so I wrote a small loop to enable the first 100 elements

To iterate through all button windows I create an empty button variable with type intptr as startpointer and start the loop. Every cycle I write the current found button window to this variable to use it as startposition for the next cycle. In the end we call the EnableWindow API to enable the button and then, we are done and our % button is enabled, yay!

Maybe there is an easier and even faster way to get this thing to work, but for me I learned a lot about applications and api calls and how applcation elements are threatened by windows.

Here is the complete source code for the vb.net console application:

Veröffentlicht in.NETCoding

3 Kommentare

  1. JD JD

    How do i use this in a button click?

  2. Kimble Gray Kimble Gray

    I’m paste your code to module in VB 2010 but VB 2010 to some error on EnableWindow. It seems like an error is cause by this:

    ‚ Function used to enable windows (buttons, listviews, etc…)
    <DllImport(„user32.dll“)> _
    Private Function EnableWindow(ByVal hWnd As IntPtr, ByVal bEnable As Boolean) As Boolean
    End Function

    Please help…

    Thanks.

  3. I think the syntax changed a bit from my code to something like that:
    [DllImport(„user32.dll“)]

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.