Tag Archives: CPlusPlus

Why is MFC Not Dead?

I was reading through some blogs this morning, and ran across this one, from my MSDN Feed.

Here is my answer (I wanted to leave a comment, but it wasn’t working, and I figured it would be a good blog post anyways)

Right now you can make an MFC app and it can run on win98,2k,xp,vista, etc – out of the box. Anything with .NET requires the framework, and if you want your app to just be downloaded and ran, then the framework limitation hurts you. Why make someone download and install a d 20+ MB framework?

I wish there was a way to deploy .net apps without the framework, maybe with just assemblies the apps needs.

But like I said, companies want apps to run on as many clients as possible, which just isn’t a reality with .NET, but it is with MFC.

I really think Microsoft is clueless on why people use MFC and not .NET or even an Web App. Finally, MSFT is starting to use .NET in their client apps here and there (WLW, SSMS, Zune, etc, etc)

Once all apps written by Microsoft use some form of .NET, and Windows 98, 2000, and XP are gone for good (or at such small % of market share they don’t matter, say < 1%), then we can actually write .NET client applications (and have to target the version of .NET on Vista, since that is the lowest common denominator) – OR… MSFT could push .NET as a critical update to XP and wipe the % of .NET installed down to a low enough number to make it feasible to create .NET client apps and get a good chunk of the market share..

There are always going to be people that use MFC for whatever reason, but ease of use is certianly not one of them. A small example is, in .NET, I can create an app that displays a toast message, has a systray icon, connects to FTP, handles web services, and much much more, in very little time, and with a small number of lines of code, whereas in MFC, doing those things is a huge undertaking, 1000′s of lines of code, and even then some of it is very “hackish”. Yes, doable, but not very easily.

Another argument could be as well, that if your app is good enough, people will download it and install the framework if they don’t have it, and I think that is a very good argument (except windows 98 is out of luck – can’t install .NET) – I think this last argument is the best – if people want it, and it is an awesome app, they will install whatever to get it to run.

Anyways, I am rambling.. probably could keep talking on this topic for another 100 paragraphs or so. :)



Installing Fonts Programmatically on Windows

Working on a project, I came across the need to install a font on a machine. Now, manually, you can just right click on the font->install. Or I am pretty sure you can just copy into %windir%\fonts\ and it then it works, but it might not be usable until you reboot, I am not a font expert here so don’t quote me, but just from what I have been reading in the forums.

Now, to install a font programmatically, you can just copy it into the folder, but what if you want it usable right away? um… Well, some people say there are some reg keys you need to run, etc. But I came across another very undocumented app that Microsoft has: fontinst.exe

You can just call this program and pass in an .inf file as parameter and it will install the font for you.

The inf file is formatted like:

[fonts]
My Font Name.TTF

now, to call it, you can run “fontinst.exe /F MyFontName.inf” (if you saved the file as MyFontName.inf)

C++ Code:

ShellExecute( NULL, “open”, C:\\MyPath\\fontinst.exe”, ” /F MyFont.inf”,C:\\MyPath\\”, SW_HIDE );

And it should install your font!

Note: I think you can do multiple fonts in one .inf file, I didn’t try it because I didn’t need to install more than one at a time, but I read on the forums and such that it is possible.



TFS Team Build, TFSBuild.props and Visual C++

Team Foundation Server is a pretty sweet setup. It integrates source control into the Visual Studio IDE, and makes it easy for teams to work on projects together. With a little tweaking you can set up Continuous Integration and nightly builds. There are many different ways to set up your project layouts and references, which can make it easier to do deployments, etc. The one thing they forgot to mention is that, it is really easy with .NET projects. It gets a little hairy with Visual C++ projects.

What happens is that if you have VC++ projects that output libs (assemblies in .NET Land), and another project needs to reference them, you will probably run into pathing issues on your TFS buildserver.

TFS wants to output all the binaries to a specific folder. With VC++, there is a TFSBuild.props file that gets created dynamically that overrides the output folder (nice huh?). It is really a pain to try to override this yourself from what I have been researching. 20 different ways and no real solid method.

On your TFS server, in the path

C:\Program Files\MSBuild\Microsoft\VisualStudio\v8.0\TeamBuild\Microsoft.TeamFoundation.Build.targets

Is where all the settings are stored for how the builds happen.

There is a place in there where you can find the setting where the path gets overridden for VC++. It is set as $(OutDir)

When you make projects on your local machine, the output dir is set to $(SolutionDir)$(ConfigurationName)

Everything builds fine on your local machine, but once you try to set up a team build and have it build on the TFS server, it croaks, because the paths to libs arent the same.

Even though Microsoft says all over, never edit the .targets file, I did anyways, and all our projects build and have no issues on the TFS Server.

One other quick thing I have found different for VC++ projects compared to .NET projects. When you create a team build, you need to specify Win32 for the CPU target instead of the default Any CPU. Another quirk as usual :)



Visual Studio 2005 – C++ Unit Testing – Not so good

So, as of late, I have been programming more in C++ than in C#/.NET. The first order of business was getting everything to Visual Studio 2005, which has been accomplished. In .NET, there is built in Unit Testing, Code Coverage, Refactoring, etc. In Visual Studio C++ unmanaged/native C++, you don’t get any of that. (Thanks Microsoft!) Now, if you code in managed C++, you get all the nice features (I’m pretty sure you get all of them).

What you can do, and there are some articles/blogs on the net, is set up a Unit Testing project in managed C++ and then link in your managed C++ projects. This works. Sometimes. It looks better on paper than when you actually try to implement it, depending on your environment and how you have things laid out.

We are making static MFC (probably the first problem – MFC :)) libs for a Core library, and we had to tweak a bunch of settings (ie: make a new build configuration), just so we could link into the managed C++ projects. There were numerous issue, just too many to list here. Things just don’t work nice together.

When we managed to get things to actually compile, and run, then the code coverage would show all the Microsoft API’s as not covered, since the libs were statically linked in to the test project.

Overall, my experience with Visual Studio 2005 and unit testing has been a good one. As long as you are using VB.NET or C# :) 

It is so nice since it is integrated into the IDE, and it can make unit tests for you from existing code. This all would be a god send for C++, yet, there isn’t anything there.

And as long as I am griping about it, intellisense in C++ really isn’t that good. I did some research and found Visual AssistX, and we purchased it. Really is worth the money. Adds refactoring and intellisense on crack compared to the built in intellisense.

Anyways, I will follow up with a few more posts with my experiences on C++ unit testing. I tried a few other frameworks, and actually got CppUnit to work well, so I will blog on the steps I took to make it work.

Just because you develop in C++ doesn’t mean you can’t develop with an Agile mindset, it is just a little bit harder to get started. Unit Testing, Refactoring, Code Coverage, and then Continuous Integration. Hopefully over time I will get some more posts up about these things and how as a C++ developer using Visual Studio 2005 you can accomplish them (or at least the way I did it) :)

By no means am I saying I know the best way, but it seems that there isn’t much out there talking about this stuff for a native/unmanaged C++ dev using Microsoft technologies, or maybe I just can’t find it.



C++ OutputDebugString()

I have programmed in many different languages, and as much as I can remember, one of the best things you can do is write debug ouput to an output window

VB 6.0 – Debug.Print “Debug Output”

.NET – System.Diagnostics.Debug.WriteLine(“Debug Output”);

and recently I have been doing some VC++ programming, and I didn’t know how to output to the output window, so I decided to figure that one out. Came across OutputDebugString();

Now I can stop throwing MessageBox’s all over the place when trying to debug something. What is cool to is that there are utlities that will read the messages from a debug output, like SysInternals Microsoft’s DebugView

One thing that is kind of weird, is that even if you build in Release mode, debug messages still come out. You could and probably should I am guessing wrap then OutputDebugString() in a DEBUG define, or even better IsDebuggerPresent()

Anyways, I’m glad to have taken 2 minutes out of my coding to find this instead of going along thinking there aren’t easier ways. :)



First-chance exception at 0x7c812a5b in : Microsoft C++ exception: CError at memory location

If you are programming and you have some calls to ShellExceute in your code, and you are debugging, you might see this fly across the output window

First-chance exception at 0x7c812a5b in : Microsoft C++ exception: CError at memory location

The app will be your exe name, and location will be a memory location.

You can reproduce this by calling ShellExecute with a url as the file param like so:

ShellExecute(NULL, “open”, “http://www.stevienova.com” , NULL, NULL, SW_SHOWNORMAL);

You should have a path to a file, but what Windows does is look for the http:// or .com and then does a lookup in the registry for the default handler, which more than likely is Internet Explorer, or Firefox, or whatever is your default browser. More info here

INFO: Use ShellExecute to Launch the Default Web Browser KB 224816

I haven’t tried catching the exception, but I can’t figure out a way to get rid of it. It doesn’t seem to hurt anything and actually doesn’t throw up an error. Just an annoying little quirk in Windows and C++.

I did a little digging on Google and didn’t seem to find any more info, so I guess it isn’t a huge deal. Ahh, the mystery of Windows!!!



C++ – Release Your Buffers

I am in the process of taking some 3rd party c++ source code, and converting it to VS2005. One thing I noticed over and over, is that when you are reading in file contents, you need to make sure to release the buffer, but with the length of the file as the parameter.

For example, this code:

CString myData;

if (file.Open(lpszFilename, CFile::modeRead))
{
DWORD dwLength = file.GetLength();

file.Read(myData.GetBuffer(dwLength), dwLength);
myData.ReleaseBuffer();

file.Close();
}

will throw an assertion when in debug mode

GetData.JPG
to fix, add the dwLength value to your ReleaseBuffer()

myData.ReleaseBuffer(dwLength);

if you run the bad code in release mode, nothing happens, which suprises me, you would think that the runtime would croak, but it doesn’t. Anyways, make sure to release your buffers.



fatal error CVT1100: duplicate resource.

More C++ gotchas. You get this error, what do you do?

Check your resource file, there is a resource with an ID of 1. Change it to something (5000) or whatever, and rebuild. You should be good to go.



error C2440: ‘static_cast’ : cannot convert from ‘UINT (__thiscall CStaticLink::* )(CPoint)’ to ‘LRESULT (__thiscall CWnd::* )(CPoint)’

If you are updating from VS2003 to VS2005, C++, you might run across an error like this. What it means is that they changes the return types from 2003 to 2005. You just need to change the UINT to an LRESULT and you should be good to go.



LNK1104: cannot open file ‘LIBC.lib’

If upgrading a C++ project from VS2003 to VS2005, you might run into this error. LNK1104: cannot open file ‘LIBC.lib’

I resolved it by doing the following:

Project->Properties->Configuration Properties->Linker->Input

Ignore Specific Library: libc.lib

I guess VS2003 has there by default, from what I have been reading.