前回書いた進め方でCEDITクラスの移植を行い、いよいよファイル入出力をどうするか、になろうとして、FindText、ReplaceText処理で躓いてしまいました。
BCCSkeltonのCREDITクラスは"REDIT32.DLL"(バージョン1.0)の時に書かれ、文字列の検索、置換ダイアログを使って意図通りの動作をしますので、そのままUTF-16化を行えば問題なし、と思っていましたが、どっこいそうは問屋が卸してくれませんでした。
先ずこのFindText、ReplaceText(ダイアログ)処理ですが、
(1)「文字列の検索」「文字列の置換」用コモンダイアログは呼び出すだけでは何もしません。これら(モードレス)ダイアログの「次を検索」とか「すべて置換」等のボタンを押した際に発生するメッセージを拾って、ユーザーが文字列検索、文字列置換処理を行います。
(2)そのためには、先ずこれら(モードレス)ダイアログが送るメッセージを登録します。
//検索・置換メーッセージの登録
m_frMsg = RegisterWindowMessageW(FINDMSGSTRINGW);
(3)これら(モードレス)ダイアログはFINDREPLACE(W)構造体へのポインターを引数として、FindText、ReplaceText関数で呼び出します。
(4)後はこれら(モードレス)ダイアログがメッセージを送った場合に呼び出すユーザー定義関数をCREDITクラスのメンバーに加えます。(lParamはFINDREPLACE(W)構造体のポインター)
//CREDITクラスは文字列検索・置換用にユーザーメッセージを作るので、
//このような処理を行います。CREDITファイルを覗いてください。
if(Msg == m_Edit.m_frMsg)
m_Edit.FindReplace(lParam); //検索・置換処理
ということで、特段難しい処理ではなく、検索文字列をFINDTEXT構造体のlpstrTextにぶち込み(これら(モードレス)ダイアログがやってくれる)、検索範囲を同じくCHARRANGE構造体であるchrg(先頭が0、末尾は-1)に入れて検索し、「もう無い(NOMORE == -1)」が返るまで、与えられたフラグ(FR_DOWN等)にに従って検索します。(例:SendMessageW(m_hWnd, EM_FINDTEXTW, flag, (LPARAM)ft)) != NOMORE)
戻り値が検索文字の先頭のキャラクターポインターになっているので、文字列長だけ選択して表示します。(交換したけりゃMessageBoxで確認して、交換文字列と替えます。例:SendMessageW(m_hWnd, EM_REPLACESEL, TRUE, (LPARAM)m_ReplaceWith);)
しかし、テストではきちんと検索するのに、コモンダイアログで探すと見当たらない、という結果になる等、何故か正常に動作しません。コードも今回見直しを行い、若干手直しの上、コメントを書き直して分かりやすくしているのですが...
何故なんだ?
まぁ、気長に調査を行ってゆきます。