WIN32,VISUAL C++2005にて開発。ExtTextOut関数を実行すると文字化けする。原因と解決策を教えてください。

このQ&Aのポイント
  • WIN32初心者が開発中のプログラムにて、ExtTextOut関数を使用すると文字化けが発生します。特に、ウィンドウの背景色と同じ色に設定しようとすると文字化けが起きます。
  • 原因としては、文字列の描画前に背景色を指定するため、文字列の描画には使用されていなかった背景色が指定されてしまい、文字化けが生じることがあります。
  • 解決策としては、文字列の描画前に背景色を取得し、その背景色を使用するように変更することです。これにより、文字列の描画時には正しい背景色が使用され、文字化けが解消されます。
回答を見る
  • ベストアンサー

ExtTextOut

WIN32,VISUAL C++2005にて開発してます。 下記のプログラムを実行すると文字化けします。 原因と解決策を教えてください。 ウィンドウの背景色と同じ色にしようとすると文字化けします。 WIN32初心者なので出来るだけ分かりやすくお願いします。 case WM_PAINT: HDC hdc; PAINTSTRUCT paint; wchar_t *str = L"Ver***byKKK"; COLORREF sCOLOR = SetBkColor(hdc,GetBkColor(hdc)); hdc = BeginPaint(hWnd, &paint); ExtTextOut(hdc,120,225,sCOLOR,NULL,(LPCTSTR)str, wcslen(str),NULL); EndPaint(hWnd, &paint); break;

質問者が選んだベストアンサー

  • ベストアンサー
  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.1

MSDNより >BOOL ExtTextOut( > HDC hdc, // デバイスコンテキストのハンドル > int X, // 開始位置(基準点)の x 座標 > int Y, // 開始位置(基準点)の y 座標 > UINT fuOptions, // 長方形領域の使い方のオプション > CONST RECT *lprc, // 長方形領域の入った構造体へのポインタ > LPCTSTR lpString, // 文字列 > UINT cbCount, // 文字数 > CONST INT *lpDx // 文字間隔の入った配列 >); 第4引数はCOLORREF型ではないようですが…警告でなかったのでしょうか? > COLORREF sCOLOR = SetBkColor(hdc,GetBkColor(hdc)); この時点ではhdcは不定値のようですがエラーチェックなどは行わなくてよいのでしょうか?

glee_sss
質問者

お礼

回答ありがとうございます。 下記の記述でうまく行きました。 SetBkColorは変数に入れたりしなくてもいいみたいでした。 case WM_PAINT: HDC hdc; PAINTSTRUCT ps; wchar_t *str = L"Ver *** by KKK"; hdc = BeginPaint(hWnd, &ps); SetBkColor(hdc,RGB( 255, 128, 255 )); ExtTextOut(hdc,120,240,ETO_OPAQUE,NULL,(LPCTSTR)str, wcslen(str),NULL); EndPaint(hWnd, &ps); break;

その他の回答 (1)

  • php504
  • ベストアンサー率42% (926/2160)
回答No.2

wchar_tを表示するのなら ExtTextOutW( )を使った方がいいと思いますよ 又は LPCTSTR str = _T("Ver***byKKK"); してマルチバイトでもユニコードでもコンパイルできるようにした方がいいと思います。

glee_sss
質問者

お礼

回答ありがとうございます。 下記の記述でうまく行きました。 SetBkColorは変数に入れたりしなくてもいいみたいでした。 case WM_PAINT: HDC hdc; PAINTSTRUCT ps; wchar_t *str = L"Ver *** by KKK"; hdc = BeginPaint(hWnd, &ps); SetBkColor(hdc,RGB( 255, 128, 255 )); ExtTextOut(hdc,120,240,ETO_OPAQUE,NULL,(LPCTSTR)str, wcslen(str),NULL); EndPaint(hWnd, &ps); break;

関連するQ&A

  • TextOut( ) が動かない

    LRESULT CALLBACK WndProc( HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam){ PAINTSTRUCT ps; HDC hdc; switch(msg){ case WM_KEYDOWN:  if( wParam == VK_ESCAPE ){   hdc = BeginPaint(hWnd, &ps);   TextOut(hdc,0,0,str,strlen(str));   EndPaint(hWnd, &ps);  }  break; case WM_PAINT:  break; エスケープキーで文字表示をやりたいけど TextOut( ) が動作していないみたいでした。 switch(msg){ case WM_KEYDOWN:  if( wParam == VK_ESCAPE ){   hdc = BeginPaint(hWnd, &ps);   TextOut(hdc,0,0,str,strlen(str));   EndPaint(hWnd, &ps);  }  break; case WM_PAINT:  hdc = BeginPaint(hWnd, &ps);  TextOut(hdc,0,0,str,strlen(str));  EndPaint(hWnd, &ps);  break; とすると、常に文字が表示されたから、やっぱり case WM_KEYDOWN: の中の TextOut( ) が 動作していないんだと思いました。 TextOut( ) は case WM_PAINT: からのつながりが ある場合でないと実行されないんですか? ソースのおかしいところがあったら教えてください。

  • WinAPIでRECT構造体の宣言について

    PAINTSTRUCT ps; HDC hdc; RECT rct={200,200,200,200}; char *szStr = "あけまして\n\tおめでとう"; switch (msg) { case WM_PAINT: GetClientRect(hWnd, &rct); hdc = BeginPaint(hWnd, &ps); DrawText(hdc, (LPCTSTR)szStr, -1, &rct, DT_CENTER | DT_WORDBREAK); EndPaint(hWnd, &ps); break; のようにしているのですが文字列が表示される場所が中央上部です。 何故なのでしょう? 自分としてはど真ん中辺りから表示されるようにしているつもりなのですが

  • TextOut( ) を BeginPaint( ) と GetDC( )

    LRESULT CALLBACK の case WM_PAINT: で、 hdc = BeginPaint(hWnd, &ps); TextOut(hdc,0,0,str,strlen(str)); EndPaint(hWnd, &ps); ↑問題無し。↓文字がちらつく。 hdc = GetDC(hWnd); TextOut(hdc,0,0,str,strlen(str)); ReleaseDC(hWnd,hdc); ちらつきの原因は、高速で TextOut( ) が繰り返されるから だと思いました。 どうして TextOut( ) が繰り返されるんですか? 上の方法の場合は、 ReleaseDC(hWnd,hdc); は書かなくてもいいですか?

  • WM_PAINT

    WM_PAINT について教えてほしいのですが、 WM_PAINTがシステムから発行されるタイミングとして、 クライアント領域に無効領域がある時 UpdateWindow()を呼び出した時 InvalidateRect()を呼び出した時があると思いますが 例えば LRESULT CALLBACK WndProc(HWND , UINT , WPARAM , LPARAM) { LPCTSTR  Str = TEXT("Kitty"); switch (msg) { case WM_CREATE:    hdc = GetDC(hwnd);    SetTextColor(hdc , RGB(255, 0 , 0));    ReleaseDC(hwnd , hdc);    return 0; case WM_PAINT:    hdc = BeginPaint(hwnd , &ps);    TextOut(hdc, 10 , 10 , Str, lstrlen(Str));    EndPaint(hwnd , &ps);    return 0; } return DefWindowProc(hwnd , msg , wp , lp); } の場合, WM_PAINTはどのタイミングでシステムから呼び出されるんですか? WinMain()でUpdateWindow()もInvalidateRect()もつかっていないのですが。 いつシステムから送られるかご教授をお願いします。

  • SDKでウィンドウの中央に文字列を表示させる方法

    ウィンドウの中央に文字列sを表示させる方法を教えて下さい。 /********************************** WM_PAINTで TCHAR s[80]; HDC hDC; PAINTSTRUCT ps; RECT rc; GetClientRect(hWnd, &rc); hDC = BeginPaint(hWnd, &ps); TextOut(hDC, rc.right / 2, rc.bottom / 2, tcDayTime, lstrlen(s)); EndPaint(hWnd, &ps); return FALSE; ***********************************/ GetClientRect(hWnd, &rc);でウィンドウのサイズを取得し、 TextOutの第2、第3引数で ウィンドウ幅/2、ウィンドウ高さ/2 としていますが、これだと中央から表示されてしまいます。 できれば、ウィンドウのサイズを変更してもウィンドウの中央に表示させたいです。 #VC ++ 6.0 & Win98 & SDK で作成してます。

  • TextOutについて

    ウィンドウの雛形に、 case WM_PAINT:{ static int t; PAINTSTRUCT ps; char cbuf[100]; HDC hdc = BeginPaint( hWnd, &ps ); wsprintf( cbuf, _T("on WM_PAINT%d"),t); TextOut(hdc,0,100,cbuf,sizeof(cbuf)); SetWindowText( hWnd, cbuf ); t++; EndPaint( hWnd, &ps ); break; } として実行したところ、ウィンドウを任意のところに重ねて、移動すると、SetWindowはタイトルバーにちゃんとの値が表示されるのですが、TextOutのtは再描画されないのですが、通っているのに描画されないのはなぜでしょうか?

  • ダブルバッファの作り方

    画面に描画するBCC5.5 のCプログラムがあります。画面がちらつくので、ダブルバッファにしたいのですが、具体的に、どの関数を呼んで実装したらよいのかわかりません。WEB検索をしますと結構情報がヒットしますが、解決に至ってませんので、よろしくお願いします。 具体的にやったことは、現在動いているプログラムの case WM_PAINT:  hdc=BeginPaint(hWnd,&ps);  paint(hdc); // 自作の描画プログラム本体  ReleaseDC(hWnd,hdc);  EndPaint(hWnd,&ps);  break; の部分を、「画面サイズのビットマップイメージhBitmapをつくり、そこにpaint関数で描き込み、最終画面を一気に出力する」というつもりで以下のプログラムに書き換えたのですが、表示すらしなくなってしまいました。何が悪いのかお教えください。 case WM_PAINT:  GetClientRect(hWnd,&rt);   h = (int)rt.bottom;   w = (int)rt.right;  hBuffer = CreateCompatibleDC(NULL);  hBitmap = CreateCompatibleBitmap(hBuffer, w, h);  SelectObject(hBuffer, hBitmap);  paint(hBuffer);  hdc=BeginPaint(hWnd,&ps);   BitBlt(hdc, 0,0,w,h, hBuffer,0,0, SRCCOPY);  ReleaseDC(hWnd,hdc);  EndPaint(hWnd,&ps);  DeleteDC(hBuffer);  DeleteObject(hBitmap);  break;

  • 色描画

    以下は、ウインドウプロシージャ内でのプログラムです。 RGB( )ですが、0xFFは、255の事ですよね? x*0xFF/rect.rightこの計算式は、何を求めているんですか? 教えてください。 HDC         hdc; PAINTSTRUCT  ps; COLORREF    color; LONG        x,y; RECT        rect; switch(umsg){   case  WM_PAINT:       hdc =BeginPaint(hwnd,&ps);       GetClientRect(hwnd,&rect);       for(y=0;y<rect.bottom;y++){          for(x=0;x<rect.right;x++){            color=RGB(x*0xFF/rect.right,0,0);            SetPixel(hdc,x,y,color);          }       }

  • CTreeCtrlのCreate関数でエラーになります。

    Visual C++ .NET Win32 プロジェクト で、アプリケーションを作成しようと思っています。 #include<afxwin.h> #include<afxcmn.h> // マルチスレッド CTreeCtrl *m_TreeCtrl; LRESULT CALLBACK int WindowProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) { switch(message) { case WM_LBUTTONDOWN: m_TreeCtrl=new CTreeCtrl; m_TreeCtrl->Create(WS_VISIBLE | WS_TABSTOP | WS_CHILD | WS_BORDER | TVS_HASBUTTONS | TVS_LINESATROOT | TVS_HASLINES | TVS_DISABLEDRAGDROP, CRect(10, 10, 300, 100), CWnd::FromHandle(hWnd), 10000); break; case WM_CREATE: break; case WM_DESTROY: PostQuitMessage(0); break; case WM_PAINT: HDC hDC; PAINTSTRUCT Paint; hDC=BeginPaint(hWnd,&Paint); EndPaint(hWnd,&Paint); } return DefWindowProc(hWnd,message,wParam,lParam); } ・・・ と記述すると、エラーになります。 解決方法を教えてください。

  • OpenGLでウィンドウハンドルの取得

    コンソールアプリで作ることが前提です。 glut関数で作成したウィンドウのハンドルを取得し、その画面上に文字を表示しようとTextOutやDrawTextやらを使ってみたんですが、背景色しか表示されません。DrawTextの戻り値が18だったので成功していると思うのですが。どこがおかしいのかご指摘をお願いします。 #include<stdio.h> #include<windows.h> #include<GL/glut.h> HWND hwnd; void display(){ glClearColor(0.5,0.5,0.5,1); glClear(GL_COLOR_BUFFER_BIT); hwnd=GetActiveWindow(); PAINTSTRUCT ps; HDC hdc; RECT rect; LPCSTR str = TEXT("あああ"); GetClientRect(hwnd, &rect); hdc = BeginPaint(hwnd, &ps); SetRect( &rect, 10, 10, 100, 100); TextOut(hdc, 10, 10, str, lstrlen(str));    DrawText(hdc, TEXT("あああ"), -1, &rect,DT_CENTER); EndPaint(hwnd, &ps); glFlush(); } int main(int argc,char **argv){ glutInit(&argc,argv); glutInitWindowSize(640,480); glutCreateWindow("aaa"); glutDisplayFunc(display); glutMainLoop(); return(0); }

専門家に質問してみよう