Programmatically Opening the Windows Start Menu

windows-vista-start-menu

Some time ago I was looking for a way to launch the Windows Start Menu programmatically. The simplest way I thought so far was to fake the Ctrl + Escape keystroke so the menu could be tricked as being requested by the user.

I was more than satisfied to discover that a System.Windows.Forms.SendKeys class was readily available from the .NET Framework and that it could be used send keystrokes to other applications.  According to MSDN, all I have to do was call SendKeys.Send("^{ESC}") to achieve my goal.

 

Well, but this didn’t work quite well.

Further reading on MSDN revealed the reason. Sending keystrokes only worked in a focused window, and to focus the Start Menu I needed to get its window handle. A possible, but not so trivial or clean operation to be done in a purely managed world.

Because there is no managed method to activate another application, you can either use this class within the current application or use native Windows methods, such as FindWindow and SetForegroundWindow, to force focus on other applications.

This was going to get quite complex, so I decided for another approach, instead. While googling for the SendKeys class, I found about the SendKeys method of the Windows Script Host (WSH) and decided to give it a try.

 

Using Windows Scripting Host to Send Key Messages to Windows

To use the Windows Script Host in your dot-Net application, all you have to do is include a reference in your project to the Windows Script Host Object Model (found under the COM tab of Visual Studio‘s Add Reference dialog) and then import the IWshRuntimeLibrary namespace to your code with the using directive.

After a bit of testing, it was evident the native SendKeys method behaves differently than the Framework way and didn’t require the windows to be previously focused.

 

So I ended up writing the following code, and decided to share in case someone else finds it useful:

 

using System;

using IWshRuntimeLibrary;

 

namespace cSouza.Utils.Windows

{

 

    /// <summary>

    ///   Provides methods for sending

    ///   keystrokes to an application.

    /// </summary>

    public static class SendKeys

    {

 

        /// <summary>

        ///   Sends one or more keystrokes to the active window

        ///   (as if typed on the keyboard).

        /// </summary>

        /// <param name="keys">

        ///   String value indicating the keystroke(s) you want to send.

        /// </param>

        /// <param name="wait">

        ///   Indicates if execution stops until the sent messages

        ///   have been processd by the target application.

        /// </param>

        public static void Send(string keys, bool wait)

        {

            WshShell shell = new WshShellClass();

            object wObj = wait;

 

            shell.SendKeys(keys, ref wObj);

        }

 

        /// <summary>

        ///   Sends one or more keystrokes to the active window

        ///   (as if typed on the keyboard).

        /// </summary>

        /// <param name="keys">

        ///   String value indicating the keystroke(s) you want to send.

        /// </param>

        public static void Send(string keys)

        {

            Send(keys, false);

        }

 

        /// <summary>

        ///   Sends one or more keystrokes to the active window

        ///   (as if typed on the keyboard) and stops execution

        ///   until the sent messages have been processd by the

        ///   target application

        /// </summary>

        /// <param name="keys">

        ///   String value indicating the keystroke(s) you want to send.

        /// </param>

        public static void SendWait(string keys)

        {

            Send(keys, true);

        }

    }

}

using this class, all we have to do to launch the start menu now is call:

cSouza.Utils.Windows.SendKeys.Send("^{ESC}");

 

I hope you have found this useful. Feel free to use this code as you wish. This is public domain. For more detailed information about how the Windows Script Host SendKeys method works, please read this article, Automate tasks with Windows Script Host’s SendKey method, by Greg Shultz.

Função Pseudo-Aleatoria rand() Completa

Quem já precisou gerar números aleatórios relativamente grandes em C/C++ se deparou com uma situação no mínimo frustrante.

Como uma implementação de função pseudo-aleatória gera números apenas até 32,767?

Até perceber que a função rand não gerava números com mais de 16 bits, perdi um bom tempo procurando um erro inexistente em meu programa. O pior é que este problema é específico apenas à algumas implementações da stdlib, que pude confirmar ocorrer no Visual Studio e no Mingw, que utiliza uma versão do gcc.

Para gerar números aleatórios até máximo que um inteiro (de 32 bits) agüenta, podemos utilizar o seguinte código (que gera números num intervalo fechado de i até j):

int rand_int(const int i, const int j)
{
    return i + ( ((rand() << 15) | rand()) % (j – i + 1) );
}

O que o código acima faz é gerar dois números aleatórios, deslocar um 15 bits para a esquerda (o primeiro bit em um inteiro deverá ser de sinal) e mesclar os dois num mesmo número de 32 bits. Analogamente, é possível formar números aleatórios de 32, 64, ou quantos mais bits se desejar deslocando distâncias suficientes e combinando todos números em um só.

Mais detalhes sobre implementações e aprimoramentos da função pseudo-aleatória podem ser encontrados neste site. É possível até gerar distribuições razoavelmente distribuídas com alguns truques apenas utilizando a função rand().

Outro detalhe interessante é que a sequência aleatória gerada pela função rand(), ao menos nas implementações em que testei, parece se repetir sempre a cada 2,147,483,648 chamadas. Ou seja, a função é capaz de gerar 231 (cerca de 2 bilhões) números aparentemente aleatórios até que o primeiro número seja gerado novamente e a sequência passada recomece exatamente em mesma ordem. Isto é natural de algorítmos para geração de números aleatórios pois um algorítmo é, por definição, um conjunto de passos específicos e finitos, portanto sempre possuindo uma saída previsível sem espaço para incertezas. Daí os algorítmos serem denominados, na verdade, pseudo-aleatórios, pois obedecem um conjunto de regras complexas, mas finitas, para gerar suas saídas.

Tricking higher resolutions on CRT monitors

product-5393439

If you happen to own a display monitor such as the Samsung SyncMaster 550v CRT (a very old model btw) let me inform you that your device may be capable of displaying resolutions higher than the limited on its manual. However, forcing those out-of-spec resolutions possibly can  result in problems, but this is more device dependent than anything else. I’ve tricked this display model for almost 5 years, and it continues to work flawlessly to this date.

The SyncMaster 550v (and probably other models from this line of CRT monitors) is said to have a maximum resolution of 1024×768, but can run just as well with 1152×864 pixels. However prepare your eyes to fight against a refreshing rate of 60Hz. I’ve heard somewhere you can even trick higher refresh rates on this monitor, but I can’t confirm it. Maybe this is pushing too much out-of-spec.

IMPORTANT NOTICE: Using unsupported or unspecified display modes can damage your hardware (your monitor) permanently. Just because it worked for some, you shouldn’t assume it will work for you. I assume no liability or responsability over any damages, errors or failures that could be result of the following instructions. If something brokens, it will always be your own fault! 

How to do this on Windows 9x/Me

    Download PowerStrip. PowerStrip is a shareware program that provides programmable hardware support to a wide range of graphics cards. It is possible to change hardware monitor settings and write a modified driver version for your display enabling the use of higher resolutions. This was the software I used by the time I discovered this was possible, but unfortunately I don’t have any machines with 98 anymore, and I can’t remember the steps exactly involved.

How to do this on Windows XP

    Piece of cake. Just hit the right button on your desktop then select “Properties“. Go to the “Settings” tab then click “Advanced“. Go to the “Monitor” tab then uncheck “Hide unsupported modes for this monitor“. Now you can select all sort of resolution modes for your monitor. But PLEASE don’t go selecting something crazy like the highest resolution available. Try one step above the previous maximum at time. At the very least, it just won’t work, going black or displaying garbage. Wait 15 seconds to return back to previous mode. At the other hand, I can’t garantee it just wouldn’t blow up. USE WITH CARE!

How to do this on Linux

    Well, lets edit our xorg config file as usual. Just grab your favourite text editor, assegure you have the proper privileges and open /etc/X11/xorg.conf. In my case, I’ll use nano.

    nano /etc/X11/xorg.conf

    Now find the Device section, as indicated by the line

    Section “Device”

    Now add the following option line:

    Option “IgnoreEDID” “1”

    In summary, if you had a section looking like this:

    Section “Device”
       Identifier      “NVIDIA TNT2”
       Driver          “nvidia”

    Now it should be looking like this:

    Section “Device”
       Identifier      “NVIDIA TNT2”
       Driver          “nvidia”
       Option         “IgnoreEDID”  “1”

    Now specify the resolutions you want on xorg.conf as normal. I’ll update this post with the proper config lines as soon as I have enough spare time again. Now, just be sure to never make something stupid such as selecting the highest resulution available or guessing something crazy. Make only small, incremental steps. More information about EDID and why we are ignoring it can be found on Wikipedia, here.

Windows Shortcut HotKeys

images

The way Windows recognized hotkeys for shortcuts was always a mystery to me. Create a shortcut, put it on any folder, open its properties and define a hotkey for it. If you happen to have created it on your Desktop, then it should work. But if it was My Documents, then it probably wouldn’t. Now what if you delete your shortcut with the working hotkey? The hotkey will still work, and there will be no way to unregister it other than rebooting!

Well, googling around I found a little explanation about how Windows manages shortcuts (at least until XP, don’t know if it applies to Vista). This will be interesting for a new application I’m writing.


Windows Explorer looks in 4 places for hotkeys, which are read on startup. Hotkeys are stored in the shortcuts contained inside them or in any of its subdirectories. So a to have a valid hotkey the shortcut must be put inside any of the following folders:

%UserProfile%desktop
%AllUsersProfile%desktop
%UserProfile%Start Menu
%AllUsersProfile%Start Menu

Now that explains why rebooting solved the zombie hotkey issue. Interestingly, the place from where I adapted this text has a very useful utility to manage Windows shortcuts that is worth taking a look.