■ 現在のこのページの役立ち度:
表示されない場合こちらのリンクからもご覧になれます。
■ このページの役立ち度を評価する:
役立ち度を評価してください。
(1(左):あまり役立たない - 5(右):大変役立った):
■ ページの共有:
[ サイト内検索 ]
カスタム検索
#41233-0EM_GETSELのバグ?回避について菅野2001-04-04(水) 00:11
     #41235-0RE#41233:EM_GETSELのバグ?回避について魔界の仮面弁士2001-04-04(水) 00:58
     #41238-0RE#41235:EM_GETSELのバグ?回避について菅野2001-04-04(水) 02:01
     #41244-0RE#41238:EM_GETSELのバグ?回避について魔界の仮面弁士2001-04-04(水) 10:24
#41233-0
EM_GETSELのバグ?回避について
EM_GETSELを使いキャレットのある場所を得ようとすると、65535バイト目までは正常に値を得られるので
すが、それを上回るテキストを処理する場合、滅茶苦茶の値が帰ってきてしまいます。ちゃんとしてエディ
タなどは、このような問題は無いので何らかの回避方法があると思うのですがわかりません。どなたか教え
てください。お願いします。
#41235-0
RE#41233:EM_GETSELのバグ?回避について
> EM_GETSELを使いキャレットのある場所を得ようとすると、65535バイト目までは正常に値を得られるので
> すが、それを上回るテキストを処理する場合、滅茶苦茶の値が帰ってきてしまいます。

どのような開発環境で、どのようなコードを書いているのでしょうか?

こちらで試してみましたが、こちらでは 100KBを超えるテキストであっても、
問題なく wParam, lParamに値が返ってきたのですが…。

# Win2000/SP1, VB6/SP5

Option Explicit

Private Const EM_GETSEL As Long = &HB0&

Private Declare Function SendMessage Lib "user32" _
                  Alias "SendMessageA" _
   (ByVal hWnd As Long, _
    ByVal wMsg As Long, _
    ByRef wParam As Long, _
    ByRef lParam As Long) As Long

Private Function SLng2ULng(ByVal SignedValue As Long) As Currency
    If SignedValue < 0 Then
        '4294967296 = 100000000h
        SLng2ULng = CCur(SignedValue) + 4294967296@
    Else
        SLng2ULng = CCur(SignedValue)
    End If
End Function

Private Sub Command1_Click()
    Dim ret As Long
    Dim SelStart As Long
    Dim SelLength As Long
    Dim buf As String
    
    With RichTextBox1
        SelStart = LenB(StrConv(Left(.Text, .SelStart), vbFromUnicode))
        SelLength = LenB(StrConv(Mid(.Text, .SelStart + 1, .SelLength), vbFromUnicode))
        
        Label1.Caption = SelStart
        Label2.Caption = SelStart + SelLength
        
        ret = SendMessage(RichTextBox1.hWnd, EM_GETSEL, SelStart, SelLength)
        
        Label3.Caption = SLng2ULng(SelStart)
        Label4.Caption = SLng2ULng(SelLength)
    End With
End Sub
#41238-0
RE#41235:EM_GETSELのバグ?回避について
舌足らずな説明で申し訳ありませんでした。開発環境はVB6(SP4) WIN98SE DOS/V IE5.5です。
 
> Private Function SLng2ULng(ByVal SignedValue As Long) As Currency
>     If SignedValue < 0 Then
>         '4294967296 = 100000000h
>         SLng2ULng = CCur(SignedValue) + 4294967296@
>     Else
>         SLng2ULng = CCur(SignedValue)
>     End If
> End Function

この関数の行っている処理の意味がわかりません。CCurは通貨型への変換関数でしょうか?
この関数は長整数型を通貨型に変換しているのですか?そして+4294967296@とはどのような
意味があるのでしょうか?そして最後の@マークはどういう意味なのでしょうか?初歩的な
質問ですみません。 m(_ _)m
#41244-0
RE#41238:EM_GETSELのバグ?回避について
> 開発環境はVB6(SP4) WIN98SE DOS/V IE5.5です。
この環境を用意して試してみましたが、やはり問題なく取得できています。(^_^;

先にもたずねましたが、「どのようなコードを書いているのでしょうか?」
コードを見せてもらえれば、どこが間違っているのか指摘することができますので、
うまくいかなかったコードを提示してください。m(_ _)m


> この関数の行っている処理の意味がわかりません。
あまり気にしなくても良いです。
この関数を介さなかったとしても、2GB以下のデータで有れば
問題なく処理できますので、事実上、使わなくても問題はないでしょう。


> この関数は長整数型を通貨型に変換しているのですか?
この関数の意味ですが、「符号付き32bit整数型」を「符号無し32bit整数型」に変換する物です。
(関数名の[SLng2ULng]は、[Signed Long To Unsigned Long]程度の意味です。)


> そして+4294967296@とはどのような意味があるのでしょうか?
例えば、16bitの整数型について考えてみましょう。

VBでは、符号付き16bit整数型(いわゆる Integer 型) の最大値は 32767 です。
そして、符号無し16bit整数型(対応するVBの型は無い)の最大値は 65535 です。

これらはメモリ上で、以下のような対応をとります。
    符号無し      符号付き
 ----------------------------
        0              0
        1              1
        2              2
       :             :
       :             :
    32767           32767
    32768          -32768
    32769          -32767
    32770          -32766
       :             :
       :             :
    65534              -2
    65535              -1


これは、16進数化してみると、
  Debug.Print Hex( 32770)
  Debug.Print Hex(-32766)
それぞれが同じ文字列を返すことからも判断できます。

で、上記より「符号付き16bit→符号無し16bit」を返す関数を作れば、
  Private Function SInt2UInt(ByVal SignedValue As Integer) As Long
      If SignedValue < 0 Then
          '65536 = 10000h
          SInt2UInt = CLng(SignedValue) + 65536
      Else
          SInt2UInt = CLng(SignedValue)
      End If
  End Function
となるわけです。
(VBでは符号無し16bit型が無いため、65536以上の値を返すために、
  Integerの代わりにLongを使っている事に注意してください。)

先の関数は、これの32bit版というわけです。


> そして最後の@マークはどういう意味なのでしょうか?
「型宣言文字」のひとつです。(ヘルプで 通貨型 (Currency) を調べると載っています。)

  Debug.Print TypeName(4294967296)
を実行してみるとわかりますが、VBはこれを Double型と判断します。
このままでも問題はないのですが、いわゆる「浮動小数点型」は小数点誤差が
発生する可能性があるので、明示的に 通貨型を指定したと言うわけです。


…以上、駆け足で説明しましたが、わかっていただけたでしょうか?(汗)
このページと関連する記事:
#18587-0負になってしまうのを回避できますか?2001-02-09(金) 15:07
#13028-016進数の負の数表示2000-01-12(水) 19:16
#6799-0ビット計算2000-03-21(火) 06:00
#5865-0色値の判断2002-03-11(月) 16:26
#28785-0unsigned型の扱い方2002-05-20(月) 12:53
#17618-0データ型について2001-01-09(火) 09:11
#10275-032ビット2000-05-10(水) 15:02
#18600-0テキストボックスの中の座標2001-11-04(日) 07:53
#44587-0EM_GETSELの怪現象2001-06-30(土) 23:22
#753-0Len関数で、正しい数値が返ってこない。1999-08-11(水) 10:35
お探しの情報は見つかりましたか?お困りの問題は解決しましたか?
サイト内検索, 似た記事検索で見つからなくてもあきらめずに掲示板で質問してみましょう。
VB初心者友の会があなたのお役に立てれば幸いです。また、本ページの投稿者の方々にこの場を借りて感謝致します。
本ページは過去ログを集めて自動構成しています。よろしければこのページに関するフィードバックをお願いします。
(※ 構成の誤り、広告等の不適切な記事、リンク切れ、読めないページの報告など)