CString Format problem and differences in Windows XP and 7? - c++

There is a problem, below code works for Windows 7 and not for Windows XP? By any chance, do you know the reason for that? Thanks in advance. I have checked that it is not a DB error.
For Win 7 it returns what is stored, also the same case for Win XP. But, Formatting in XP sets CString as "".
if(getDB()->getEncoding() == IDatabase::UTF8){
a_value.Format(_T("%s"), sqlite3_column_text(getCommand()->getStatement(), idx));
}else{
a_value.Format(_T("%s"), sqlite3_column_text16(getCommand()->getStatement(), idx));
}
Also, we are sure that it is not a unicode issue.

This really doesn't appear to be a Windows issue. Are you sure you're not doing different builds between the version that works and the one that doesn't?
The code above is problematic because if you do a Unicode build, sqlite3_column_text() will return the wrong type of string. For Unicode builds, you'd want sqlite3_column_text16() instead.

check if character set configured during compilation is the same on the two platform
unicode
or
multibyte
maybe it helps, bye

Related

OleCreate fails with E_CLASSNOTREG when compiled with 64-Bit (C++)

I am trying to display a new Word document inside a Widget, using OLE. This works fine as long as I compile my application under x86 architecture. Now I tried porting my application to x64 and it stopped working. The call to OleCreate() fails with REGDB_E_CLASSNOTREG.
CLSID clsID;
IUnknown* pIUnknown;
HRESULT res = CLSIDFromProgID(L"Word.Document.8", &clsID);
if (SUCCEEDED(res)) {
res = OleCreate(clsID, IID_IUnknown, OLERENDER_DRAW, NULL, NULL, storage, reinterpret_cast<void**>(&pIUnknown));
}
After some research I came across some solutions, but none of them were applicable.
I can't set my compiler to x86 when I'm trying to port my application to x64 so following Post hasn't solved my problem.
I tried calling regsvr32.exe withC:\Windows\System32\ole32.dll but it didn't change the result.
I tried installing the hotpatch, which was shipped by microsoft to fix the same problem with OleCreateFromFile(). Sadly it doesn't fix the problem for OleCreate() - hotfix
The only solution, which worked so far was to copy the content of HKLM\SOFTWARE\SysWow64\Classes\CLSID\<CLSID of Word Document> into HKLM\SOFTWARE\Classes\CLSID\<CLSID of Word Document> but this is more of a hack than a fix, because I would have to modify the registry of every machine on which I want to run my application. Since this task requires administrator privileges, I can't do this from inside my application.
I need a solution which works and doesn't force me to manually alter registry entries.
I'm running my application on a Windows 7 Professional SP1 64-Bit machine with a 32-Bit Office 2010.
After some more testing I found the solution to the problem, which was to use Word.Document instead of Word.Document.8 as progID.
I have don't know why this seems to be a problem with 64-Bit compilation. The thing, I noticed though was that CLSIDFromProgID() now resolves to a different CLSID.

Change Console Code Page in Windows C++

I'm trying to output UTF8 characters in the Windows command line. I can't seem to get the function, setConsoleOutputCP to work. I also heard that you had to change the font to "Lucida Grande" for it to work but I can't get that working either. Can someone please provide me with a short example of how to use these functions to correctly output UTF-8 characters to the console?
Also I heard that those functions don't work in Windows XP, is there a better alternative to those functions which will work in Windows XP?
[I know this question is old and was about Windows XP, but it still seemed like a good place to drop this information so I (and maybe others) can find it again in the future.]
Support for Unicode in CMD windows has improved in newer versions of Windows. This program will work on Windows 10.
#include <iostream>
#include <Windows.h>
class UTF8CodePage {
public:
UTF8CodePage() : m_old_code_page(::GetConsoleOutputCP()) {
::SetConsoleOutputCP(CP_UTF8);
}
~UTF8CodePage() { ::SetConsoleOutputCP(m_old_code_page); }
private:
UINT m_old_code_page;
};
int main() {
UTF8CodePage use_utf8;
const char *text = u8"This text is in UTF-8. ¡Olé! 佻\n";
std::cout << text;
return 0;
}
I made an RAII class to ensure the code page is restored because it would be rude to leave the code page changed if the user had purposely selected a specific one. All the Windows-specific code (SetConsoleOutputCP) is contained within that class. The definition of the use_utf8 variable in main changes the code page to UTF-8, and that code page will stay in effect until the variable is destructed at the end of the scope.
Note that I used the u8 prefix on the string literal, which is a newer feature of C++ to ensure that the string is encoded using UTF-8 regardless of the encoding used for the source file. You don't have to use that feature if you have another way to make a string of valid UTF-8 text.
You still have to be sure that the CMD window is using a font that supports the glyphs you need. I don't think there's a way to get font linking automatically.
But this will at least show a the replacement character if the font is missing the glyph. For example, on my window, the ¡Olé! looks right but the CJK glyph is shown approximately like �. If the user copies that replacement character, the clipboard will receive the original glyph, so they can paste it into other programs without any loss of fidelity.
Note that command line parameters you get from main's argv will be in the original code page. One way to work around this is to get the unconverted "wide" command line with GetCommandLineW, convert it to UTF-8 with WideToMultibyte, and then parse it yourself. Alternatively, you can pass the result of GetCommandLineW to CommandLineToArgvW, which will parse it, and then you'd convert each argument to UTF-8.
Finally, note that changing the code page affects only the output. If you input text from the user, it arrives encoded using the original code page (often called the OEM code page).
TODO: Figure out input. SetConsoleCP isn't doing what I think the documentation says it should do.
Windows console doesn't play nice with UNICODE and particularly with UTF-8.
Setting a console code page to utf-8 won't work.
One approach is to use WideCharToMultiByte() (or something else) to convert the text to UTF-16, then MultiByteToWideChar() (or something else) to convert to a localised ISO encoding. The set the console code page to the ISO code page.
Its ugly, but it sort of works.
In short: SetConsoleOutputCP CP_UTF8 and cout/wcout dont work together by default.
Though windows CRT supports utf-8 output, a robust way to output to console utf-8 chars is to convert them into a console current codepage, especially if you want to use count/wcout.
Standard high level functions of basic_ostream does not work properly with utf-8 by default.
I've seen usage of MultiByteToWideChar and WideCharToMultiByte with CP_OEMCP and CP_UTF8 parameters.
You may setup your application environment, including console font via SetCurrentConsoleFontEx but it works only from Vista and Server 2008.
Also, check this about cout and console.
_setmode and wprintf works together as well, but this may lead to crash for non-wide char functions.
The problem occurs because there is a difference of codepage that uses windows in your console with the encoding of your source code text file.
Qt uses utf-8 by default, but another editor can use another one. So you must to verify which one you're using.
To change to utf-8 use:
#include <windows.h>
SetConsoleOutputCP(CP_UTF8);

Is Win32_PerfFormattedData_PerfDisk_PhysicalDisk missing from WMI in Vista?

From what I understand, the output from the following script should include "Win32_PerfRawData_PerfDisk_PhysicalDisk" in Windows XP and higher, but it doesn't for me in Vista Business 32-bit Service Pack 2. Thus far I have been very unsuccessful googling for information about this performance class.
strComputer = "."
Set objWMIService=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _
strComputer & "\root\cimv2")
For Each objclass in objWMIService.SubclassesOf()
Wscript.Echo objClass.Path_.Class
Next
Does this WMI class simply not exist in Vista? If it is just me, is there a way to fix WMI? I have already tried running winmgmt /resetrepository and winmgmt /resyncperf and neither helps.
Edit: Sorted and Edited Output
snip...
Win32_PerfFormattedData_NETFramework_NETCLRSecurity
Win32_PerfFormattedData_Outlook_Outlook
Win32_PerfFormattedData_PerfNet_Browser
Win32_PerfFormattedData_PerfNet_Redirector
snip...
Win32_PerfFormattedData_PerfDisk_* is missing.
Also tried lodctr /R. No help.
SOLVED
These counters can be disabled in the registry. Just set HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Perfdisk\Performance\Disable Performance Counters to 0 and reboot.
http://blogs.technet.com/askperf/archive/2010/03/05/two-minute-drill-disabled-performance-counters-and-exctrlst-exe.aspx
Should be okay on Vista. the docs here state at the bottom of the page:
DLL: Wmicookr.dll on Windows Server 2003 and Windows XP, WmiPerfInst.dll on Windows Server 2008 and Windows Vista.
Can you check that the WmiPerfInst.dll DLL exists on your box?
Another things to try is to see if you can get stats from the corresponding RawData class? Vista appears to have changed the way in which raw data is translated to cooked data. My knowledge of that is pretty thin (based on a very cursory Google search) since I'm only involved in WMI on XP/Svr2k3/Svr2k8 - I didn't think anyone was actually using Vista :-)
And, if you're going to accept my answer even though it didn't help, at least let me plagiarise your solution :-)
These counters can be disabled in the registry. Just set HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Perfdisk\Performance\Disable Performance Counters to 0 and reboot.
But seriously, thanks for that. At some point, we'll probably have to support post-Vista ourselves so it'll help us out to know this.

function to return the windows installed drive?

i would like to know the function which returns the drive where the windows has been installed.
for example
if we run a program with following code in windows which is installed in "C:\"
temp_char = getWindowsInstalledDrive();
should return "C:\".
please point me to that function if you know. it should be a C/C++ function.
Thanks.
You can use GetSystemDirectory(): http://msdn.microsoft.com/en-us/library/ms724373%28VS.85%29.aspx and then take the first 3 letters.
Use GetWindowsDirectory, and then extract the drive from the first three characters. This function is described as "legacy" in the help, but should work on all existing Windows versions.

Unexpected output of std::wcout << L"élève"; in Windows Shell

While testing some functions to convert strings between wchar_t and utf8 I met the following weird result with Visual C++ express 2008
std::wcout << L"élève" << std::endl;
prints out "ÚlÞve:" which is obviously not what is expected.
This is obviously a bug. How can that be ? How am I suppose to deal with such "feature" ?
The C++ compiler does not support Unicode in code files. You have to replace those characters with their escaped versions instead.
Try this:
std::wcout << L"\x00E9l\x00E8ve" << std::endl;
Also, your console must support Unicode as well.
UPDATE:
It's not going to produce the desired output in your console, because the console does not support Unicode.
I found these related questions with useful answers
Is there a Windows command shell that will display Unicode characters?
How can I embed unicode string constants in a source file?
You might also want to take a look at this question. It shows how you can actually hard-code unicode characters into files using some compilers (I'm not sure what the options would be got MSVC).
This is obviously a bug. How can that be?
While other operating systems have dispensed with legacy character encodings and switched to UTF-8, Windows uses two legacy encodings: An "OEM" code page (used at the command prompt) and an "ANSI" code page (used by the GUI).
Your C++ source file is in ANSI code page 1252 (or possibly 1254, 1256, or 1258), but your console is interpreting it as OEM code page 850.
You IDE and the compiler use the ANSI code page.
The console uses the OEM code page.
It also matter what are you doing with those conversion functions.