Ticket #33260

Visual Basic 6 アプリケーションの複数行エディットで改行位置が正しく認識されない

Open Date: 2014-02-24 20:22 Last Update: 2014-03-05 14:20

Reporter:
Owner:
(None)
Type:
Status:
Closed
Component:
(None)
MileStone:
Priority:
5 - Medium
Severity:
5 - Medium
Resolution:
Fixed
File:
None

Details

Visual Basic 6 で開発されたアプリケーションのフォームに複数行エディット(ThunderRT6TextBox)が使われていると、そのコントロールの中のテキストの改行位置が正しく認識されないという現象を確認しました。

テスト環境は Windows 8.1(64ビット)+ NVDA 日本語テスト版 jpbeta140223 です。

テスト用の VB6 アプリケーションはお問い合わせをされたかたから提供していただきました。

例えば、以下のようにエディットにテキストを貼り付けて、 上下の矢印キーで移動すると、見えている行頭とは違う場所が行頭として認識されています。

NVDAによって視覚障害者は、
Windowsオペレーティングシステムやサードパーティー製の
アプリケーションを使えるようになります。 
NVDAの主な特徴は以下の通りです。

また、レビューカーソルを先頭から1文字ずつ右に移動すると、2行目の「オペレーティング」の長音で「みぎ」と通知され、この文字が行末として認識されていることがわかります。

Ticket History (3/11 Histories)

2014-02-24 20:22 Updated by: nishimoto
  • New Ticket "Visual Basic 6 アプリケーションの複数行エディットで改行位置が正しく認識されない" created
2014-02-24 20:56 Updated by: nishimoto
Comment

追加ですが、英語の(マルチバイト文字を含まない)テキストの場合は、行末位置のずれは起こっていません。

まだあまりちゃんと調査していませんが source/NVDAObjects/window/edit.py で使われている EM_LINELENGTH が "For ANSI text, this is the number of bytes" を返す仕様になっていることと関係があるような気がします。

http://msdn.microsoft.com/ja-jp/library/bb761613.aspx

2014-02-24 21:46 Updated by: nishimoto
Comment

本家版 2014.1rc1 で再現できたので、本家にチケットを書きました。

http://community.nvda-project.org/ticket/3918

2014-02-25 08:41 Updated by: nishimoto
Comment

jteh さんからコメントをもらいました:

it's quite tricky to detect the encoding for an ANSI control. We'd probably have to go in-process (in-thread actually) and call GetThreadLocale.

どうやら Python 部分だけの修正では直せないようです。

2014-02-26 15:22 Updated by: nishimoto
Comment

後述のデバッグコードで検証してみました。

エディットの内容:

ああああ
hello

パッチ(ブランチ ti33260):

diff --git a/source/NVDAObjects/window/edit.py b/source/NVDAObjects/window/edit.py
index 362fe1b..4325254 100644
--- a/source/NVDAObjects/window/edit.py
+++ b/source/NVDAObjects/window/edit.py
@@ -422,6 +422,10 @@ class EditTextInfo(textInfos.offsets.OffsetsTextInfo):
                lineNum=self._getLineNumFromOffset(offset)
                start=watchdog.cancellableSendMessage(self.obj.windowHandle,EM_LINEINDEX,lineNum,0)
                length=watchdog.cancellableSendMessage(self.obj.windowHandle,EM_LINELENGTH,offset,0)
+               if not self.obj.isWindowUnicode:
+                       import tones
+                       tones.beep(880,10)
+                       log.info("lineNum %d, start %d, length %d" % (lineNum,start, length))
                end=start+length
                #If we just seem to get invalid line info, calculate manually
                if start<=0 and end<=0 and lineNum<=0 and self._getLineCount()<=0 and self._getStoryLength()>0:

カーソルの上下の移動のログ:

INFO - NVDAObjects.window.edit.EditTextInfo._getLineOffsets (15:01:15):
lineNum 0, start 0, length 8
INFO - NVDAObjects.window.edit.EditTextInfo._getLineOffsets (15:01:16):
lineNum 1, start 10, length 5

ということで、isWindowUnicode が False になっていること、start と length が全角1文字を2バイトで数えている、改行の CR/LF を2バイトで数えている、などの可能性が高いです。

本家チケットではなぜ isWindowUnicode で判定できないのか聞いてみたのですが「ANSI であったとしてもロケールがシステムデフォルト(いわゆる Shift JIS) とは限らないため、プロセスにフックして GetThreadLocale する必要がある」とのことでした。

日本で開発された非 Unicode のアプリケーションで Shift JIS 以外を考慮する必要はないと思いますが、ユニバーサルに対応するなら彼らの言うとおりでしょうね。。

状況としては、いつ本家が着手するか不明です。

ちょっとだけ調べてみた Visual Basic 6.0 の国際化に関する資料:

http://msdn.microsoft.com/en-us/library/aa261360%28v=vs.60%29.aspx

2014-03-01 22:40 Updated by: nishimoto
Comment

Unicode でない場合は mbcs で決め打ちするという前提で対策を実装してみました。

[ti33260 c4c0031] work around _getLineOffsets
 1 file changed, 11 insertions(+), 4 deletions(-)

ただし、下記のような内容で行の区切りは正しくなったのですが、行のインデックスが正しく認識されていないので、EM_LINEFROMCHAR もどうやら対策が必要らしいです。。

1ぎょうめ
2ぎょうめ
あああ
Text1
INFO - NVDAObjects.window.edit.EditTextInfo._getLineOffsets (22:34:46):
offset 0 lineNum 0 start 0 end 10 buf 1ぎょうめ start_new 0 end_new 5
INFO - NVDAObjects.window.edit.EditTextInfo._getLineOffsets (22:34:52):
offset 7 lineNum 0 start 0 end 10 buf 1ぎょうめ start_new 0 end_new 5
INFO - NVDAObjects.window.edit.EditTextInfo._getLineOffsets (22:34:55):
offset 14 lineNum 1 start 12 end 22 buf 2ぎょうめ start_new 7 end_new 12
INFO - NVDAObjects.window.edit.EditTextInfo._getLineOffsets (22:34:56):
offset 19 lineNum 1 start 12 end 22 buf 2ぎょうめ start_new 7 end_new 12
INFO - NVDAObjects.window.edit.EditTextInfo._getLineOffsets (22:34:58):
offset 26 lineNum 2 start 24 end 30 buf あああ start_new 14 end_new 17
INFO - NVDAObjects.window.edit.EditTextInfo._getLineOffsets (22:34:59):
2014-03-02 00:20 Updated by: nishimoto
Comment

いちおう EM_LINEFROMCHAR も含めて対策してみました。

[ti33260 888b82e] work around ti33260
 1 file changed, 21 insertions(+), 8 deletions(-)
2014-03-02 11:24 Updated by: nishimoto
Comment

NVDA 日本語テスト版 jpbeta140302 https://dl.dropboxusercontent.com/u/62564469/nvda_jpbeta140302.exe

特定の開発ツールやAPIで作られたアプリケーションが、 複数行エディットでカーソル位置や改行位置が不正確になる、 というご指摘を他にもいただいていたので、 この修正が有効かどうかご検討いただけると助かります。

2014-03-03 10:52 Updated by: nishimoto
  • Milestone Update from (None) to 2014.1jp (closed)
  • Resolution Update from None to Fixed
Comment

NVDA 日本語テスト版 jpbeta140303 https://dl.dropboxusercontent.com/u/62564469/nvda_jpbeta140303.exe

VoicePopper のフリーズ対策、ANSI アプリケーションの改行位置対策が、このビルドには含まれています。

これらの変更によって新たな副作用が起きているかどうかを確認することが、このビルドの目的です。

もし新しい副作用があるなら #33037#33260 は 2014.2jp に延期します。

いままでと同じ状況(存在するその他の不具合の状況に変化がない)ならば、影響なしとみなして、2014.1jp への採用とさせていただきます。

スケジュールとしては、本家の 2014.1 が正式にリリースされたら、日本語版については、電子署名付きのリリース候補版を作りたいと思っています。

補足説明:

ブランチ jp2014.1 と ti33037v2 と ti33260 を jpnext にマージしました。

この jpnext ブランチから jpbeta140303 をビルドしました。

点訳エンジンの修正は jp2014.1 ブランチに反映されています。

2014-03-03 13:41 Updated by: nishimoto
Comment

比較のために ti33037v2 と ti33260 をマージしていないビルドも作りました。

NVDA 日本語テスト版 jpbeta140303s https://dl.dropboxusercontent.com/u/62564469/nvda_jpbeta140303s.exe

2014-03-05 14:20 Updated by: nishimoto
  • Ticket Close date is changed to 2014-03-05 14:20
  • Status Update from Open to Closed
Comment

本件の対策を含むブランチ jpnext を jp2014.1 にマージします。

Attachment File List

No attachments

Edit

Please login to add comment to this ticket » Login