Last active
April 16, 2017 11:31
-
-
Save DBJDBJ/9d02f8dbfb0dceef372607af93eb53f2 to your computer and use it in GitHub Desktop.
C++ WINDOWS UNICODE CONSOLE OUTPUT
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
/* | |
---------------------------------------------------------------------- | |
ACTUALLY: | |
http://archives.miloush.net/michkap/archive/2008/03/18/8306597.html | |
It seems this is very wizard like method? | |
Try this simeple test and see if it crashes your console: | |
<pre> | |
#include <fcntl.h> | |
#include <io.h> | |
#include <stdio.h> | |
int main(void) { | |
_setmode(_fileno(stdout), _O_U16TEXT); | |
wprintf(L"\x043a\x043e\x0448\x043a\x0430 \x65e5\x672c\x56fd\n"); | |
// following line is very likely to crash the UCRT | |
printf(L"\x043a\x043e\x0448\x043a\x0430 \x65e5\x672c\x56fd\n"); | |
return 0; | |
} | |
</pre> | |
WARNING FROM BEFORE: | |
The following is a "hack" and shouild not be applied to the global app env. | |
It should be used inside functions in a local manner. | |
Neither "C" API or C++ stdlib, can work normaly if this is executed. | |
Probably no ANSI output will work at all. | |
---------------------------------------------------------------------- | |
*/ | |
/* | |
Copyright 2017 [email protected] | |
Licensed under the Apache License, Version 2.0 (the "License"); | |
you may not use this file except in compliance with the License. | |
You may obtain a copy of the License at | |
http ://www.apache.org/licenses/LICENSE-2.0 | |
Unless required by applicable law or agreed to in writing, software | |
distributed under the License is distributed on an "AS IS" BASIS, | |
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
See the License for the specific language governing permissions and | |
limitations under the License. | |
*/ | |
/* set to 1 if using UTF16 console output */ | |
#define DBJU16 1 | |
#define WIN32_LEAN_AND_MEAN | |
#define VC_EXTRALEAN | |
#include <Windows.h> | |
#if DBJU16 | |
#include <io.h> | |
#include <fcntl.h> | |
#endif | |
namespace dbj { | |
namespace win { | |
namespace console { | |
#if DBJU16 | |
/* | |
WIN console is not unicode U16 by default | |
thus console output of unicode string will not produce what is expected | |
For example: | |
const static std::wstring doubles = L"║═╚"; | |
const static std::wstring singles = L"│─└"; | |
std::wcout << doubles ; | |
will not work is the following low level intialisatoon of console has not been | |
performed | |
*/ | |
namespace { | |
struct __declspec(novtable) | |
UINT16CONSOLEINIT | |
{ | |
unsigned int & counter() | |
{ | |
static unsigned int counter_ = 0; | |
return counter_; | |
} | |
/* | |
If you call ::CoInitialize(NULL), after this method is used | |
most likely the HRESULT will be : | |
hRes = 0×80010106 — Cannot change thread mode after it is set. | |
*/ | |
UINT16CONSOLEINIT() | |
{ | |
const UINT & ctr = (counter())++; | |
if (0 == ctr) { | |
/* | |
To print unicode into the Windows console one has to set it to UNICODE first. | |
And then set it back so that CRT does not throw. Solution is described here | |
https://msdn.microsoft.com/en-us/library/tw4k6df8.aspx | |
*/ | |
if (EOF == fflush(stdout)) { | |
/* TODO: If fflush returns EOF, data may have been lost due to a write failure. */ | |
} | |
_setmode(_fileno(stdout), _O_U16TEXT); | |
/*TODO: log the result here*/ | |
} | |
} | |
~UINT16CONSOLEINIT() | |
{ | |
const UINT ctr = --(counter()); | |
if (ctr < 1) { | |
/* | |
apparently must do this | |
also make sure NOT to mix cout and wcout in the same executable! | |
*/ | |
if (EOF == fflush(stdout)) { | |
/* TODO: If fflush returns EOF, data may have been lost due to a write failure. */ | |
} | |
_setmode(_fileno(stdout), _O_TEXT); | |
/*TODO: log the result here*/ | |
} | |
} | |
}; | |
/* | |
WARNING! Better do not do this. | |
Probably no ANSI console output will work after this. | |
*/ | |
static const UINT16CONSOLEINIT uint16consoleinit__{}; | |
} | |
#endif // DBJU16 | |
} // console | |
} // win | |
} // dbj | |
/* | |
If problems with them, one can undef the macros defined in here | |
#undef WIN32_LEAN_AND_MEAN | |
#undef VC_EXTRALEAN | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
ACTUALLY:
http://archives.miloush.net/michkap/archive/2008/03/18/8306597.html
It seems this is very wizard like method?
Try this simeple test and see if it crashes your console: