プロが教えるわが家の防犯対策術!

C言語でWindowApiのプログラムを行っています。
コンパイラはBorland C++です。

ウィンドウから、右クリックでファイルを開くダイアグラムを開き、
ある文字だけをファイルから読み込み、結果をウィンドウ上に
表示させると言う感じのプログラムを作っています。

そこでですが、
WndProc関数の中の、
GetOpenFileName(&ofn);
SetWindowText(hWnd , strFile);
と言う部分でファイルダイアログを開き、
ファイル読み込みをしているわけなのですが、
このstrFileを別の関数に渡したいわけです。
そういう時どうすればいいでしょう?

また、char型をchar_w型に変換する際に、
WideCharToMultiByte
MultiByteToWideChar
関数を用いればいいことがわかりました。
しかし、char_w型は検索しても見つかりません。
この事も何かヒントを教えていただけたらと思います。

宜しくお願い致します。

A 回答 (16件中1~10件)

ざっと見ただけですが、前に書いたグラフィックを消していないので残っているだけでは?



例えば、文字列"12345”をTextOutで表示して
12345
あとで、同じ場所に文字列"999"をTextOutで表示すると
99945
となっている様に見えます。これは前の文字"45"が残っているためです。これじゃないでしょうか?

方法としては、
(1)文字列の後ろに適当な数の空白を付けてTextOutする。
先ほどの状態の画面で同じ場所に文字列"888  "をTextOutで表示すると
888  
となります。

(2)これから文字を書く所を背景色の長方形で塗りつぶしてから文字列をTextOutする。
Rectangleでこれから文字列を書く場所を背景色で塗りつぶしておきます。
私としては(1)より(2)がお勧めです。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
そういう事ではないようです。

修正しましたので、ソース乗せて起きます。
http://onegaisimasune.web.fc2.com/main2.txt

お礼日時:2007/09/28 15:00

>一応、ファイルを開いて、ファイルを選択した時は、


>何も表示されず、その後、
>タイトルバーを広げると、思い通りの結果が表示されていました。
それはウィンドが再描画されていないだけだと思います。
InvalidateRect関数で再描画を促してください。

>それと、再度、同じように読み込みをしたら、いい結果が表示されませんでした。。
状況が良くわかりません。悪い結果とは、どんな状況ですか?
    • good
    • 0
この回答へのお礼

ご教授ありがとうございます。
早速試してみます。

再度、一回目、パスを読み込み、タイトルバーを広げると、
うまく表示されるのですが、
その後、同じように、右クリックでファイルダイアログを開き、
パスを読み込むと、
表示されたものにプラスされた表示がされてしまうのです。
具体的に言いますと、
ファイルの中の文字を数えるとします。
その数をウィンドウ上に表示させます。
次に、続けて右クリックで同じようにファイルダイアログを
開いてファイルパスを読み込むと、
前の数字にプラスされた数字が表示されてしまうのです。
一応ファイルをアップしました。
これは、InvalidateRect関数で修正していないものです。

http://onegaisimasune.web.fc2.com/main.txt

お礼日時:2007/09/28 12:17

WinMainの処理に関しては、Oh-Orangeさんにお任せするとして。


私としては用語の扱いがアバウトなのを直してほしいと思います。回答者のみなさんがそのために混乱しているのが見受けられますので。

>GetOpenFileName(&ofn);
>でファイルを読み込み、
>(中略)
>読み込んだファイル名で置き換えれないかと言う事です。
GetOpenFileNameでは、ファイル名(パスを含む)を得ることができるだけで、ファイルを読み込む事はしません。
機能は理解していると思いますが、表現がまずいので他にも処理があるんじゃないかと混乱させられます。
「GetOpenFileName(&ofn);でパス付のファイル名を得て」などが正しい表現ですので今後は表現に注意してください。読む、読み込んだという表現はファイル実体の読み込み時ぐらいにしか使いません。

>また、別に、自分で作った、
>const char * func()
>関数にも、同じ記述があり、
>ファイル名を渡して、処理をしたいのですが・・・
const char * func(TCHAR *str)
と関数を作れば渡せると思いますが。
呼び出しは、
char_ptr = func(strFile);
で出来ます。
注意点は、func関数の利用時点で、strFile変数の有効範囲内であることです。

この回答への補足

一応、ファイルを開いて、ファイルを選択した時は、
何も表示されず、その後、
タイトルバーを広げると、思い通りの結果が表示されていました。

何が原因でしょう。

それと、再度、同じように読み込みをしたら、いい結果が表示
されませんでした。。

不具合を修正したいと思います。

補足日時:2007/09/27 14:15
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
ファイルを読み込んでいるのではなく、パスを
読み込んでいるのですね、注意します。

お礼日時:2007/09/27 12:35

★WinMain関数内ですか?


・GetOpenFileName 関数はプロシージャ関数の WM_RBUTTONUP メッセージで
 記述していますよね。ここで選択されたファイル名を WinMain 関数に記述
 されている fopen 関数に渡したいの?
・この動作はウインドウを一旦閉じるとまたメッセージ・ループに入って
 そのときに fopen 関数でファイルからデータを読み込む仕組みですか?
 もしこの動作なら次のように改善した方が好ましいです。
 (1)プロシージャ関数の WM_RBUTTONUP で GetOpenFileName 関数を呼ぶ
 (2)WM_RBUTTONUP 部分で選択されたファイル名を fopen 関数に渡す
 (3)WM_RBUTTONUP 部分でデータを読み書きする
 (4)WM_RBUTTONUP 部分でオープンされたファイルを fclose 関数で閉じる
 この仕組みにします。なぜ WinMain 関数なのでしょうか?

対策:
・『sample.txt』の部分は文字型配列の変数にしておけば良いです。
 TCHAR szFile[ MAX_PATH ]; ←GetOpenFileName 関数で選択されたファイル名が入っている
 FILE *fp;
 
 if ( (fp = fopen(szFile,"r")) == NULL ){
  // エラーなど
 }
 // 読み込み処理
 fclose( fp );
 ↑
・この部分を WinMain 関数に記述するのではなくて GetOpenFileName 関数の
 呼び出した後に記述してみたらどうでしょうか。
 自分で作った関数にもそのまま szFile などの文字型配列を渡せば良いです。
 今回はコンパイラのオプション設定より TCHAR、LPTSTR が char、char* 型と
 同じになりますのでそのまま TCHAR 型の配列を char *、const char * 型に
 渡せば使えます。
・以上。なぜ WinMain 関数で fopen しているのか補足して欲しいです。仕組みを。

この回答への補足

クリックし、何もしないと表示しないのですが、
タイトルバーをクリックしてウィンドウを広げると、
何とか思い通りの結果が表示させられました。
あとはこの不具合を何とかするだけです。。

補足日時:2007/09/27 13:28
    • good
    • 0
この回答へのお礼

このようにしました。

case WM_RBUTTONUP:
hdc = GetDC( hWnd );

if ( GetOpenFileName(&ofn) ){

if ((fp = fopen(strFile, "r")) == NULL) { /* 読み込むファイル名 */ /* ファイルを開けなかったら */
fprintf(stderr, "Can't Open C Source File!\n");/* メッセージを表示して */
exit(2);/* シェルへ戻る */
}

while (GetWord(fp, word)) {
BSearch(word);
}
SelectObject( hdc, hFont );

SetBkColor( hdc, RGB(255,255,255) );
TextOut( hdc, 200, 410, strFile, lstrlen(strFile) );
SetWindowText( hWnd, strFile );

}else{
MessageBox( hWnd, TEXT("キャンセルされました。"), TEXT("確認"), MB_OK );
}

fclose( fp );
ReleaseDC( hWnd, hdc );
break;

また、その後の、case WM_PAINT:では、
y = func(l,strFile);
のように、strFileをfuncに渡しています。
const char * func(int number,TCHAR * strz)
と言った関数です。
strzの部分は、

fp = fopen(strz, "r");
if (fp == NULL){
return 0;
}

と言った感じです。ちなみにfclose(fp);
はこの関数の、下の方でやってます。
実行してみましたが、しっかり表示されないですね・・・
strFileが渡っていないみたいです・・・

お礼日時:2007/09/27 13:18

★追記。


・今気づいたが『WINAPI』キーワードは Win32 API 関数という意味で使ってる?
 Win32 API 関数は char 型を引数に取るタイプと wchar_t 型を引数で受け取る
 2タイプが DLL で用意されています。そしてコンパイルのオプション設定から
 『UNICODE』定数の有無によりどちらの関数を呼び出すかが決まります。
・例えば SetWindowText() API 関数は次の2タイプが DLL 内に存在します。
 (1)SetWindowTextA()…char型で処理
 (2)SetWindowTextW()…wchar_t型で処理
 この2つの関数を直接呼び出すことも出来ますがお勧めしません。
 通常は TCHAR、LPTSTR、LPCTSTR 型を使うことでコンパイルのオプションから
 適切に char、wchar_t 型に置き換えられます。関数の末尾の A、W も同様に
 『UNICODE』定数の有無から適切に置き換わります。
・C 標準関数だけは char 型を処理するようになっているためこの関数群を
 利用するときには char、wchar_t 型に気をつける必要があります。
 本当はファイル処理なども C 標準関数ではなく Win32 API 関数か、MFC の
 CStdio クラスのメンバ関数を利用します。
 Windows GUI で C 標準関数のファイル入出力を使うべきではない気がします。
・以上。今後の参考にして下さい。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
↓にも記述しましたが、私がしたい事といいますのは、

GetOpenFileName(&ofn);
でファイルを読み込み、
WinMain関数内の、
if ((fp = fopen(sample.txt, "r")) == NULL)
の中の、sample.txtを何とか、
読み込んだファイル名で置き換えれないかと言う事です。

また、別に、自分で作った、
const char * func()
関数にも、同じ記述があり、
ファイル名を渡して、処理をしたいのですが・・・

できますでしょうか。

お礼日時:2007/09/26 12:25

★この質問は次の質問の続きですか?


http://oshiete1.goo.ne.jp/qa3364459.html→『ファイルを開く。(API・C言語)』
 もしも続きの質問でしたら OPENFILENAME 構造体に正しく情報を
 セットしていないために表示できていなかった可能性があります。
・続きの質問でないとするならこの『SetWindowTextについて。』は
 どのような質問でしょうか?補足して下さい。
 ちなみに『WINAPI』は WinMain() 関数ぐらいしか使いません。
 ユーザ関数にはつける必要はないです。
 多分は WndProc のプロシージャ関数内での TCHAR 型の文字列処理を
 どうすべきかという質問ですよね。
・以上。

参考URL:http://oshiete1.goo.ne.jp/qa3364459.html
    • good
    • 0
この回答へのお礼

読み込んだファイルを別のC関数に渡したいのですが、
何を渡せばいいのでしょう?
strFileでしょうか?
ofnでしょうか?

お礼日時:2007/09/26 16:43

>ちょっとソースは長くなるので無理だと思います・・・


全部でなくても良いのですが、
>GetOpenFileName(&ofn);
>SetWindowText(hWnd , strFile);
これだと省略しすぎてわからない。。。
もしこの通りのコードならstrFileにはファイル名さえ
入っていませんし。。。もう少し周辺のコードを載せてみては??

>一つは、WINAPI関数に渡したいのですが・・・。
WINAPI関数とは何者なのでしょうか??
ANo.5さんがおっしゃっているように、WINAPIという語句は
Windowsの呼び出し規約の予約語として既に使用されています。
無理にWINAPIという関数名を使うと様々なところに弊害が出ると
思います。
#もしかしてWinMain関数の事を言っている??
#あと補足を要求している部分についての回答が全くないのですが。。。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
すみません、WinMain関数の事を言っておりました。
↓に、私のやりたい事を記述しましたので、
よろしければご覧になってください。

お礼日時:2007/09/26 12:22

>WINAPI関数に渡したいと思うのですが。


WINAPIの意味が違うような気がしてきました。
前に、
> WINAPI(LPCTSTR str);
と書いていましたが、もしかして
void WINAPI xxxxx(TCHAR *str);
という関数名xxxxxの関数を作りたいという意味でしょうか?

WINAPIは、WindowsAPIの呼び出し規約を定義するためのマクロで、必要な場合は定義しなくてはなりませんが、関数内でWindowsAPIを呼び出しているだけの場合は定義する必要はありません。

それともまだ別の意味があるのでしょうか?
    • good
    • 0
この回答へのお礼

回答どうもありがとうございます。
WINAPI関数ではなく、WinMain関数でした。
この、WinMain関数の中に、この記述があります。

if ((fp = fopen("sample.txt", "r")) == NULL) {
fprintf(stderr, "Can't Open C Source File!\n");

ですので、この中の、sample.txtを、
ファイル読み込みダイアグラムから読み込んだファイルに
置き換え、処理をさせたいのですが。。

また、別の、
const char * func()
にも、同じような、

fp = fopen(sample.txt, "r");
if (fp == NULL)

の記述があり、
これを、 WndProc関数の中の、
GetOpenFileName(&ofn);
から読み込んで何とか渡したいのですが。。

何とかなりませんでしょうか。

お礼日時:2007/09/26 12:19

★こちらにも書き込みます。


>ファイル読み込みをしているわけなのですが、
>このstrFileを別の関数に渡したいわけです。
>そういう時どうすればいいでしょう?
 コンパイル・オプションが UNICDOE を定義しない設定ですので
 そのまま strFile を関数などに渡せば良いと思います。
 何かエラーが出た場合は補足に貼り付けて下さい。
 回答しやすくなります。
・この質問も char 型 と wchar_t 型の変換は必要ないと思います。
 char 型で使う C 標準関数の文字列も TCHAR 型で宣言しても上手く動くと思います。
 すべての char 型を TCHAR 型に書き換えれば問題は解決しませんか?
 エラーが出た場合はそのメッセージをそのまま補足に貼り付けて下さい。
・以上。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
置き換えてやってますね。
しかし、WINAPI関数に渡したいと思うのですが、
難しいですねぇ。

お礼日時:2007/09/25 17:33

WINAPIという名前は予約されているので基本的に使わないでください。



>"file.txt"の部分を置き換えたいのです。
って事は、文字列の置き換え処理を関数側でしたいってことですよね。
LPCTSTRのCはconstつまり変更しないという意味なので、文字列置換するなら使ってはいけません。TCHAR*を使ってください。

>また、char型をchar_w型に変換する際に、
>WideCharToMultiByte
>MultiByteToWideChar
>関数を用いればいいことがわかりました。
>しかし、char_w型は検索しても見つかりません。
>この事も何かヒントを教えていただけたらと思います。

Oh-Orangeさんの言うとおり、文字コードの変換はややこしいので、UNICODEを使わない設定でコンパイラを利用したほうが簡単です。
どうしても、文字コードの変換を使いたい理由があるのでしょうか?
UNICODEで便利なこともありますので挑戦したないなら止めはしませんが。
    • good
    • 0
この回答へのお礼

ありがとうございます。
UNICODEとは何なのかとかまださっぱりわからないので、
ちょっと勉強してみます。
ちなみに使っているコンパイラはBorland C++です。

お礼日時:2007/09/27 12:23

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています