Changing Resource encoding from Windows 1252 to UNICODE UTF-8 with signatures - c++

I am working on an older project (compiled with UNICODE defined) and came across a problem within the .rc. For example, a static text element which includes “©” defined in a DIALOGEX resource by
LTEXT "Copyright ©”,IDC_COPYRIGHT_STATIC,7,154,110,8
The resource file, probably created by MSVC application wizard many years ago and migrated forward with each release, now looks like this:
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252) //present for over 10 years
#endif
For many years the © display correctly but recently appeared as “Å©” or even “½¿”. Obviously, an encoding issue, but I needed to understand how and why before making changes. So, after researching, these three properties in the .rc play a part in the bug and the encoding:
The presence or absence of “#pragma code_page(…)” in the .rc
The encoding used to Save with Encoding… the .rc file
Save with Encoding… .rc “with signature” or “without signature” (meaning BOM?)
As an empirical test, changing these things in the .rc and looking at the result text in dialogue
#pragma code_page(…)
Save with Encoding
Signature(BOM)
Text in Dlg
code_page(1252)
Original file
n/a
Å©
code_page(1252)
Windows 1252
n/a
©
code_page(1252)
UTF-8 65001
BOM
Å©
code_page(1252)
UTF-8 65001
No BOM
Å©
code_page(65001)
Windows 1252
n/a
©
code_page(65001)
UTF-8 65001
BOM
©
code_page(65001)
UTF-8 65001
No BOM
©
No code_page in .rc
UTF-8 65001
BOM
©
No code_page in .rc
UTF-8 65001
No BOM
Å©
I can explicitly Save with Encoding all .rc files encoding as Windows (1252) OR encoding as UNICODE UTF-8 with signatures (and delete the #pragma code_pages). The specific bug will go away, but is this the best solution?
It seems switching from Windows 1252 to UNICODE UTF-8 is a step forward and the right way to go long term. Is there any problem with this? Or better solutions?

Related

non-ASCII file paths Windows

I work on Windows and have file paths with non-ASCII symbols. For non-ASCII symbols windows using wstring. I am doing the conversion and pass them to luaL_dofile but it fails with can not find a file.
Here is my example of code:
std::wstring wstr_path = "non-ASCII path"
using convert_type = std::codecvt_utf8_utf16<wchar_t>;
std::wstring_convert<convert_type, wchar_t> converter;
std::string str_path = converter.to_bytes(wstr_path);
luaL_dofile(mRoot, str_path.c_str());
I know nothing about luaL_dofile, but it's rather unlikely it uses UTF-8. Windows file API for Unicode unaware programs uses the ANSI codepage (which corresponds to the system default locale). The ANSI codepage on English/US systems is 1252, but other system default locales have different codepages. Central European is 1250, Cyrillic is 1251, etc.
Also, you could try generating the short name for the file (see the GetShortPathName API) and feed that.

Making code (more) cross platform

I am trying to make my (currently working on windows) code a bit more platform independent. This small snippet is for opening a text file (for reading/writing).
As with modern pcs many files are stored as unicode. Now In this question I am especially wondering what the right way to open such a file is. (Where the filename may be unicode).
On windows, using microsoft visual studio, I used
char* filename("c:\\\xD0\x92.txt");
#ifdef _WIN32
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
#else
std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
//non windows wstring = utf8
#endif
std::wstring wfilename(converter.from_bytes(filename));
std::fstream fstream(wfilename);
However I just now realized this isn't standard C++11, instead a visual studio (only?) extension. However when I try on windows to first convert the widestring to an UTF-8 std::string and open the file that way the fstream doesn't recognize the filename.
So what is the cross platform solution? - Should I just expect std::fstream to always accept a widestring input? Or should I expect this on windows always?
And if possix systems don't use widestrings for their directories; what do they use?

fatal error RC1015

I am really new to programming for C++ and I was given the task to pick up were a previous employee left off with programming a windows mobile device. I had the emulator working the other week and now when I load the program I get:
Fatal error RC1015: cannot open include file "xxxx.h"
I have tried almost everything that I have seen on the internet without a single bit of luck. I think that one of my include statements is missing but every time I put one in that works something else breaks. Please any help will be greatly appreciated.
Here is what the .rc file says:
// Microsoft Visual C++ generated resource script.
//
#include "resourceppc.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
#include "ConnectLoginDlgsRes.h"
#include "AboutDlgRes.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resourceppc.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""afxres.h""\r\n"
"#include ""ConnectLoginDlgsRes.h""\r\n"
"#include ""AboutDlgRes.h""\r\0"
END
3 TEXTINCLUDE
BEGIN
"#define _AFX_NO_SPLITTER_RESOURCES\r\n"
"#define _AFX_NO_OLE_RESOURCES\r\n"
"#define _AFX_NO_TRACKER_RESOURCES\r\n"
"#define _AFX_NO_PROPERTY_RESOURCES\r\n"
"\r\n"
"#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
"LANGUAGE 9, 1\r\n"
"#pragma code_page(1252)\r\n"
"#include ""res\\J3ItemListsppc.rc2"" // non-Microsoft Visual C++ edited resources\r\n"
"#include ""afxres.rc"" // Standard components\r\n"
"#include ""ConnectLoginDlgs.rc""\r\n"
"#include ""AboutDlg.rc""\r\n"
"#endif\r\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDR_MAINFRAME ICON "res\\J3ItemLists.ico"
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_J3ITEMLISTS_DIALOG DIALOG 0, 0, 156, 169
STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION
EXSTYLE WS_EX_APPWINDOW | 0x80000000L
The problem is with the #include "ConnectLoginDlgsRes.h" line. The header file is in a shared folder that if it is added that it breaks somewhere else.
Any ideas? Like I said someone else started this and I get to figure it out.
Since you program for Windows Mobile we can assume that you use VS2005 or VS2008. You just need to set the search path for the resource compiler.
Lookup the missing file "ConnectLoginDlgsRes.h" and add the path in the project properties dialog. The path must be added in Configuration Properties->Resources->General. Use the "Additional Standard Include Path".
Edit:
Since your previous employee might have given you a working project you should also check the build environment. Probably you need some scripts to be executed before you can actually build the VS project.
If you are not using the resource.h file that is generated in Visual Studio. Make sure you delete the line that includes resource.h from [Solution]->[Project]->Resource Files->app.rc.
In your case this is the line:
'#include "resourceppc.h"'
I solved l error RC1015 using and running the vcvars32.bat file in command line environment which is found in the bin directory under the VC installation directory.or use everything tool to find it. It's limited to setting the appropriate environment variables to enable 32-bit x86 command-line builds. It's the equivalent of the vcvarsall x86 command.
https://msdn.microsoft.com/en-us/library/f2ccy3wt.aspx?f=255&MSPPError=-2147217396

LoadString(AFX_IDP_PARSE_INT) fails in an mfc exe (not in a dll)

AFX_IDP_PARSE_INT is the id for a standard MFC error message (it's defined in afxres.h), but in my project it fails to load, meaning that LoadString returns FALSE, GetLastError returns ERROR_RESOURCE_NAME_NOT_FOUND, and CString stays empty.
This happens even when I try loading it at the beginning of InitInstanse:
BOOL CMyLegacyProject::InitInstance()
{
CString string;
if (!string.LoadString(AFX_IDP_PARSE_INT))
AfxMessageBox(_T("Failed."));
}
This same code works on a new project, however - same linking of MFC (I link to it statically), same WINVER, I've tried making it as similar as my old project, but I can't reproduce the error on a newly started project.
It looks like your resources are not building correctly. Make sure your .rc file includes all the AFX resources as well. First I'd try building a brand new project from scratch, test loading the string in that, and then have a look to see what the default .rc file looks like.
It should be including a file called 'afxres.rc', ie your RC should have something like this in it:
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE 9, 1
#pragma code_page(1252)
#endif //_WIN32
#include "res\MyRes.rc2" // non-Microsoft Visual C++ edited resources
#include "afxres.rc" // Standard components
#include "afxprint.rc" // printing/print preview resources
#endif

How to Increment Visual Studio build number using C++?

I have a Visual Studio 2008 project that produces a file called: "Game-Release.exe".
This was configured under Project Properties -> C/C++ -> Linker -> General:
$(OutDir)\$(ProjectName)-Release.exe
I would like to take this a bit further by have an incrementing build number so I would have something which says:
Game-Release-Build-1002.exe
The number on the end should be an incrementing integer. I will be storing the build exe's on subversion so I think i would find this useful (although not necessary).
Perhaps there is a built in macro in Visual Studio that could handle this. Quite possibly I was thinking I could have a text file with the build number in it and have the compiler read, use and increment the number in the file each time the project is built. My goal is however to make the process as automated as possible. What is the best way to accomplish this?
If you offer an opinion, please also provide the code we can all share. Thnx.
The Versioning Controlled Build add-in seems like it would do the job.
Update: Your question specifically mentions using Visual Studio to increment the version, but there is nothing automated about that. Have you considered using Nant and a CI server? That way, it is easy to inject the SVN revision number into AssemblyInfo.cs equivalent for C++. Automatically, on the build server.
If you are using svn to version your project you could follow the instructions in this link it works perfectly for me because I can track bugs in a release application using its version information and comparing the source code.
All information below is not included in the link:
setup your rc file like this version.rc
#include "resource.h"
#include "version.h" //<-----------Don't forget the include
/////////////////////////////////////////////////////////////////////////////
//
// Version.rc
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION VER_FILE_VERSION
PRODUCTVERSION VER_PRODUCT_VERSION
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040704b0"
BEGIN
VALUE "CompanyName", "Your Company Name"
VALUE "FileDescription", "Your Application Description"
VALUE "FileVersion", VER_FILE_VERSION_STR "\0"
VALUE "InternalName", "Internal Name"
VALUE "LegalCopyright", "CopyRight stuff - Copyright (C) 2015"
VALUE "OriginalFilename", "yourapp.exe"
VALUE "ProductName", "Your Application"
VALUE "ProductVersion", VER_PRODUCT_VERSION_STR "\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x407, 1200
END
END
Next add version.h file to your project which defines everything, setup like this:
#include "svn_version.h"
#define STRINGIZE2(s) #s
#define STRINGIZE(s) STRINGIZE2(s)
#define VERSION_MAJOR 1
#define VERSION_MINOR 0
#define VERSION_REVISION SVN_REVISION
#define VERSION_BUILD 0
#if SVN_LOCAL_MODIFICATIONS
#define VERSION_MODIFIER "M"
#else
#define VERSION_MODIFIER
#endif
#define VER_FILE_VERSION VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION, VERSION_BUILD
#define VER_FILE_VERSION_STR STRINGIZE(VERSION_MAJOR) \
"." STRINGIZE(VERSION_MINOR) \
"." STRINGIZE(VERSION_REVISION) \
"." STRINGIZE(VERSION_BUILD) \
#define VER_PRODUCT_VERSION VER_FILE_VERSION
#define VER_PRODUCT_VERSION_STR VER_FILE_VERSION_STR
after this you can follow the link above.
I'm not sure VS2008 has that feature but I think you can do it with a post-linker event that runs a little script that make the task for you.
I use a pre-build script (written in JavaScript and executed using the cscript.exe engine) that defines the major/minor release, gets the SVN revision number and generates a magic build number based on the current date. The script then creates a version.h file that is used by the main application (and by the main apps resource file to create a VERSION resource).
My own approach, including binary file stamping:
http://indiocolifax86.wordpress.com/2010/05/22/a-scheme-for-automatic-build-numbers-in-cc-projects/