Archive

Archive for the ‘c++’ Category

Force Windows to refresh the Desktop (and Start Menu)

February 23rd, 2010

Today I learned a new trick.

When you programatically delete a shortcut from the Desktop folder Windows is “generally” smart enough to update the Desktop and the “recently used programs” section of the Start Menu. But sometimes it does not work and you are left with a “ghost” icon.

As a regular end user, you can hit the F5 key to force a refresh of the Desktop, but for the Start Menu you are left with no alternative than killing/restarting explorer.exe.

I was looking for a better solution for a custom installer application. And after a lot of MSDN scattering and googling around, Eureka, I finally found a magic incantation to programmatically force a refresh of the Desktop.

SHChangeNotify (SHCNE_ASSOCCHANGED, 0, 0, 0);

Programming, Windows, c++, win32

Make LoadLibrary() failures silent on Win2k

December 3rd, 2009

For a custom installer application, I have been working on a crude and efficient way to determine whether the particular version of the C runtime (CRT) we need is installed or not. The technique I use is simply to check if a dummy DLL linked to the CRT libraries would load up properly.

This works gloriously well, except for one simple detail. When the CRT is not installed, on Windows 2000 only, the LoadLibrary error would also cause a MessageBox to be displayed. This stops the flow of the installer and of course, is not very elegant…

Win2k LoadLibrary failure

But there is a simple trick to get rid of the MessageBox, using the very obscure SetErrorMode system call.

::SetErrorMode(SEM_FAILCRITICALERRORS);
HMODULE hDll = ::LoadLibrary("CrtCheck.Dll"); // Won't bark
if (hDll)   ; // CRT is installed
else        ; // CRT is NOT installed

Do you guys know a better (yet simple) way to determine if the CRT is installed?

Update: this is not a Windows 2000 specific issue (thanks Ferruccio). It’s also true for older versions of Windows. As far as I know WinXP, Vista and 7 do NOT display a MessageBox under the same circumstances.

Programming, Windows, c++, win32

C++: object initialization and error handling

August 28th, 2009

This column is in no way revolutionary. But looking back in the past, when I was learning C++, this is the kind of summary that I would have liked to read. So here it is, for the happy few!

In C++ there are two common idioms with regards to object construction and initialization.

  • the constructor fully initializes the object: this idiom makes it impossible to construct an object which is not correctly initialized and ready to use.
  • the constructor does not initialize (or partially initialize) the object: the initialization is performed at a latter stage by calling some init() method. This, in effect, splits the object allocation and initialization. It is common to encounter this pattern whenever the class mimics some transactional behavior like opening/closing a file, connection/disconnecting from a server…

One may have legitimate reasons to use one idiom rather than the other, but as a rule of thumb the first approach (full initialization in constructor) should be favored. This is because it makes it hard to use the interface of the object incorrectly. In the second case it is possible to construct the object and call a method on it before the initialization was performed. There are two ways to handle this improper usage:

  • do nothing and state that this is an “undefined behavior”. It will probably make the class a bit faster to write, but harder to debug. Not a good idea…
  • carry an internal state to remember whether or not the object was initialized. This make it possible to report errors in a much more graceful way. On the other hand it puts the burden on maintaining an internal state and checking against it. Maintaining an internal state looks very easy but my experience is that it is error prone in the long run…

So in summary, unless you have a good reason not to construct a fully initialized object, then you should. It will make your code harder to use incorrectly and much simpler. And you probably will have to write less.

There’s one issue though… Error handling.

There are three general ways to handle errors:

  • exceptions: this is the recommended and the best possible way.
  • return error code on each function: this is the classical C idiom. In practice it means every function you call returns an error code and that you MUST! check against it.
  • global error state: there is a function or method that you need to call after each method of the public API. This is similar to the role of the  GetLastError() function in Win32. It’s quite unpractical, and very seldom used. Therefore, I will not discuss it any further…

In the case of a fully initializing constructor, it is not possible to use the “return error code” idiom, because the constructor does not return anything. That makes it mandatory to use an exception based system.

I worked in a large organization that essentially banned the use of exceptions in their code, for rather dubious reasons. The consequence of this move was that people were forced to use the “non initializing constructor” idiom almost everywhere. This made the code more verbose (init/terminate functions everywhere), the interface easy to use incorrectly (many bugs were related to calling methods on a non initialized object) and put the burden on maintaining an internal state on each object (many bugs were related to failing to maintain this internal state correctly). But the main source of bug was by far, people “forgetting” to check against the error code, leading to much more subtle bugs long after the point of error.

Sounds like a good idea to favor the fully initializing constructor isn’t it? If you use this idiom then you  must know how to use exceptions properly. Techniques like RAII and smart pointers are mandatory. Here’s one reason:

If an exception is throw in the constructor of an object, the destructor of that object is not called.

So if you do something like in the (counter)example below, you are in troubles:

// class Child1 and Child2 defined earlier...
class Parent {
public:
    Parent() : m_child1(new Child1()), m_child2(new Child2()) { }
    ~Parent() {
        if (m_child1)
             delete m_child1;
        if (m_child2)
             delete m_child2;
    }
private;
     Parent(const Parent& ); // non copyable
     Parent &operator=(const Parent &); // non assignable
     Child1* m_child1;
     Child2* m_child2;
};

In this example if the constructor of Child2 throws and exception, then the constructor of Parent also throws. Since the destructor of Parent is not called, the newly constructed Child1 is not destroyed. It leaks!

However if you rely on smart pointers, the problem disappears. While the destructor of a class is not called if an exception is thrown in its constructor, the destructor of each instance variable is called. The following code would fix the leak:

// class Child1 and Child2 defined earlier...
class Parent {
public:
    Parent() : m_child1(new Child1()), m_child2(new Child2()) { }
private:
     Parent(const Parent& ); // non copyable
     Parent &operator=(const Parent &); // non assignable
     std::auto_ptr m_child1;
     std::auto_ptr m_child2;
};

That’s all folks!

Programming, c++