Tired, overused metaphors, a.k.a. Two rails forward, one rail back!

by Michael S. Kaplan, published on 2007/01/16 06:01 -05:00, original URI: http://blogs.msdn.com/b/michkap/archive/2007/01/16/1476857.aspx


Remember when I talked about how The Unicode train is leaving the station? and how I talked about the Unicode default

Well, not to overtax a metaphor, but pointing out the two cool "rails" in that post ("by default" Unicode projects in C++, a resource editor that can support Unicode), there is at least one rail that kind of keeps the train from moving too far ahead,one that Mihai pointed out the other day in the Suggestion Box:

Fire up VS 2005, and start a new Visual C++ project (Win32/Win32 Project, or MFC/MFC Application, it does not matter).

Add a dialog to the project, or you can use the already existing About box, good enough.

(btw, why the About dialog uses "System" font, and all the others go with "MS Shell Dlg"? :-)

Experiment number 1:

Add a RichEdit 2.0 control to the dialog, and then save.

Open the .rc file in Notepad (or open it in VS as Source Code).

The RichEdit control has the "RichEdit20A" class!

Change it to "RichEdit20W" (because we want Unicode!), and save.

Now open it again the VS Resource editor, change something and save. Check the .rc file again, "RichEdit20A" is back!

Experiment number 2:

Add a custom control to the dialog, and set the class of the custom control to RichEdit20W. Save .rc.

Close project, open project, change something in the dialog and save .rc. Open in Notepad, "RichEdit20A" is back!

Experiment number 3:

No more hope in using the generic version, so that I can build both Unicode and ANSI versions of my application:

- add #include "Richedit.h" to the rc file
- in the custom control set the class to RICHEDIT_CLASS (defined in Richedit.h as RICHEDIT_CLASSW or RICHEDIT_CLASSA)
- save file, open in Notepad, "RichEdit20A" is back!

So, is there a way to get a Unicode RichEdit control without loosing it every time we edit the file in Visual Studio? And is there a way to stop the VS Resource Editor from trying to be smart, and just do what I tell it to do, because I know better?

Sadly, it looks like this "little" Unicode scenario was missed. The only way I could avoid it was to not use the VS Resource Editor. Maybe there is a template for the control and its code somewhere that could be updated?

This will require a little investigation....

 

This post brought to you by  (U+098a, a.k.a. BENGALI LETTER UU)


# Roger Lipscombe on 16 Jan 2007 6:42 AM:

Yeah, I ran into this problem when writing the Rio Music Manager program (using Visual Studio 2003).

In the end, we had a custom step that replaced RC.EXE, and preprocessed the .RC file to fix this specific case up. This wasn't a big deal for us, since we already wanted to do some other preprocessing (although I don't recall what).

# jonathan wilson on 16 Jan 2007 10:44 AM:

If there isnt one already, someone should file a bug in the visual C++ bug database so that it can get looked at (and hopefully fixed :)

# Michael S. Kaplan on 16 Jan 2007 11:25 AM:

Of course, look how they have "fixed" this sort of bug in the past like if you added strings to a form's RESX file and they were wiped out when you modified the form. The fix was to warn you when you tried to add/modify strings in the RESX.....

The fear here is that they would fix this the same way and warn you about modifying the resource. :-(

# Mihai on 16 Jan 2007 2:31 PM:

It looks like the thing is hard-coded in %VSDir%\VC\vcpackages\resedit.dll

There is one instance only, Unicode. Changing that instance fixes the problem.

There are also hard-coded things that will break the wizards (in %VSDir%\VC\VCWizards\CodeWiz\MFC\Variable\HTML\1033\default.htm

%VSDir%\VC\VCWizards\CodeWiz\MFC\Variable\Scripts\1033\default.js)

But, as I said, changing that is not a solution:

- is probably not legal to hex-edit MS files :-)

- not portable

- will break the ANSI projects

# Mihai on 17 Jan 2007 12:08 PM:

Ok, I have something relatively clean for MFC, trying to come with something at least half decent for pure Win32.

Then I will put together an article and post the code.

(idea: change the dialog template in memory :-)

# Michael S. Kaplan on 17 Jan 2007 8:04 PM:

Hmmm... which versions are you going to target?

# Mihai on 17 Jan 2007 8:26 PM:

<<Hmmm... which versions are you going to target?>>

What I have now works on MFC 8.0, but does not use MFC for the implementation itself. One just needs to override the DoModal method of the CDialog derived class.

The goal was to be as non-disruptive as possible: "include this header, add DoModal to your class, call this function inside your DoModal, then call the original."

But the function itself does not use MFC at all, so it should work on any MFC version.

I want something as clean for plain Win32 API, "just replace DialogBox[Indirect][Param] with this X"

If by version you mean "dialog memory template version" then the 32 bit version, both DIALOG and DIALOGEX

(only the Ex version is ready now, but working on it)

Although now I have second thoughts: the structure is not quite officially documented, might change at any time, etc. :-) Changing resources in memory might even break in Vista (http://blogs.msdn.com/oldnewthing/archive/2007/01/08/1434501.aspx :-)

# Andre on 5 Feb 2007 3:28 AM:

I just want to say Hello to Roger, see you on the empeg BBS :-)

# Paul Sanders on 23 Nov 2007 10:50 AM:

Hi there,

I have a clean and tidy solution for the 'RichEdit20A' problem.  I add a 'pre-build' event to my project to run the following batch file (tested on VS 2005 SP1):

--------------------------------------------
@echo off
echo Convert Richedit20A to RichEdit20W in .rc file...
gawk -f richedit20w.awk <VinylStudio.rc >xxx
if errorlevel 1 goto move
echo No changes made
goto end
:move
move xxx VinylStudio.rc
echo VinylStudio.rc updated
:end

--------------------------------------------

And file richedit20w.awk looks like this:

--------------------------------------------
# Replace RICHEDIT20A with RICHEDIT20W, if found
/"RichEdit20A"/ {
   sub (/"RichEdit20A"/, "\"Richedit20W\"")
   ++changes
}

// {
   print
}

END {
   if (changes > 0)
       exit (1)
}

--------------------------------------------

You will also need a copy of GAWK.EXE somewhere in your path.  You can get it from here:

http://gnuwin32.sourceforge.net/packages/gawk.htm

Hope this helps.  It's certainly helping me!

Regards,
Paul Sanders
AlpineSoft
http://www.alpinesoft.co.uk


referenced by

2007/03/16 A way better model for features

go to newer or older post, or back to index or month or day