2012年11月22日木曜日

エビデンス!エビデンス!!エビデンス!!! VBAでクリップボード監視 その3

第1回 → エビデンス!エビデンス!!エビデンス!!! VBAでクリップボード監視
第2回 → エビデンス!エビデンス!!エビデンス!!! VBAでクリップボード監視 その2
ユーザーフォームのソースコード → gist
標準モジュールのソースコード → gist

最後に補足。

このマクロを含めたブックは、自動保存をOFFにしたほうが良いです。また、マクロ実行中にブックを保存した場合、保存途中にPrintScreenを押してはいけません。良い子と僕らの約束だぞ。

というのも、クリップボードの変化を検知した後に、画像をシートに貼りつける部分
Public Sub pasteToSheet()
    Dim rowIdx As Integer
     
    With Sheet1
        If .Shapes.Count > 0 Then
            With .Shapes(.Shapes.Count)
                rowIdx = (.Top + .Height) / ROW_HEIGHT + 4
            End With
        Else
            rowIdx = 1
        End If
        .Cells(rowIdx, 1).PasteSpecial
    End With
End Sub
これの、"With .Shapes(.Shapes.Count)"がエラーになるから。
なんでかはよくわからないけど、保存中は、オートシェイプがVBAから正しく認識されないっぽい。
何せ保存中なのだから、そんなことがあってもしょうがない。というわけで、自動保存も非推奨です。

あと、前回こんな風に書きました。
  1.  WM_NCHITTESTであれば…
    これは実ははまるところなのですが、クリップボードの処理に直接関係ないので、次回に飛ばします。
これについてですが、WM_NCHITTESTの時にもCase Elseのようにもともとのウィンドウプロシージャを呼び出すようにすると、マウスカーソルがフォームの中に入った途端なぜだかCPUの使用率が跳ね上がり、フォームが反応しなくなります。無限ループに陥ってるっぽい。
勝手に元ネタにさせていただいたこちらでも、同じかわからないけど、似たような現象を確認されているし・・・。

この"WM_NCHITTEST"というのは、どうやら、マウスが動いたとか、ボタンが押されたとか、とにかくマウス系のイベントが起こると真っ先に送られるものらしく(MSのデベロッパー センター デスクトップ) 試しにこのメッセージを受け取った時にDebug.Printなどしてやると、フォームの上でマウスをぐりんぐりん動かしたときに、まあ出るわ出るわ。

この無限ループっぽい動きの原因はよく分かっていないのですが、このメッセージの時だけ何もしないようにしてやれば、とりあえず大丈夫そうです。
ただしこの場合、クリップボード監視中にフォームをクリックしても、ウィンドウがアクティブになった時の色にならなくなってしまうのですが・・・まぁ動くからよし。
チェックボックスのクリックもできるし。

というわけで、VBAでクリップボード監視はこれでおしまいです。

あと改良するなら、PrintScreenを押したときに、ちゃんと「押されたよ」的なポップアップがうにょんと最前面に出るといいかもしれません。対象のウィンドウを最大化していて、Excelが後ろに隠れていると、本当にPrintScreenが押されたかどうかすぐに確認できないんですよね。

0 件のコメント:

コメントを投稿