メニューのオーナードローをした時、どうしても制御できないのがメニューのボーダ部分とサブメニューの▶の部分
いろいろ調べて▶の部分が制御ができるようになった。
オーナードローをしても、枠の灰色の線とSubの隣の▶の色が環境依存で、指定が出来ない。
▶については、通常黒で、選択すると反転して白になる。
左図のような黒背景だと▶が見えない。
DrawItemイベントでは描画しておらず、その後に勝手に描画されるからSetTextColorとか適用されないかな?と思ったけど無視される。
やり方は、ExcludeClipRectでメニュー項目全体をクリップすると、勝手に描画されるのを抑制できるので、あとは自分で描画するだけ。
通常状態でも白で表示出来るようになった。
2017年7月19日水曜日
2017年5月16日火曜日
VS2017のAllocConsoleでUnicode(UTF-16)出力
std::wcout.imbue(std::locale("Japanese")) ;
AllocConsole() ;
FILE * pF = _wfdopen( h, L"w" ) ;
fclose( stdout ) ;
*stdout = *pF;
setvbuf( stdout, NULL, _IONBF, 0 ) ;
AllocConsole() ;
FILE * pF = _wfdopen( h, L"w" ) ;
fclose( stdout ) ;
*stdout = *pF;
setvbuf( stdout, NULL, _IONBF, 0 ) ;
VS2010では上記のコードで、wcout、wprintfを使ってコンソール出力が出来た。
VS2017でコンパイルすると、コンパイルは通るが実行すると落ちる。
いろいろ調べてみた結果、_wfreopen(freopen)でstdoutを"CONOUT$"で開き直すとコンソールと紐付けは出来るようだ。
でも、printfすると落ちる。
wprintfすると表示されなかったり、表示されるが16進文字だったり、文字化けしていたり。
wcoutは日本語は表示されるが、"\n"、endlの部分で落ちる。
coutはやってない。
唯一、表示されるのがWriteConsole関数。
試してみたのは下記のキーワード
wcout.imbue
_wsetlocale(setlocale)
setvbuf
_setmode
wcout.rdbuf
SetConsoleOutputCP
sync_with_stdio
どうやってもまともに表示されない。
色々やっているとwcoutで落ちるのは、rdbufが準備できていない?感じで、rdbufを入れ替える方法を見つけたのでwcout以外は全部捨てて対応したコードが下記。
class Out {
private :
class Buf : public std::wstreambuf {
private :
HANDLE h ;
public :
virtual int_type overflow( int_type c = EOF ) override {
if( c == EOF ) return c ;
wchar_t sBuf[] = { c, '\0' } ;
DWORD nW ;
WriteConsole( this->h, sBuf, 1, &nW, NULL ) ;
return c ;
}
Buf( void ) {
this->h = GetStdHandle( STD_OUTPUT_HANDLE ) ;
}
} oBuf ;
std::wstreambuf * pOld ;
public:
Out( void ) { this->pOld = std::wcout.rdbuf( &oBuf ) ; }
~Out( void ) { std::wcout.rdbuf( this->pOld ) ; }
} ;
private :
class Buf : public std::wstreambuf {
private :
HANDLE h ;
public :
virtual int_type overflow( int_type c = EOF ) override {
if( c == EOF ) return c ;
wchar_t sBuf[] = { c, '\0' } ;
DWORD nW ;
WriteConsole( this->h, sBuf, 1, &nW, NULL ) ;
return c ;
}
Buf( void ) {
this->h = GetStdHandle( STD_OUTPUT_HANDLE ) ;
}
} oBuf ;
std::wstreambuf * pOld ;
public:
Out( void ) { this->pOld = std::wcout.rdbuf( &oBuf ) ; }
~Out( void ) { std::wcout.rdbuf( this->pOld ) ; }
} ;
AllocConsoleした後に、Outクラスのインスタンスを作ると、wcoutのバッファがoverflow関数に1文字ずつ渡ってくるらしい。内部では唯一まともに動くWriteConsoleを呼び出す。
登録:
コメント (Atom)

