- ベストアンサー
ソフト改行文字が入らず困っています
VB6環境で、テキストボックスにEM_FMTLINES(= &HC8)をSendMessageしソフト改行文字を入れた形でテキストを取得したいのですが、希に複数行入力されているにもかかわらず、ソフト改行文字が追加されない場合があります。 MultiLineをtrueにしたテキストボックス「text1」とボタン「Command1」をフォームに貼り付け、以下のようなテストプログラムを作成してみました。(お見苦しいところありましたらすみません) Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long Private Const EM_FMTLINES = &HC8 'ソフト改行文字を設定/削除する定数 Private Sub Command1_Click() Dim ret As Boolean Dim str As String ret = True 'ソフト改行文字を付加 Call SendMessage(Text1.hwnd, EM_FMTLINES, 1&, ByVal 0&) str = Text1.Text If InStr(str, vbCr & vbCr & vbLf) = 0 Then MsgBox "失敗!" ret = False End If 'ソフト改行文字を削除 Call SendMessage(Text1.hwnd, EM_FMTLINES, 0&, ByVal 0&) If ret = True Then MsgBox "成功" End If End Sub テキストボックスの横幅をある程度狭くし、複数行になるよう適当に文字を入力しボタンをクリックすると、ほとんど成功するのですが、確かに20回に1回くらい失敗します。 失敗した際は何度ボタンをクリックしても失敗します。逆に成功した文字列でなんどもボタンをクリックしても成功しか帰ってきません。 試した環境 WindowsXP Pro SP2、Windows2000 SP4 なんとも法則性も見つからず、途方に暮れております。決方法やこんな事象ご存知でしたら助けて頂けないでしょうか。よろしくお願い致します。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
たぶん EM_SETWORDBREAKで EditWordBreakProcを登録してから EM_FMTLINESを設定して使うのだろうと思いますよ ちょっと試してみたんですが EditWordBreakProcを設定した後IDEがクラッシュしてしまう現象が出てますので確信はないんですけど ・・・ 判断は vbCr vbCr vbLf の並びでチェックでいいと思います
その他の回答 (2)
- imogasi
- ベストアンサー率27% (4737/17069)
#1でもおっしゃっている >If InStr(str, vbCr & vbCr & vbLf) = 0 Then はおかしくないですか vbCr & vbCr & vbLf は余り意味がないのでは? VBCrLfとか。 それに、「あれかまたはこれか」の意味ではこの書き方はできないと思います。 If InStr(str, vbCr ) = 0 Or InStr(str, vbLf) = 0 Then になりませんか。
お礼
解答ありがとうございます。 VBですと、&は結合という意味なので、ここの判定の意味は「str」の中に「VbCrVbCrVbLf」というコードがないかということをチェックしていることになりますので大丈夫・・・だと思います。 調べてみたところ、「VbCrLf」はユーザーが入力した改行、「vbCr & vbCr & vbLf」はソフト改行文字を意味するそうです。 If InStr(str, vbCr ) = 0 Or InStr(str, vbLf) = 0 Then こちらのコードでも試しましたが、やはり数回に1回失敗してしまいます。やっぱりSendMessageでソフト改行文字の挿入に失敗?してるみたいです。
- tomiono1
- ベストアンサー率38% (5/13)
自分の知識が低いので見当違いなことを言っていたら、申し訳ありません。 判定ののところで「vbNewLine」を使用してみてはではいかがでしょうか?
お礼
早速の解答、ありがとうございます。 If InStr(str, vbCr & vbCr & vbLf) = 0 Then ↓ If InStr(str, vbNewLine) = 0 Then 判定のところを上記のように変更してみたのですが、やっぱりだめでした。プログラムを使ってもらってる人からの指摘で判明したので、私のところの環境だけではないとは思うのですが・・・ SendMessage自体不安定なものなのでしょうか
お礼
教えて頂いたキーワードを元に、サンプルなどを作成して確認したのですが、やっぱり失敗してしまいます。 サンプルですが、手元に「VisualBasic300の技」という本があり、そのなかに「ワードラップを抑止する」という項目があったので、まずはそのコードで実行してみたのですが、redfox63さんと同じようにIDEが強制終了してしまいました。 HP等を検索してワードラップを抑止するコードは確認でき、そこにソフト改行文字を挿入するコードを加えたのですが、やっぱり失敗してしまいました。 いろいろ試したところ、以下のような状態でソフト改行文字を入れようとするとこちらでは必ず失敗してしまいます。 ・スケールモード Twip ・テキストボックス width=915 Height=1935 ・文字列 「oooooooooooooooooooooooaaaaa」(コピペだと成功します)
補足
サンプルは以下のように作ってみました Private Const EM_FMTLINES = &HC8 'ソフト改行文字を設定/削除する定数 Private Sub Command1_Click() Dim ret As Boolean Dim str As String ret = True 'ソフト改行文字を付加 Call SendMessage(Text1.hwnd, EM_FMTLINES, 1&, ByVal 0&) str = Text1.Text If InStr(str, vbCr & vbCr & vbLf) = 0 Then MsgBox "失敗!" ret = False End If 'ソフト改行文字を削除 Call SendMessage(Text1.hwnd, EM_FMTLINES, 0&, ByVal 0&) If ret = True Then MsgBox "成功" End If End Sub Private Sub Form_Load() Call NonWordrap(Text1) End Sub -------- 以下標準モジュール ----------- Option Explicit Public Const EM_SETWORDBREAKPROC = &HD0 Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long Public Function NonWordrap(Ctl As Control) Dim lngSubProcAddress As Long Dim lngWin32apiResultCode As Long ' コールバック関数のアドレスをLong値に変換 lngSubProcAddress = _ GetSubProcAddress(AddressOf EditWordBreakProc) ' ワードラップを抑止 lngWin32apiResultCode = _ SendMessage(Ctl.hwnd, _ EM_SETWORDBREAKPROC, _ 0, _ ByVal lngSubProcAddress) End Function ' コールバック関数のアドレスをLong値に変換 ' Public Function GetSubProcAddress _ (ByVal lngProcAddress As Long) As Long GetSubProcAddress = lngProcAddress End Function ' ' コールバック関数 - ワードブレイク処理 ' Public Function EditWordBreakProc _ (ByVal lpch As Long, _ ByVal ichCurrent As Long, _ ByVal cch As Long, _ ByVal action As Long) As Long End Function