C++とWin32APIでツールを制作しています。
メインウインドウのメニュー→ファイル→新規作成 で新規作成ダイアログを開き、そこに文字列を入力できるテキストエディットがあり、OKを押すとメインウインドウにその文字列が表示される
というプログラムを書いていました。しかし、
テキストエディットに入力された文字列をGetDlgItemTextで受け取る際に、その文字列がそれを入れる配列以上のサイズになっている場合、OKを押してダイアログを閉じ、
次にもう一度ダイアログを開こうとすると開けなくなってしまうというバグが発生しました。
TCHAR szName[32];//グローバル変数
BOOL CALLBACK MyDlgProc(HWND hDlg,UINT msg,WPARAM wp,LPARAM lp)
{
switch(msg)
{
case WM_COMMAND:
switch(LOWORD(wp))
{
case IDOK://OKボタンを押したら
int x;//文字数
x = GetDlgItemText(hDlg,IDC_EDIT1,szName,(int)sizeof(szName)-1);
if(x>32)//文字数超過の場合、警告をだしてエディタの中身を初期化、もう一度入力しなおし
{
MessageBox(NULL,TEXT("文字数が多すぎます。"),TEXT("文字数超過"),MB_OK);
SetDlgItemText( hDlg,IDC_EDIT1,TEXT("") );
}
else
{
EndDialog(hDlg,IDOK);
}
return TRUE;
}
return FALSE;
}
return FALSE;
}
一応、重要そうな部分のプログラムを書いておきましたが、問題なのはGetDlgItemTextの仕様な気がします。
この関数は、説明だと「文字列が配列サイズを超えた場合、文字列を切り捨てる」そうですが、配列サイズを超えるたびにバグってしまうので、ここになんらかの原因があるような気がします。
ちなみに、猫でもわかるWindowsプログラミング第4版の10章を参考にプログラムを書いているのですが、
この本のサンプルプログラムでも文字列を配列サイズが超過するとエラーが発生してしまっていました。
どなたか対処法をお願いします。(現在は配列サイズをめちゃくちゃ大きくして、オーバーする文字列を入力することを物理的に難しくするという無理やりな方法で対処しています)
C++/Win32APIでのテキストエディタの文字列超過時のバグ
-
skn
Re: C++/Win32APIでのテキストエディタの文字列超過時のバグ
ちなみに、ダイアログが開けなくなった際、
「初回の例外が発生しました」というメッセージが4件ほど出ることがあります。(でないときもあります)
「初回の例外が発生しました」というメッセージが4件ほど出ることがあります。(でないときもあります)
Re: C++/Win32APIでのテキストエディタの文字列超過時のバグ
コードはBBCodeを有効にした状態でcodeタグで囲んでいただけると、見やすくてありがたいです。
(int)(sizeof(szText)/sizeof(szText[0]))としてみてください。
GetDlgItemText function (Windows)
GetDlgItemText 関数
GetDlgItemTextの第4引数は、配列のデータサイズではなく要素数を指定しなければなりません。skn さんが書きました:問題なのはGetDlgItemTextの仕様な気がします。
この関数は、説明だと「文字列が配列サイズを超えた場合、文字列を切り捨てる」そうですが、配列サイズを超えるたびにバグってしまうので、ここになんらかの原因があるような気がします。
(int)(sizeof(szText)/sizeof(szText[0]))としてみてください。
GetDlgItemText function (Windows)
GetDlgItemText 関数
EM_SETLIMITTEXTメッセージを用いると、入力できる文字数を制限できます。skn さんが書きました:現在は配列サイズをめちゃくちゃ大きくして、オーバーする文字列を入力することを物理的に難しくするという無理やりな方法で対処しています
オフトピック
ちょっと入力ミスをすると振り出しに戻される鬼畜仕様、個人的には嫌いだなあ…skn さんが書きました:文字数超過の場合、警告をだしてエディタの中身を初期化、もう一度入力しなおし
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
-
skn
Re: C++/Win32APIでのテキストエディタの文字列超過時のバグ
GetDlgItemTextの第4引数をそのように修正することで解決できました、ありがとうございました!