トップ回答者
SetCaretPosでキャレットを設定しても、入力時に元の場所に戻ってしまう。

質問
-
現在VBAのコーディングの高速化のためにVBEのcomアドインを作っています。
「現在の行をコメントにする」というものをとりあえず作りました。
ところがReplaceLineメソッドで行を変更するとキャレットの位置が下にずれてしまいます。
なのでキャレットの位置を元に戻すためにGetCaretPosのあとにReplaceLineメソッドを実行し、
その後SetCaretPosを呼び出せばキャレットの位置を復元出来ると思いましたが
見かけのキャレットの位置は同じままなのですが、文字を入力すると元の場所(下の行)へ文字が入ってしまいました。
VBEのキャレット(入力)位置を制御したいのですがどのようにすればよいでしょうか?ぜひご教示お願いします。
Option Compare Binary Option Explicit Private Type POINT X As Long Y As Long End Type Private Declare Function GetCaretPos Lib "user32" ( _ ByRef lpPoint As POINT) As Long Private Declare Function SetCaretPos Lib "user32" ( _ ByVal X As Long, _ ByVal Y As Long) As Long Private pVBE As VBE Private WithEvents Addin As CommandBarButton Private Sct(3) As Long Private pPoint As POINT Private nCode As String Private Sub AddinInstance_OnConnection( _ ByVal Application As Object, _ ByVal ConnectMode As AddInDesignerObjects.ext_ConnectMode, _ ByVal AddInInst As Object, _ custom() As Variant) Set pVBE = Application 'アドインボタン追加 Set Addin = pVBE.CommandBars("メニュー バー").Controls.Add(msoControlButton) With Addin 'ショートカットキー等設定する .Caption = "Quick(&S)" .Style = msoButtonCaption End With End Sub Private Sub Addin_Click( _ ByVal Ctrl As Office.CommandBarButton, _ CancelDefault As Boolean) With pVBE.ActiveCodePane '現在の入力行を取得 .GetSelection Sct(0), Sct(1), Sct(2), Sct(3) With .CodeModule '現在の行の内容取得 nCode = .Lines(Sct(0), 1) '先頭にシングルクォート追加 nCode = "'" & nCode 'キャレット位置取得 GetCaretPos pPoint '行を置換する .ReplaceLine Sct(0), nCode 'キャレット位置復元 SetCaretPos pPoint.X, pPoint.Y End With End With End Sub
回答
-
きちんと実験していないので推測になりますが、キャレット位置の管理が独自に実装されているのではないでしょうか。
せっかくなので、GetSelection と対になる SetSelection を使ってみては?GetSelection であらかじめ現在位置を得ているようですし。(もし、試した後でうまくいっていなかったのであればごめんなさい)
文字が入るのはカーソル位置ではないでしょうか?、カーソルを移動してから、キャレットを移動させたと思います。キャレット位置だけで十分なのでしょうか?
文字の入力位置を表す言葉は キャレット です。カーソルを移動するというのは何を意図されているかわかりませんが、「文字入力位置を表すカーソル」のつもりであれば、「キャレット」と同義と言えます。
キャレットと書かず、カーソルと書く文献・分野もあると思いますが、どちらも同じものだと、私はとらえています。(少なくとも文字入力位置を表す場合において)
- 編集済み AzuleanMVP 2012年7月28日 3:09
- 回答としてマーク sskr 2012年7月28日 13:55
すべての返信
-
Fuda1です。
文字が入るのはカーソル位置ではないでしょうか?、カーソルを移動してから、キャレットを移動させたと思います。キャレット位置だけで十分なのでしょうか?イメージとして、SetConsoleCursorPosition http://msdn.microsoft.com/ja-jp/library/cc429740.aspxこんな事ができれば良いのかなぁと思ってます。VBEが、コンソールと同じか試さないと行けないのですが、今、別件で急いでますので、後でテストして見ます。
Win32API コンソールスクリーンバッファのカーソル位置を設定する
http://d.hatena.ne.jp/s-kita/20100926/1285470932- 編集済み 電子の妖精 2012年7月28日 2:34
-
きちんと実験していないので推測になりますが、キャレット位置の管理が独自に実装されているのではないでしょうか。
せっかくなので、GetSelection と対になる SetSelection を使ってみては?GetSelection であらかじめ現在位置を得ているようですし。(もし、試した後でうまくいっていなかったのであればごめんなさい)
文字が入るのはカーソル位置ではないでしょうか?、カーソルを移動してから、キャレットを移動させたと思います。キャレット位置だけで十分なのでしょうか?
文字の入力位置を表す言葉は キャレット です。カーソルを移動するというのは何を意図されているかわかりませんが、「文字入力位置を表すカーソル」のつもりであれば、「キャレット」と同義と言えます。
キャレットと書かず、カーソルと書く文献・分野もあると思いますが、どちらも同じものだと、私はとらえています。(少なくとも文字入力位置を表す場合において)
- 編集済み AzuleanMVP 2012年7月28日 3:09
- 回答としてマーク sskr 2012年7月28日 13:55
-
Fuda1様、Azulean様、ご返事いただきありがとうございます。
Azulean様のご回答である「SetSelection」を使うことで、今回の問題は解決しました。
自分で「GetSelection」を使っていながら、「キャレットの制御」という観点から「SetSelection」を使うとは
思ってもいませんでしたので「言われてみれば…」という感じがして少し恥ずかしく思います。
Azulean様の回答を「回答としてマーク」させて頂きます。
返事をくださったお二方に重ねてお礼申し上げます。またよろしくお願いします。sskr
差分のコード
Private Sub Addin_Click( _ ByVal Ctrl As Office.CommandBarButton, _ CancelDefault As Boolean) With pVBE.ActiveCodePane '現在の入力行を取得 .GetSelection Sct(0), Sct(1), Sct(2), Sct(3) With .CodeModule '現在の行の内容取得 nCode = .Lines(Sct(0), 1) '先頭にシングルクォート追加 nCode = "'" & nCode '行を置換する .ReplaceLine Sct(0), nCode End With 'キャレット位置を復元 .SetSelection Sct(0), Sct(1), Sct(2), Sct(3) End With End Sub