###わかったこと
- Win7の電卓アプリはボタンに絵が表示されていてキャプションは空。
- WM_GETTEXTは
wstring
型で受けたほうが良い - WM_GETTEXTで取得できる文字列は途中に
'\0'
を含むかもしれないので文字列を受ける側の変数にあらかじめWM_GETTEXTLENGTHで文字長を指定するなら取得後に再度文字長を定義したほうが良い
###前提・実現したいこと
UIオートメーションを実現するためにテストとして、とりあえずWindowsに標準でインストールされている電卓を操作しようとしています。
いま、取得できるハンドラのうちどれがどのボタンか判別ができずにいます。
そこで、WM_GETTEXTをGetMessage関数に指定してボタンのキャプションを取得しようしています。
ですが、以下のメッセージが発生しており如何ともならなくなっている状況です。
また、どのハンドラーがどのボタンであるかを判断する方法が他にあればGetMessage
関数が使えなくとも良いです。
ボタンのキャプションを取得して判別しようとしましたがほとんどが空になっており終端文字'\0'
しか取得できず目的を達成できません。
電卓のボタンをそれぞれ特定するために良い方法はないでしょうか?
よろしくお願いいたします。
以下は解決しました。
###発生している問題・エラーメッセージ
| Micorosoft Visual C++ RuntimeLibrary | | Debug Error! Program : ......\UIAuto.exe HEAP CORRUCTION DETECTED: after Normal block(#570) at 0x0000000000031F0D0. CRT detected that the application wrote to memory after end of heap buffer. (press Retry to debug the application) | | 中止 | 再試行 | 無視 |
以下のコードの位置のブレークポイントでとめた後、ひとつステップを進めると上記の内容でエラーダイアログが表示されます。
###該当のソースコード
c++
1void CUIAutoDlg::OnBnClickedOk() 2{ 3 // TODO: ここにコントロール通知ハンドラー コードを追加します。 4 CWnd* cWnd = FindWindow(_T("CalcFrame"), _T("電卓")); 5 6 try { 7 if (cWnd == NULL) throw std::exception("cant find calc."); 8 } 9 catch(std::exception e){ 10 MessageBox(CString(e.what()), NULL, 0); 11 return; 12 } 13 HWND hWnd = cWnd->GetSafeHwnd(); 14 15 int cnt = 0; 16 cWnd->SetForegroundWindow(); 17 EnumChildWindows(hWnd, EnumChildProc, (LPARAM)&cnt); 18 ::UpdateWindow(hWnd); 19 20 //CDialogEx::OnOK(); 21} 22 23BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lParam) 24{ 25 int bufLen = 0; 26 bufLen = SendMessage(hwnd, WM_GETTEXTLENGTH, NULL, NULL) + 1; // +1は文字末端\0用 27 if (bufLen > 1) { 28 // std::vector<char> buf[bufLen]; ご指摘を受けて改善 29 // SendMessage(hwnd, WM_GETTEXT, bufLen, (LPARAM)&buf[0]); 30 std::wstring buf; //wstringに変更 std::string buf; 31 buf.resize(bufLen); 32 SendMessage(hwnd, WM_GETTEXT, bufLen, (LPARAM)&buf[0]); 33 buf.resize(std::char_traits<wchar_t>::length(&buf[0])); //wstringに変更 char>::length(&buf[0])); 34 35 int hoge = 0; // ブレークポイント設置用の行。 // ここのブレークポイントから先でエラー 36 } 37 return TRUE; 38} 39
###試したこと
上記のコードで文字列を受けるバッファにchar配列を用いたりしましたが同じ現象で最後まで走りきりませんでした。
定義はchar *buf = new char[bufLen];
で初期化、デバッガで内容を確認する行をはさんですぐdelete [] buf;
していたので何も問題ないだろうと思ったのですが・・・。
GetWindowText( hwnd, CString ,int)
関数でキャプションを取得する方法も試しましたがほとんどが空欄でボタン特定の参考にはなりませんでした。
###補足情報(言語/FW/ツール等のバージョンなど)
- Windows7/64bit SP1
- VisualStudio2015 SP1
- VC++/MFC

回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/01/22 06:16