Mar 212013

One of my programs needs to access a shared folder on another system.  Unfortunately, the other system may be on another domain and/or workgroup so the access may not be automatic if credentials had not previously been set up.  When this happens using Explorer you will see a dialog pop up that asks for a login and password for the share you’re trying to access.  The dialog allows you to save the credentials so you don’t have to put them in every time.

In my program I am trying to access a file on a shared folder and if the folder is not accessible the file access just fails and the user is left up to their own to figure out how to fix the problem.

I wanted to be able to pop up the same dialog so the user is encouraged to enter the credentials for the share in the same way that they do for Explorer.  It turns out that this is pretty easy, but it took me a while to figure it out so I thought I’d post the code here in case anyone else needs to do this sort of thing.

bool ConnectToShare()
{
    CString csResource = RemoveSlash(m_csMyNetworkSharedFolder);
    NETRESOURCE nr;
    nr.dwType = RESOURCETYPE_DISK;
    nr.lpLocalName = NULL; // explicitly set this to NULL
    nr.lpRemoteName = csResource.GetBuffer();
    nr.lpProvider = NULL;
    return WNetAddConnection2(&nr, NULL, NULL,
                CONNECT_INTERACTIVE) == NO_ERROR;
}

I call this function after trying, and getting a failure, for accessing the file I want to open. Then, if the function returns true I try to open the file again and, finally, fail if it can’t after the connection is made. Fortunately, it seems to work pretty reliably once the connection is established and the users sees something they recognize instead of my dumb “it just didn’t work” message.

Hope this helps!

Oct 182012

I talk to people all the time about upgrading to Visual Studio 2012. There are some great technical reasons to upgrade, but almost no one likes the new user interface. One of the first questions is always, “Why are the menus in upper case?” Many also don’t like the color scheme because it looks a little dreary.

Fortunately, these are two easy things to fix. The first, the upper case letters, is super easy to fix. For Visual Studio Pro just add a key to the registry:

Open your registry editor.
Create a new key:
HKEY_CURRENT_USERS\Software\Microsoft\VisualStudio\11.0\General\
called SuppressUppercaseConversion. It should be a DWORD and set to the numeric 1.
Quit the registry editor and start up Visual Studio. You’ll notice that now the menus display as you were hoping.

Changing the color scheme is also pretty easy:

Open Visual Studio 2012 and to to Tools/Extensions and Updates
Find and load the extension called “Visual Studio 2012 Color Theme Editor”
After it’s loaded you can go to Tools/Customize Colors to select on of the built in color schemes or create your own.

The toolbars can be modified to your liking. You would have done that with any release anyway. You can add toolbars based on views, add buttons to existing bars, or create your own bars.

There are so many good reasons to use Visual Studio 2012. Don’t let little appearances hold you back from trying it out.

Sep 202012

I wrote a small MFC program that demonstrates reading CD Text information from an audio disc. It’s pretty well commented. I figured I’d drop it off here in case anyone needs to know how to do this process. It’s kind of simple, but like so many things, it’s complicated to figure out from the information that is given by Sony. You can download this file:

ReadCDText.zip

This is a complete program compiled on Visual Studio 2010.

In case you want some additional information you can start here:

Unofficial CD Text FAQ

There is also a lot of information about the process here:

CD Text Format

Apr 052012

Many people have asked me why I would use C++ for Windows 8 development when I have the whole of .NET to use. The really quick answer is, “Why not?”

For versions of Visual Studio previous to 11 (upcoming release) us C++ types have argued that the tools and syntax are much easier to use in .NET specific languages like C#. However, that is no longer the case. C++ is a first class player in Windows 8/Metro development.

The advantages:

  • We can use all of that we know from years of programming in C++ for the desktop
  • C++ creates programs for Metro that are “native” so much smaller and faster than those created by .NET. There are lots of applications where this is an imperative like games, applications that handle a lot of data, or legacy applications we may be upgrading to Windows 8/Metro.
  • C++ gives us more control over our programming environment so we can still have all the flexibility we’ve always enjoyed within the guidelines that Metro programming requires.
  • We can still write libraries and programs that have more of a chance of being ported to other environments
  • We’ve been touting the benefits of using C++ for years, but for the first time, in several release, C++ is threatening to take the front seat in our programming paradigms again. Smaller, faster, programs are a natural for mobile devices like tablets and phones where memory is still precious. And, for those of us who write programs that handle huge amounts of data, interact directly with the operating system, and want to use the same skill set for developing for the web, drivers, desktop, and Metro C++ will be the best choice.

    I’ve heard a few people refer to it as a “renaissance”. I guess the next few months leading up to the official release will be telling, but I am very optimistic and excited to see so much attention being paid to C++ again.

    Mar 152012

    I’ve been using MFC since the first version was released back in the early 90’s. I’ve heard rumor of its demise more than once. There are likely millions of applications and thousands of useful examples using MFC based code.

    The recent announcements of Windows 8 and Visual Studio 11 have changed direction with respect to the desktop’s part in the user’s paradigm. Windows 8 will work on desktop machines, but it’s really being tailored for use with mobile devices and tablet based computers. This is a good thing for Windows. Windows 8 will help Microsoft migrate to the new “ecosystem” of the future where most of use will consume applications on our phones, tablets, and desktop computers. Windows 8 will help homogenize the look and feel of what we see and will, ultimately, make it easier to use all of these devices since we’ll see basically the same thing on all of them.

    Of course, this leaves some of us with legacy code written in MFC/C++. Some of my applications are hundreds of thousands of lines of code. Many of them have been developed over many years. I’m sure some of you are like me and simply unable to turn on a dime when it comes to migrating applications to new versions of Windows.

    The good news, for us, is it will take several years still for Windows 8 to become the standard. If history repeats it will be at least a year after release before most people will upgrade. Most upgrades will happen as people buy new computers.

    The other good news is all of our MFC code will still run on Windows 8 under the desktop mode. We won’t have the same look and feel as a Windows 8 Metro application, but our users won’t be stranded if they upgrade.

    Even more good news. With the advent of Windows 8/Metro and Visual Studio 11 C++ once again becomes a major player for Windows development. So, those of us who have invested years of lives learning C++ will once again have a first class, modern, language to use in our Windows development.

    The whole new direction sort of reminds me of when MFC first came out in Visual Studio 1.0 , back then leading up to the Windows 95 release. There were a ton of growing pains, but we were all the better for it. We had a lot to learn, but the benefits of learning it really paid off. Now, we have new “stuff” to learn in C++/CX and WinRT. I suspect the payoff will be equally as great as the world changes.

    Our new programs, and code that we migrate from our previous programs will now be easily to use on all kinds of devices. That’s the promise.

    In the meantime, Microsoft has thrown a few upgrade goodies and bug fixes into Visual C++ 11 to show use that they haven’t stopped working on MFC even now.

    Bottom line: It will be wise for us to start embracing the new technologies, but we, and our customers, will not have to totally abandon all of our legacy applications for a really long time to come. Things just don’t move that fast in the Windows world.

    Mar 152012

    A friend of mine passed on this interesting use of an CImageList to make color in a bitmap transparent. It’s really simple and handy for creating bitmaps as backgrounds on dialogs or controls.

    BITMAP bminfo;
    CBitmap bm;
    CImageList imageList;
    bm.LoadBitmap(IDB_RIMAGELOGO);
    bm.GetBitmap(&bminfo);
    imageList.Create(bminfo.bmWidth, bminfo.bmHeight, ILC_COLOR24 | ILC_MASK, 1, 1);
    imageList.SetBkColor(CLR_NONE);
    imageList.Add(&bm, RGB(255, 255, 255));

    Note: the second argument of the .Add() function is the color you want to make transparent.

    Mar 052012

    OK,once again, I can’t talk about much that I learned at the Summit this year. As you’d probably guess a lot of discussions centered around the future of C++ specifically with regards to the new Windows 8 and Visual Studio 11 technology previews which are now downloadable.

    If you haven’t yet, you will definitely want to give Visual Studio 11 a look at:

    Visual Studio 11

    And if you have an extra machine (real or virtual) you can use you will want to look at Windows 8 as well:

    Windows 8 Consumer Preview

    There was a lot of excitement about all the new stuff for C++ in Visual Studio 11 and what a great part C++ will play in this future. I’ll write more later, but I wanted to get these links listed.

    Nov 012011

    If you need to create or open a file that is in a really deeply nested path structure in Windows you can’t use a typical file path. File paths are good up to MAX_PATH (260) characters. If the name of the folders or number of folders deep takes it beyond that restriction you have to add characters to the beginning of the path to tell Windows it’s OK to access. These functions will help you manage those types of paths.

    One of the functions listed below uses the IsPathUNC() function that is part of the SHLWAPI API. To include it simply add the include file “shlwapi.h” and add the library “shlwapi.lib” to your linked libraries for your project.

    #include "shlwapi.h"
    #define LONGPATH_UNC _T("\\\\?\\UNC")
    #define LONGPATH_DRIVE _T("\\\\?\")

    // See if Unicode path already added
    bool IsUNCPathUnicode(CString path)
    {
        CString DRIVEVersion = LONGPATH_DRIVE;
        return path.Left(DRIVEVersion.GetLength()) == LONGPATH_DRIVE;
    }

    // Remove Unicode
    CStringW RemoveUNCPathUnicode(CString path)
    {
        CString UNCVersion = LONGPATH_UNC;
        CString DRIVEVersion = LONGPATH_DRIVE;
        bool bIsUNC = false;
        CString header = _T("");
        if(path.Left(UNCVersion.GetLength()) == LONGPATH_UNC) {
            header = UNCVersion;
            bIsUNC = true;
        }
        else if(path.Left(DRIVEVersion.GetLength()) == LONGPATH_DRIVE)
            header = DRIVEVersion;
        else
            return path; // Already done

        path = path.Mid(header.GetLength());
        if(bIsUNC)
            path = _T("\") + path; // Add back UNC part
        return CString(path);
    }

    //
    //  Return a Unicode name suitable for win32 really long filepaths.
    //  If the name is a UNC then it adds \\?\UNC to the start of the path.
    //  In any case the path is changed to Unicode.
    //
    CStringW MakeUNCPathUnicode(CString path)
    {
        if(IsUNCPathUnicode(path)) // Already done
            return path;
        CStringW csw;
        // allow really long names, add \\?\ for drive letter and \\?\UNC\ for UNC paths
        if (path.GetLength()) {
            path = RemoveUNCPathUnicode(path); // In case it has one already
            if (PathIsUNC(path))
                path = LONGPATH_UNC + path.Mid(1);
            else
                path = LONGPATH_DRIVE + path;
            csw = CStringW(path);
        }
        return csw;
    }

    I hope this helps someone else use this kind of obscure functionality.

    Sep 112011

    OK, it’s my birthday so I’ll do a short one this time. This function must have been written a hundred times, but it is useful. When you have an error from many Win32 functions you typically get back a, not so useful, error number. This function will return a string for that error in a really convenient CString variable.

    CString GetCriticalErrorString(DWORD nError)
    {
        LPVOID lpMsgBuf;

        FormatMessage(
            FORMAT_MESSAGE_ALLOCATE_BUFFER |
            FORMAT_MESSAGE_FROM_SYSTEM,
            NULL,
            nError,
            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
            (LPTSTR) &lpMsgBuf,
            0, NULL );
        CString cs = (LPCTSTR)lpMsgBuf;
        LocalFree(lpMsgBuf);
        return cs;
    }
    Aug 112011

    I recently had to figure out how to read CD Text data from CD’s for an application that needed the functionality. This is the text that you will see on your player if you insert the CD into your car or home device. It includes lots of information about the whole disc and each track on the disc including:

      Artist
      Publisher
      Copyright
      Songwriter
      Names of Songs
      Composer
      Lots more…

    This information is not difficult to retrieve, but there is not much information available for doing it from C++ so I thought I’d just post this sample project in case anyone else needs to get at this information. The zip file at:

    ReadCDText.zip

    Is a working program that has all the code you’ll need. You can get more technical information about CD Text from here:

    Unoffical CD Text FAQ

    Enjoy.