sha5010 / vim.xlam

Vim experience in Excel: An add-in that brings Vim’s key bindings to Excel, enhancing navigation and efficiency.
MIT License
68 stars 6 forks source link

Excelの古いバージョンへの対応について #41

Closed sdys-box closed 6 months ago

sdys-box commented 6 months ago

お世話になっております。 VimExcelが2.0になり動かなくなったので、こちらを利用させていただきました。

当方、Windows10 64bit で Office2007 32bit を使っております。 この環境ではINSERTモードにするとフリーズ^1するようで、C_KeyStrokeを修正すると動くようになりました。 具体的にはモジュールの宣言のところでAPIの戻り値をIntergerに変更しました。

    Public Declare Function GetAsyncKeyState Lib "User32.dll" (ByVal vKey As Long) As Integer
    Public Declare Function GetKeyState Lib "User32.dll" (ByVal vKey As Long) As Integer

IF文で分岐するのだと思いますがやり方が分からず、もし簡単に直るのでしたらご対応いただければ幸いです。

珍しい環境かと思いますのでご面倒ならば修正不要です。

sha5010 commented 6 months ago

ご連絡ありがとうございます。 該当する部分のコードを見直しましたが、そもそも戻り値にLong型を指定していること自体おかしいかもしれないですね。 当方、Windows10 Excel2013 32bitの環境で主に開発していますが、Integerにして問題ないか確かめてみます。

1点ご確認させてください。 実は私の中で、CtrlやShiftが押しっぱなしになる問題は把握しているのですが、対処法がなく諦めています。 この問題はキーを仮想的に押して離す処理をする際、

  1. Ctrl/Shift/Altが押されているか取得する
  2. 押されているキーは押しっぱなしにするよう命令を飛ばす
  3. キーイベントによってキーが押される

という感じなのですが、1〜3の間に0.02〜0.04秒くらいのラグが生じるため、そこでキーを離しても押されたままになるという現象です。

Q. Long型の時は毎回発生していたのが、Integer型に変更したらほとんど発生しなくなりましたか?(たまたま治ったように見えただけの可能性を懸念しています)

sdys-box commented 6 months ago

ご対応ありがとうございます。

Long型の場合、「i」キーを押下してINSERTモードにすると必ず発生します。 Interger型では快適に使えています(使い始めたばかりなのでまだわかりませんが)。

Long型に戻してから調べると、初期状態からiキーを押したときに

Private Sub StrokeSingleKey(ByVal key As Long, Optional ByVal ignoreKeyUp As Boolean = False)
    ''''中略
    ' Get current key status
    pHoldShiftLeft = ((GetKeyState(ShiftLeft_) And &H8000) <> 0) And Not ignoreKeyUp
    pHoldShiftRight = ((GetKeyState(ShiftRight_) And &H8000) <> 0) And Not ignoreKeyUp
    pHoldCtrlLeft = ((GetKeyState(CtrlLeft_) And &H8000) <> 0) And Not ignoreKeyUp
    pHoldCtrlRight = ((GetKeyState(CtrlRight_) And &H8000) <> 0) And Not ignoreKeyUp
    pHoldAltLeft = ((GetKeyState(AltLeft_) And &H8000) <> 0) And Not ignoreKeyUp
    pHoldAltRight = ((GetKeyState(AltRight_) And &H8000) <> 0) And Not ignoreKeyUp

の箇所で左辺の変数が全てTrueとなっており、続くkeybd_eventで左右のShift/Ctrl/Altが全て押された状態になるようです。 Long型のときはGetKeyState()の戻り値が意図しない値になっているのではないかと思います。

sha5010 commented 6 months ago

Integer型で不具合なく使えているとのことで良かったです。

GetKeyState関数を調べてみたところ、戻り値がShort型でした。 https://learn.microsoft.com/ja-jp/windows/win32/api/winuser/nf-winuser-getkeystate

Short型は2バイトなので、VBAではInteger型が正しかったです。

少なくとも64bit版の読み込みはInteger型にしていて、64bit版のExcelでは不具合ないので、Integer型に修正することでクローズとしたいと思います。 次回リリース時に反映させていただきます。ご連絡ありがとうございました!

sdys-box commented 6 months ago

v0.5.3をインストールし動作することを確認いたしました。 早々にご対応いただきありがとうございました。