Pluralsight FREE WEEK

Just a heads up to let you know that Pluralsight is making their full library of video courses on machine learning, IT Ops, software development, security, cloud and more free for this week!

During the week, you can freely access all my C++ courses as well!

EDIT 2020-10-20: The Pluralsight free week is over, but now there is a 33% Off Promo on Annual and Premium Subscriptions (Limited time: October 20-22).

Happy Learning!

 

The Case of the Context-Menu Shell Extension That Doesn’t Get Invoked by Explorer

A developer was working on a context-menu shell extension.

He wrote all the skeleton infrastructure code, including some code to display the selected files when the shell extension gets invoked by Windows Explorer. It’s kind of the “Hello World” for context-menu shell extensions.

He happily builds his code within Visual Studio, copies the shell extension DLL to a virtual machine, registers the extension in the VM, right-clicks on a bunch of files… but nothing happens. His extension’s menu items just don’t show up in the Explorer context-menu.

What’s going wrong, he thought?

He starts thinking to all sorts of hypotheses and troubleshooting strategies.

He once again manually registers the COM DLL that implements the shell extension from the Command Prompt:

regsvr32 CoolContextMenuExtension.dll

A message box pops up, informing him that the registration has succeeded.

He tries right-clicking some files, but, once again, his extension’s menu items don’t show up.

He then checks that the extension was properly registered under the list of approved shell extensions (this was part of his shell extension infrastructure C++ code):

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved

He finds the GUID of the shell extension in there, as expected.

He then checks that the extension was registered under the proper subkey in HKEY_CLASSES_ROOT. Found it there, too!

He starts wondering… what may be going so wrong?

He checks the C++ infrastructure code generated by the ATL Visual Studio wizard, including his own additions and modifications. The implementations of DllRegisterServer and DllUnregisterServer seem correct.

He also checks his own C++ code in the C++ class that implements the shell extension’s COM object. He has correctly implemented IShellExtInit::Initialize, and the three methods of IContextMenu: GetCommandString, InvokeCommand, and QueryContextMenu.

He takes a look at the class inheritance list: both IShellExtInit and IContextMenu are listed among the base classes.

The IShellExtInit and IContextMenu COM interfaces are correctly listed among the base classes.
The IShellExtInit and IContextMenu COM interfaces are correctly listed among the base classes.

He feels desperate. What’s going wrong?? He wrote several shell extensions in C++ in the past. Maybe there’s some bug in the current version of Visual Studio 2019 he is using?

Why wasn’t his context-menu shell extension getting called by Explorer?

 

I took a look at that code.

At some point, I was enlightened.

I gave a look at the COM interface map in the header file of the C++ shell extension class.

There’s a bug in the shell extension C++ object’s COM interface map.
There’s a bug in the shell extension C++ object’s COM interface map.

Wow! Can you spot the error?

Something is missing in there!

In fact, in addition to deriving the C++ shell extension class from IContextMenu, you also have to add an entry for IContextMenu in the COM map!

I quickly added the missing line:

    COM_INTERFACE_ENTRY(IContextMenu)

The COM interface map, with both the IShellExtInit and IContextMenu entries.
The COM interface map, with both the IShellExtInit and IContextMenu entries.

I rebuilt the extension, registered it, and, with great pleasure and satisfaction, the new custom items in the Explorer’s context-menu showed up! And, after selecting a bunch of files to test the extension, the message box invoked by the shell extension C++ code was correctly shown.

All right! 😊

So, what was going wrong under the hood?

Basically, since the context-menu shell extension was correctly registered under the proper key in the Windows Registry, I think that Windows Explorer was actually trying to invoke the shell extension’s methods.

In particular, I think Explorer called QueryInterface on the shell extension’s COM object, to get a pointer to IContextMenu. But, since IContextMenu was missing from the COM map, the QueryInterface code implemented by the ATL framework was unable to return the interface pointer back to Explorer. As a consequence of that, Explorer didn’t recognize the extension as a valid context-menu extension (despite the extension being correctly registered in the Windows Registry), and didn’t even call the IShellExtInit::Initialize method (that was actually available, as IShellExtInit had its own entry correctly listed in the COM map from the beginning).

The bug is in the details!

So, the moral of the story is to always check the COM map in addition to the base class list in your shell extension’s C++ class header file. The COM interfaces need to both be in the base class list and have their own entries in the COM map.

And, in addition, to me this experience has suggested that it would have been great if Visual Studio had issued at least a warning for having the IContextMenu COM interface listed among the base classes, but missing from the COM map! This would be an excellent time-and-bug-saving addition, Visual Studio IDE/Visual C++/Visual Assist X teams!

 

Where Should I Register My Context-Menu Shell Extension to Operate on All Files and Folders?

A developer was working on a context-menu shell extension. He registered the extension under:

HKEY_CLASSES_ROOT\*\shellex\ContextMenuHandlers

The developer noted that his context-menu extension was called for all files. But he also wanted his extension to be called for all directories.

If you want your context-menu shell extension to be invoked on all files and all file folders, the correct key to use for registration is HKCR\AllFileSystemObjects, not HKCR\*.

For more information, MSDN has a list of Predefined Shell Objects.

 

Simplifying Windows Registry Programming with the C++ WinReg Library

The native Windows Registry API is a C-interface API, that is low-level and kind of hard and cumbersome to use.

For example, suppose that you simply want to read a string value under a given key. You would end up writing code like this:

Sample code excerpt to read a string value from the Windows Registry using the native Windows API.
Sample code excerpt to read a string value from the Windows Registry using the native Windows API.

And this is just the part to query the destination string length. Then, you need to allocate a string object with proper size (and pay attention to proper size-in-bytes-to-size-in-wchar_ts conversion!), and after that you can finally read the actual string value into the local string object.

That’s definitely a lot of bug-prone C++ code, and this is just to query a string value!

Moreover, in modern C++ code you should prefer using nice higher-level resource manager classes with automatic resource cleanup, instead of raw HKEY handles.

Fortunately, it’s possible to hide that kind of complex and bug-prone code in a nice C++ library, that offers a much more programmer-friendly interface. This is basically what my C++ WinReg library does.

You can query a string value with just one simple line of C++ code using WinReg.
You can query a string value with just one simple line of C++ code using WinReg.

WinReg is an open-source C++ library, available on GitHub. For the sake of convenience, I packaged and distribute it as a header-only library, which is also available via the vcpkg package manager.

If you need to access the Windows Registry from your C++ code, you may want to give C++ WinReg a try.

 

New Pluralsight Course on C++ Standard Library Associative Containers

Happy Pi Day!

My new Pluralsight course on C++ Standard Library Associative Containers is live!

In this course, you’ll learn with a combination of slides and demo code, how to use associative containers like std::set, std::map, and std::unordered_map.

This is a follow up course of my previous course, which I encourage you to watch before this one.

Starting from this course page, you can freely play the course overview, and read a more detailed course description and the table of content.

Comparing the performance of std::unordered_map vs. std::map.
Comparing the performance of std::unordered_map vs. std::map.
Analyzing a subtle bug when working with std::map.
Analyzing a subtle bug when working with std::map.

These are some feedback notes from my reviewers:

Nice use of the PowerPoint slides and Camtasia callouts to keep the learners focused and engaged. [Peer Review]

Enjoyable clip of std::map string to string dictionary translation. [Peer Review]

Overall, a strong module that’s well-explained, approachable and professionally polished. Looking forward to more! [Peer Review]

The content is logically sequenced, building on concepts as we go. The clips are nice and short, which makes it easy to move through and absorb the content. You also do a great job transitioning across the clips; there’s a cohesive flow to the module. [Peer Review]

I’m glad you showed this error, explained why it’s happening, and how to fix it. It’s a good opportunity to reiterate learnings from earlier in the module, and also seems like a common gotcha. [Peer Review]

Happy learning!

 

New Pluralsight Course on C++ Standard Library Containers

My new Pluralsight course on C++ Standard Library Containers is live!

In this course, you’ll learn how to use some important containers implemented in the C++ Standard Library, with a combination of theoretical introduction using slides, and practical C++ implementation code, including analyzing and fixing some common bugs.

Comparing the memory layout of std::list vs. std::vector.
Comparing the memory layout of std::list vs. std::vector.

C++ Standard Library implementations offer high-quality well-tested and highly-optimized standard containers, that are very powerful tools when developing software written in C++.

In particular, I’ll discuss std::vector (which is a Standard Library workhorse), std::array, and std::list, including how to use them, discussing their pros and cons, and giving some guidance on picking one or the other, based on the problem at hand. Other containers (e.g. std::map) will be the topic of follow-up courses.

No prior knowledge of C++ Standard Library containers is required. You only need a basic knowledge of C++ language features.

Working on the implementation of a case-insensitive string search.
Working on the implementation of a case-insensitive string search.

Containers and algorithms are kind of like “bread and butter”, so in this course you’ll also learn about the C++ Standard Library design based on the teamwork between containers, iterators and algorithms, and you’ll see how to perform important operations on containers leveraging some useful algorithms already implemented in the C++ Standard Library.

Explaining the erase-remove idiom.
Explaining the erase-remove idiom.

Note that this course is both theory and practice! In fact, I’ll show practical demo code, and I’ll also discuss some bugs that are especially common for those who are just starting to learn the C++ Standard Library’s containers.

Analyzing a subtle bug when working with std::list.
Analyzing a subtle bug when working with std::list.

These are some feedback notes from my reviewers:

The narration is clear, animated, and engaging. The visuals are particularly helpful. [Peer Review]

You do a particularly good job clearly stating the problem here (and elsewhere) so that the solution, when it comes, makes sense and fits nicely. [Peer Review]

Great simple example of undefined behavior to reinforce the concepts you’ve introduced as well as a bonus of uncovering a security issue. [Peer Review]

Very nice module with good examples. Also excellent visuals when describing list, vectors and the various operations. [Peer Review]

Very nice discussion of the trade-offs between a linked list and a vector [Peer Review]

Nice use of a bug to teach a key concept [Peer Review]

 

Starting from this course page, you can freely play the course overview, and read a more detailed course description and the table of content.

Let me also express my gratitude to all the Pluralsight persons involved in the production of this course: It’s always a pleasure to work with you all!

I hope you’ll enjoy watching this course!

 

Printing UTF-8 Text to the Windows Console: Sample Code

In a previous blog post, you saw that to print some UTF-8-encoded text to the Windows console, you first have to convert it to UTF-16.

In fact, calling _setmode to change stdout to _O_U8TEXT, and then trying to print UTF-8-encoded text with cout, resulted in a debug assertion failure in the VC++ runtime library. (Please take a look at the aforementioned blog post for more details.)

That blog post lacked some compilable demo code showing the solution, though. So, here you are:

// Test printing UTF-8-encoded text to the Windows console

#include "UnicodeConv.hpp"  // My Unicode conversion helpers

#include <fcntl.h>
#include <io.h>
#include <stdint.h>
#include <iostream>
#include <string>

int main()
{
    // Change stdout to Unicode UTF-16.
    //
    // Note: _O_U8TEXT doesn't seem to work, e.g.:
    // https://blogs.msmvps.com/gdicanio/2017/08/22/printing-utf-8-text-to-the-windows-console/
    //
    _setmode(_fileno(stdout), _O_U16TEXT);


    // Japanese name for Japan, encoded in UTF-8
    uint8_t utf8[] = {
        0xE6, 0x97, 0xA5, // U+65E5
        0xE6, 0x9C, 0xAC, // U+672C
        0x00
    };
    std::string japan(reinterpret_cast<const char*>(utf8));

    // Print UTF-16-encoded text
    std::wcout << Utf16FromUtf8("Japan") << L"\n\n";
    std::wcout << Utf16FromUtf8(japan)   << L'\n';
}

This is the output:

Unicode UTF-8 text converted to UTF-16 and printed out to the Windows console

All right.

Note also that I set the Windows console font to MS Gothic to be able to correctly render the Japanese kanjis.

The compilable C++ source code, including the implementation of the Utf16FromUtf8 Unicode conversion helper function, can be found here on GitHub.