Bits & Bytes

Fixing Disappearing Icon Overlays

Icon overlays are important for visually keeping track of the state of files in a repository. At a glance, you can tell if the file checked in, modified, locked, etc. Below is a screen of some folders that are under version control in TortoiseSVN. The little green check indicates that these folders and the files inside are all checked in and have not been modified since the check in.

Folders Checked in to TortoiseSVN

Checked in file folders


The problem is that most versions of Windows have a limited number of available icon overlays that they can use at one time, usually 15 or less. If you use a version control system, like TortoiseSVN, it may register many icon overlays. TortoiseSVN, for example, registers 9 icon overlays. OneDrive uses 5 icon overlays and Google uses 3.

Once you exceed the limited number of icon overlays in the registry, the additional overlays are not displayed. In the case of TortoiseSVN, none of them were displayed when some of them could not be displayed.

The solution is to prioritize the icons that you want to see and move them up in the list using the Registry Editor. Begin by opening a Command Prompt and entering “regedit” to open the Registry Editor as shown below:

Opening regedit

Command Prompt

Once you enter “regedit” and hit return, the Registry Editor should open and look similar to what is shown below.

Registry Editor

Registry Editor shown open

As the status bar at the bottom of the window above shows, you need to navigate to the folder Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers. Now, you should see the list of the names for your icon overlays displayed in the subfolder, and you probably have move than 15 or so of them.

The names of these folders is not important, except to prioritize which ones get used. So, if you want to move some of them up the list, you can add spaces to the front of the folder name, as shown above for the One Drive icon overlays (Microsoft adds one space automatically). Otherwise, you can remove any spaces from the front of the name, as I did with the Google Drive icon overlays (In an effort to beat Microsoft, Google prepends two spaces to its names.). You can add any other characters that you would like to the names of the folders to organize them and select View->Refresh to see your changes. As I said, the name does not matter.

Alternatively, you can also delete some of these folders, but you should perform an Export first, just in case you want to be able to Import them back at a later time. Once you are done, you can close the Command Prompt and Registry Editor windows and restart your machine. The icon overlays should show up after you restart.

Creating Multicast Delegates in C#

As stated in my prior post on C# delegates, a C# delegate is similar to a function pointer in C++. There, I gave a couple of examples of how to use delegates and said that I would cover multicast delagates later.

So, what is a multicast delegate? A multicast delegate is a function pointer that can be set to point to multiple functions at the same time. It calls each of them in order when it is called. Since a function can only return one value, multicast delegates must return a void type; that is, they must not have a return type.

The program below demonstrates how to use a multicast delegate. First, the delegate type DPrintMultipleOfNumber is declared. Then, inside the Main() function, we declare an instance of the delegate called pfnMulticast and initialize it with function OneTimes() that is defined below the Main() function. The next two lines add the functions TwoTimes() and ThreeTimes() to it via the =+ operator. Finally, we call all three of the functions via the delegate with the argument 13.

The output of the program looks like this:

UsingMulticast

Program.cs

using System;

namespace UsingMulticastDelegates {
    class Program {

        delegate void DPrintMultipleOfNumber(double dX);

        static void Main(string[] args) {
            DPrintMultipleOfNumber pfnMulticast = OneTimes;
            pfnMulticast += TwoTimes;
            pfnMulticast += ThreeTimes;
            pfnMulticast(13);
        }

        static void OneTimes(double dX) {
            Console.WriteLine("One times {0} is {1}", dX, dX);
        }

        static void TwoTimes(double dX) {
            Console.WriteLine("Two times {0} is {1}", dX, 2.0*dX);
        }

        static void ThreeTimes(double dX) {
            Console.WriteLine("Three times {0} is {1}", dX, 3.0*dX);
        }
    }
}

Using C# Delegates to Call Static and Instance Functions

A delegate allows a programmer to abstract functions as variable values in the same way that he abstracts other data, such as integers and doubles, as variable values. Simply put, a delegate is a variable type that defines a specific type of function. An instance of the delegate can hold a reference to any function of that type.

Basic Steps for Using Delegates

  1. Declare a delegate type
  2. Create an instance of the type
  3. Assign that instance to a function
  4. Call the function via the delegate

The essential steps for using a delegate are listed above and demonstrated in the program below. The program consists of two files: Program.cs and CMyDelegateTester.cs–the additional class file is only needed for the second example.

For the first example, we can layout the steps very easily. First, we have the delegate declaration just above the Main() function, which designates our delegate type, DDoSomething. Next, we have the instantiation, pfnFunction, of the delegate type right after the first comment inside the Main() function. This instance is assigned to the static Square() function in the same line. Finally, we call the Square() function via the delegate in the next line with the value 3.0 and output the result.

In the second example, we do the same thing with an instance function of the CMyDelegateTester class. Notice that we need to instantiate the class and that we assign the function, along with its object, to the delegate. This is important because the delegate is attached to and will depend on the object in this case.

Executing the program, we see the output for each function call:

UsingDelegates

Program.cs

using System;

namespace UsingDelegates {
    class Program {

        delegate double DDoSomething(double dX);

        static void Main(string[] args) {

            // 1. An example using a static function
            DDoSomething pfnFunction = Square;
            Console.WriteLine("The static function returned " + pfnFunction(3.0));

            // 2. An example using a member function
            CMyDelegateTester qTesterObject = new CMyDelegateTester();
            DDoSomething mpfnMemberFunction = qTesterObject.MultiplyByTen;
            Console.WriteLine("The member function returned " + mpfnMemberFunction(3.0));
        }

        static double Square(double dX) {
            return dX * dX;
        }
    }
}

CMyDelegateTester.cs

namespace UsingDelegates {
    public class CMyDelegateTester {

        public CMyDelegateTester() {
        }

        public double MultiplyByTen(double dX) {
            return 10.0 * dX;
        }
    }
}

C# Delegates Versus C++ Function Pointers

A C# delegate is similar to a C++ function pointer. However, there are some subtle differences:

  1. C# delegates require the creation of a new data type. In fact, a delegate declaration is equivalent to a C++ typedef declaration of a function pointer type. While C++ does not require a new type definition to use function pointers, it is good practice.
  2. Like C++ function pointers, C# delegate types are detemined by the arguments and the return value. However, C++ distinguishes between static and instance functions and does not allow them to be used interchangeably as C# does. This is demonstrated in the C# code above.
  3. A C# delegate with a return type of void may be multicast to call multiple functions with one call. This is odd, but it is used with events and listeners, and will be illustrated in a future C# post.