Thursday, December 29, 2005

wxWidgets resources compile again every time you hit "Run" (F5)

Another wxWidgets related answer...

You include the wxWidgets resources in your project (wxrc.rc). Now everytime you hit 'Run' (F5) Visual Studio (7) thinks it has to rebuild some of the sources and the resources.

Create a file 'inc_wxrc.rc' with the following contents:
// Microsoft Visual C++ generated include file.
// Used by mikadoApp.rc
Do not add wx.rc to your project directly. Either add 'inc_wxrc.rc' to the project or, if you have a .rc file that includes wx.rc, include 'inc_wxrc.rc' instead.

Advertisment (for my own product):
The wxVisualSetup Project Wizard does this automatically and even add a version resource to your binary. It is available for €39.95 for Visual Studio 2002, 2003 and 2005, all versions.

Best regards


Tuesday, December 27, 2005

Compile error using XRC and Unicode (VC++ 8.0 Express)

Since I've seen this asked several times now, I'll blog the answer:

You are using wxWidgets XRC Resources and compile a Unicode application (which is default on Visual Studio 8.0 Express) and are getting an error similar to
xrcdemo.cpp:63:1: pasting "LL" and "L"UsernameField"" does not give a valid preprocessing token
xrcdemo.cpp: In member function `void LoginDialog::InitWidgetsFromXRC()':
The error is in how you are using the XRC macros. XRC macros don't accept string constants enclosed in _T(). Use string contants without _T(), even in Unicode builds.

Summary: Use _T() with XRC methods, do not use _T() with XRC macros.

Suppose you have

wxXmlResource::Get()->LoadDialog(this, NULL, _T("LoginDialog"));
UsernameField = XRCCTRL(*this, _T("UsernameField"), wxTextCtrl);

You must enclose strings in _T(), if you want to be able to compile your application in both, ANSI and Unicode builds. So LoadDialog(this, NULL, _T("LoginDialog")); is the correct way to specify 'LoginDialog' as the XRC resource.

But, the XRC macros that take a string use _T() internally already. So XRCCTRL(*this, _T("UsernameField"), wxTextCtrl) is wrong, because XRCCTRL is a macro and it adds _T() to the 'UsernameField' parameter itself. The compiler then sees something like

xrcctrl_function(*this, _T( _T("UsernameField") ), wxTextCtrl)

and prints an error.

The correct use of the XRCCTRL and similar macros is to pass in strings without _T(), even in Unicode builds.

UsernameField = XRCCTRL(*this, "UsernameField"), wxTextCtrl);

Some more background for the interested: _T() is a simple macro that simply adds the literal 'L' in front of a quoted string in Unicode builds and does nothing in ANSI builds. Unicode strings are wide-character strings (wchar_t). Wide-character string constants must be preceded by an L in C++.

"This is a char string (1byte), or ANSI string"
L"This is a wide-char string (2byte/4byte under linux), or Unicode string"

Using XRCCTRL(*this, _T("UsernameField"), wxTextCtrl) would expand to xrcctrl_function(*this, LL"UsernameField", wxTextCtrl), which is what the compiler error message says.

Best regards

Hajo Kirchhoff

P.S. Please have a look at wxVisualSetup for Visual Studio 2002/2003 or 2005 to support this blog.

Friday, December 23, 2005

wxVisualSetup for Visual Studio 2005 released

I have just released the next version of wxVisualSetup, the package that integrates the wxWidgets GUI class library into Microsofts Visual Studio IDEs. If you are using wxWidgets and Microsoft Visual Studio, you can find more information at

Thursday, December 22, 2005

Your application crashes (fails to initialise) with Visual Studio 8.0 and wxWidgets DLLs

If you are using Visual Studio 8.0 and wxWidgets DLLs and your application crashes immediately after starting or cannot be initialised properly, here is the fix:

  1. Open the file $(WXWIN)\src\msw\main.cpp
  2. Search for the function 'DllMain'
  3. Remove the entire function
  4. Recompile wxWidgets DLLs

When you open the wxWidgets .dsp files with Visual Studio 8.0, the solution conversion wizard adds the preprocessor symbol _WINDLL to the solution. This symbol is not defined when you compile the DLLs with older Visual Studios (.NET or 2003). When it is defined, the function DllMain gets compiled and included. This is causing the crash.

Monday, December 19, 2005

Upgrading your wxWidgets project to Visual Studio 8.0

Ok, so I finally found some time to start using my brand-new MS Visual Studio 2005 and try and compile my projects with it. As usual, moving to the next major version of a Microsoft Compiler involves a lot of work. Here is what I found so far:

Warnings, warnings, warnings...
The first thing you'll notice are hundreds of warnings. In an effort to make software more secure, MS has depreciated many runtime library functions that where the cause of so many buffer overflows. No more strcpy, strdup, localtime etc... Same with std::copy and other functions that are being used by the C++ standard runtime library.
I am not sure I really like this. This seems like a good idea at first, but only for new projects. For all other projects, people are probably simply going to disable the warnings. That is what I recommend when you upgrade your projects. Especially your wxWidgets projects, since the recommended replacement functions strcpy_s, localtime_c etc... are MS-specific and not found in any other compiler I know of.

So, in your project, define these macros

tell the compiler to stop complaining about using localtime etc...

stop complaining about std::copy etc...

The best place to do this is in your precompiled header file such as stdwx.h, if you have one. Of course you can add these defines to the project file itself, but you'll have to add them to all configurations.

More warnings: Microsoft also depreciated all Posix names. Did you know strcpy should actually be called _strcpy in the ISO standard? I know now. All Posix names - and there are many - have been depreciated in favor of the new ISO standard. Good idea? Probably. Someone has to make a start. But unless you are willing to spend time changing your code
and your gnu or whatever other compiler you are using supports it, you'll want to disable these warnings as well:

to stop complaining about old POSIX names

If you include the wx.rc file - which you should -, you will get an error when you compile your project with VC 8.0: invalid COFF or something. The new 8.0 linker has the ability to generate a manifest file on the fly and the .dsp/.sln conversion wizard enables this by default. So now your application has two manifest files, one included via wx.rc and the new one generated by the linker. The linker does not like this. You have two options.
  1. Define wxUSE_NO_MANIFEST to stop using the wxWidgets manifest file. You must change the file settings for your .rc file and include this define there. Using the precompiled header file as mentioned above won't work.
  2. Disable the linker|manifest option: Open the properties for your project. Select 'all configurations', open the linker settings, manifest file and set 'generate manifest' to no.
I recommend the first option as it lets the linker create a manifest with all the correct DLL side-by-side information. If you disable the linker|manifest option, a debug build may not find the MSVCP80D.DLL for example and you have to copy the DLL into your path. If the linker creates the manifest file, all the correct DLL paths are being used.