• ベストアンサー

ファイルを開く。(API・C言語)

case WM_RBUTTONUP: GetOpenFileName(&ofn); SetWindowText(hWnd , strFile); return 0; ↑のソースは、ウィンドウを右クリックした後、ファイル名をタイトルバーに表示させるものなのですが、この、strFileを、ウィンドウの画面上に表示させるのに、 SelectObject(hdc , hFont); SetBkColor(hdc , RGB(255 , 255 , 255)); TextOut(hdc , 40, 10, strFile, lstrlen(strFile)); で表示させてみようとしたところ、エラーが発生し、できませんでした。どうやるのでしょうか。ちなみに、strFileはstatic TCHAR型です。 また、ウィンドウから読み込んだテキストファイルを、ある文字列がどれだけあるか、などを数え、その後、その数を表示させたりもさせるプログラムを作っています。それで分からなかったのが、読み込んだファイルはTCHAR型ですよね。それをどうやってchar型に直すかです。 宜しくお願い致します。

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

  • ベストアンサー
  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.9

★HDC の問題です。 >hdc、hFont には正しくハンドルが入っていますか?確認して下さい。  ↑  hFont のハンドルは CreateFont() の戻り値であっています。  ただし NULL が返されたときの処理を入れておきましょう。  hFont に NULL が入っているとフォントの設定が出来ません。 ・hdc のハンドルに BeginPaint() 関数を使っていますが間違いです。  この BeginPaint() 関数は WM_PAINT メッセージ内でしか使うことがない関数です。  同様に EndPaint() 関数も同じく WM_PAINT メッセージ内でしか使いません。  ここが面白い(おかしい)ところですが WM_PAINT メッセージ以外でクライアント領域などに  描画したい場合は GetDC()、RealeceDC() 関数を使います。  下にサンプルを載せます。 サンプル1: WM_PAINT: {  PAINTSTRUCT ps;  HDC hDC;    hDC = BeginPaint( hWnd, &ps );  // ここで図形や文字を hDC に描画  EndPaint( hWnd, &ps );  break; } サンプル2: WM_RBUTTONUP: {  HDC hDC;    hDC = GetDC( hWnd );  // ここで図形や文字を hDC に描画  ReleaseDC( hWnd, hDC );  break; } 解説: ・WM_PAINT メッセージ内では BeginPaint、EndPaint 関数を使います。  でも WM_PAINT メッセージ以外では GetDC、ReleaseDC 関数を使います。  GetDC 関数でデバイスコンテキストを取得して  ReleaseDC 関数でデバイスコンテキストを解放します。 ・今回の場合は WM_CREATE メッセージで『hDC = GetDC( hWnd );』を記述して  WM_CLOSE メッセージか、WM_DESTORY メッセージのどちらか一方に  『ReleaseDC( hWnd, hDC );』を記述します。 ・あと GetOpenFileName() 関数で使う ofn 構造体は最初にセットしているので  WM_RBUTTONUP メッセージの部分は削除して下さい。私のお勧めは WM_CREATE の  場所ではなくて GetOpenFileName() 関数を呼び出す直前で記述する方法です。  どちらでも結果的には同じです。好みの問題かな。 改善策: ・次のように修正して下さい。  修正前⇒『hdc = BeginPaint(hWnd , &ps);』  修正後⇒『hdc = GetDC( hWnd );』 ・あと次の部分も一緒に修正して下さい。  修正前⇒『EndPaint( hWnd, &ps );』  修正後⇒『ReleaseDC( hWnd, hdc );』 ・以上。

noname#142813
質問者

お礼

毎回詳しい説明感謝致します。 修正後、うまく行きました。 今度は、stfFileを何とか別の関数に渡す方法を考えたいと 思います。

すると、全ての回答が全文表示されます。

その他の回答 (8)

  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.8

★予想通りの間違いだ。 >ofn構造体には何も設定はしてないですね。。  ↑  これが原因です。 ・GetOpenFileName() 関数を呼ぶ前に OPENFILENAME 構造体の情報を正しく  セットして下さい。次のリンクを以前に紹介しましたが WM_RBUTTONUP の  部分だけをコピーしちゃいましたね。  http://wisdom.sakura.ne.jp/system/winapi/common/common6.html  ↑  このリンクの GetOpenFileName() 関数を呼ぶ前に OPENFILENAME 構造体を  セットする部分を記述して下さい。これがないと何も表示されません。 ・今回の質問では ofs 構造体に正しいデータをセットしていないからです。  次のようにして下さい。 サンプル: LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) {  static TCHAR strFile[ MAX_PATH ];  static TCHAR strCustom[ MAX_PATH ] = TEXT("Before files\0*.*\0\0");  static OPENFILENAME ofn;    switch ( uMsg ){   case WM_RBUTTONUP:    if ( ofn.lStructSize == 0 ){     ofn.lStructSize = sizeof( OPENFILENAME );     ofn.hwndOwner = hWnd;     ofn.lpstrFilter = TEXT("Text files {*.txt}\0*.txt\0")              TEXT("HTML files {*.htm}\0*.htm;*.html\0")              TEXT("All files {*.*}\0*.*\0\0");     ofn.lpstrCustomFilter = strCustom;     ofn.nMaxCustFilter = sizeof( strCustom );     ofn.nFilterIndex = 0;     ofn.lpstrFile = strFile;     ofn.nMaxFile = sizeof( strFile );     ofn.Flags = OFN_FILEMUSTEXIST;    }    if ( GetOpenFileName(&ofn) ){     SetWindowText( hWnd, strFile );     SelectObject( hdc, hFont );     SetBkColor( hdc, RGB(255,255,255) );     TextOut( hdc, 200, 410, strFile, lstrlen(strFile) );    }    else{     MessageBox( hWnd, TEXT("キャンセルされました。"), TEXT("確認"), MB_OK );    }    return 0;  }  return DefWindowProc( hWnd, uMsg, wParam, lParam ); } その他: ・hdc、hFont には正しくハンドルが入っていますか?確認して下さい。  上記のサンプルは WM_RBUTTONUP メッセージのみです。 ・以上。参考に。

参考URL:
http://wisdom.sakura.ne.jp/system/winapi/common/common6.html
noname#142813
質問者

お礼

回答ありがとうございます。 ちなみに、case WM_RBUTTONUP:の前に、 ↓のような記述は前からありました。 case WM_CREATE: ofn.lStructSize = sizeof (OPENFILENAME); ofn.hwndOwner = hWnd; ofn.lpstrFilter = TEXT("Text files {*.txt}\0*.txt\0") TEXT("HTML files {*.htm}\0*.htm;*.html\0") TEXT("All files {*.*}\0*.*\0\0"); ofn.lpstrCustomFilter = strCustom; ofn.nMaxCustFilter = 256; ofn.nFilterIndex = 0; ofn.lpstrFile = strFile; ofn.nMaxFile = MAX_PATH; ofn.Flags = OFN_FILEMUSTEXIST; return 0; hdc、hFontは、 hdc = BeginPaint(hWnd , &ps); hFont = CreateFont( 15 , 0 , 0 , 0 , FW_THIN , 0 , 0 , FALSE , SHIFTJIS_CHARSET , OUT_DEFAULT_PRECIS , CLIP_DEFAULT_PRECIS , DEFAULT_QUALITY , VARIABLE_PITCH | FF_ROMAN , NULL ); /* フォント TRUE = 1 , FALSE = 0 */ と設定しています。 サンプルを実行してみましたが、 結果は同じでした。。 表示されないですね。。

すると、全ての回答が全文表示されます。
  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.7

★恐らく構造体に何も設定していないのでは?  つまり GetOpenFileName() 関数の引数である ofn 構造体に正しい設定を  していないような気がします。ソースが長いようですから WM_RBUTTONUP  メッセージの部分だけソースを貼り付けて下さい。そのままコピー&ペースト。 ・あと str の容量が足りない気がします。  修正前⇒static TCHAR str[ 64 ];  修正後⇒static TCHAR str[ MAX_PATH ];  ※MAX_PATH定数は既に定義されています。たしか 260 だったかな。  安全なために 64 よりも MAX_PATH の定数を使って下さい。 ・以上。ソースの提示を待っています。

noname#142813
質問者

お礼

case WM_RBUTTONUP: GetOpenFileName(&ofn); SetWindowText(hWnd , strFile); SelectObject(hdc , hFont); SetBkColor(hdc , RGB(255 , 255 , 255)); TextOut(hdc , 200, 410, strFile, lstrlen(strFile)); return 0; です。 64→MAX_PATHに変換しておきます。 ofn構造体には何も設定はしてないですね。。

すると、全ての回答が全文表示されます。
  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.6

★お礼の解釈はあっています。 ・これで先に進めます。  今回はコンパイルのオプションで UNICODE が定義されないため TCHAR 型と char 型は  同じ型になります。だから変換する必要はありません。 ・ただ気になるのはなぜエラーが出たのか?  TCHAR 型が char 型ですので SetWindowText()、TextOut() 関数も char 型の文字列を  普通に渡して問題はありません。それに strFile は TCHAR 型で宣言しているので  どんなエラーが表示されるのかを今度は補足して下さい。 ・それでは補足情報を待っています。

noname#142813
質問者

お礼

↓のように記述しております。 エラー出ないのですが、 ウィンドウ上に何も表示されません。 strは、 static TCHAR str[64]; という感じに宣言しております。 case WM_RBUTTONUP: GetOpenFileName(&ofn); SetWindowText(hWnd , strFile); SelectObject(hdc , hFont); SetBkColor(hdc , RGB(255 , 255 , 255)); TextOut(hdc , 200, 410, strFile, lstrlen(strFile));

すると、全ての回答が全文表示されます。
  • aris-wiz
  • ベストアンサー率38% (96/252)
回答No.5

>char_w  誤り >wchar_t 正しい 訂正です・・・申し訳ない・・・orz エラーについての補足が全くありませんが、解決したのでしょうか? もしかしたら、今回の不具合にTCHAR型はあまり無いかもしれないので、エラーの内容を・・・と聞いているのですが・・・

すると、全ての回答が全文表示されます。
  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.4

★TCHAR型(char型,wchar_t型)の意味は分かりましたか? ・簡単に説明しますと『Borand C++』コンパイラのオプションで  『UNICODE』記号定数が定義される設定では  (1)TCHAR型……wchar_t  (2)LPTSTR型 …wchar_t *  (3)LPCTSTR型…const wchar_t *  『UNICODE』記号定数が定義されない設定では  (1)TCHAR型……char  (2)LPTSTR型 …char *  (3)LPCTSTR型…const char *  にソースの記述を機械的に置き換えます。 ・まずは『Borand C++』コンパイラのオプションで UNICODE 定数が定義するように  なっているのか、定義されないでマルチバイト(char型)なのかを確認して下さい。  確認はコンパイル時のオプションです。ソース内容ではありません。 ・どうしても分からない場合は次のコードで分かります。  #if defined(UNICODE)   MessageBox( NULL, TEXT("UNICODE"), TEXT("確認"), MB_OK );  #else   MessageBox( NULL, TEXT("SJIS"), TEXT("確認"), MB_OK );  #endif  上記の5行を WinMain() のメッセージループより前に記述してコンパイルします。  その後に実行してどちらのメッセージが表示されるか補足して下さい。  それから UNICODE 定数の意味、TCHAR、LPTSTR、LPCTSTR 型の意味は分かりましたか? ・以上。2つの補足がないとアドバイスできません。先に進みませんよ。

noname#142813
質問者

お礼

回答どうもありがとうございます。 SJISでした。 TCHAR、LPTSTR、LPCTSTR 型の意味は下記のようでよろしいでしょうか。 ・TCHAR = char ・LPCTSTR = const char* ・LPTSTR = char* というのは「UNICODE」が定義されていないときの置き換えということになり、「UNICODE」が定義されているときには ・TCHAR = WCHAR ・LPCTSTR = const WCHAR* ・LPTSTR = WCHAR*

すると、全ての回答が全文表示されます。
  • aris-wiz
  • ベストアンサー率38% (96/252)
回答No.3

私の補足要求については解答なしでしょうか? >エラーとはどんなエラーなのでしょうか? 追加要求です。。。 ファイル読み込みの関数は何を使用しているのでしょうか? TCHAR型について、 説明のしかたがまずかったでしょうか・・・ 前回も書きましたが、TCHAR型というのは、 UNICODEマクロを定義した場合にTCHARはchar_w型になります。 つまりもともとchar型の場合があるわけですから、 TCAHR型をchar型にするという作業をそのまま行うのはまずいのです。 char_w と char の相互変換はWindowsであれば、 WideCharToMultiByte MultiByteToWideChar という関数を使用することで可能です。 これらはWindowsAPIなので、 Windows環境であればWindows.hをインクルードすることで 使用可能でC++ではありません。 >二つ目のリンクはC++ではないでしょうか。 newとかをmallocとかに読み直す必要はあるかもしれませんね。

noname#142813
質問者

お礼

ありがとうございます。 つまり、char_w型をchar型に変換すればいいわけですね。 一度やってみたいと思います。 また、うまく行かなかったら質問させていただきます。

noname#142813
質問者

補足

やっぱりよくわかりませんね。。 そもそもchar_wと検索してもあまり出てきませんでした。。 いい方法はありますでしょうか。。

すると、全ての回答が全文表示されます。
  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.2

★ここでしっかりと TCHAR 型についてお勉強しましょう。 ・前も char 型の文字列を描画したいという内容の質問でしたよね。 >読み込んだファイルはTCHAR型ですよね。 >それをどうやってchar型に直すかです。  ↑  これは Windows で開発しているとき TCHAR 型を使っていてファイルの入出力の時に  C関数を使いたいから char 型に直したいのですよね。  Windows 環境なら C 関数ではなくて API のファイル入出力を使うべきだと思います。  MFC なら CStdio クラスが C 関数と同じ操作で便利です。  MFC、API を利用すれば char 型に直す必要はありません。  まずは次のリンクをよく読んで下さい。  http://www.ruche-home.net/program/tips/tchar.php→『Unicode対応プログラミング』 ・ちなみに次のリンクに TCHAR 型を char 型に変換する内容が紹介されています。  http://www.usefullcode.net/2006/12/windowstchar.html→『WindowsプログラミングでのTCHARの扱い方』  上から7つ目です。  上記のをよく読み理解して下さい。  そうしないとまた TCHAR 型を char 型に変換するには…。で悩みます。 ・以上。上記の内容を読んだ後に解決策を出しますので理解度や感想なんかを補足。

参考URL:
http://www.ruche-home.net/program/tips/tchar.php
noname#142813
質問者

お礼

回答ありがとうございます。 結構長いプログラムを書いてしまいましたので、 読んでみたのですが、ちょっとよくわかりませんでした。。 ちなみにC++ではなくC言語でプログラムをしています。 二つ目のリンクはC++ではないでしょうか。 コンパイラはBorand C++です。 宜しくお願い致します。

すると、全ての回答が全文表示されます。
  • aris-wiz
  • ベストアンサー率38% (96/252)
回答No.1

>エラーが発生し、できませんでした どの様なエラーが発生したのか、 もう少し詳しく教えてください。 とりあえず、以下の2つがわかりませんね。 ・デバイスコンテキストハンドルはどうやって取得したのか? ・CreateFont関数の呼び出し方は正しか? >読み込んだファイルはTCHAR型ですよね 意味がわかりませんが。。。 ファイルからfgetsなどで読み込んだ文字列だとすると 普通はchar型です。 また、TCHAR型というのは、コンパイル時のプリプロセッサによって UNICODEが定義されていればchar_wに 定義されていなければ、char型に置換されるマクロ定義です。

noname#142813
質問者

お礼

すいません、エラーは発生せず、 表示されないだけでした。 回答ありがとうございます。 CreateFont関数は、 hFont = CreateFont( 15 , 0 , 0 , 0 , FW_THIN , 0 , 0 , FALSE , SHIFTJIS_CHARSET , OUT_DEFAULT_PRECIS , CLIP_DEFAULT_PRECIS , DEFAULT_QUALITY , VARIABLE_PITCH | FF_ROMAN , NULL ); のようになっています。

すると、全ての回答が全文表示されます。

関連するQ&A