ユーザーからの要望で実装した機能。あるフォームを表示したまま手作業を行うことがあり、その際にスクリーンセーバーを起動したくない(他の場面ではスクリーンセーバーを起動したい)という要望があり、アプリ上で実現した。
Imports System
Imports System.Runtime.InteropServices
Imports System.Threading
''' <summary>
''' 仮想マウスクラス
''' </summary>
''' <remarks>
''' 仮想マウスを定義し、カーソルを動かす
''' </remarks>
Public Class VirtualMouse
''' <summary>実行状態</summary>
<Flags>
Public Enum EXECUTION_STATE As UInteger
ES_SYSTEM_REQUIRED = &H1
ES_DISPLAY_REQUIRED = &H2
ES_CONTINUOUS = &H4C4B400
End Enum
''' <summary>マウス入力構造体</summary>
<StructLayout(LayoutKind.Sequential)>
Structure MOUSEINPUT
Public X As Integer
Public Y As Integer
Public MouseData As UInteger
Public Flags As UInteger
Public Time As UInteger
Public ExtraInfo As IntPtr
End Structure
''' <summary>キーボード入力構造体</summary>
<StructLayout(LayoutKind.Sequential)>
Structure KEYBDINPUT
Public Vk As UShort
Public Scan As UShort
Public Flags As UInteger
Public Time As UInteger
Public ExtraInfo As IntPtr
End Structure
''' <summary>ハードウェア入力構造体</summary>
<StructLayout(LayoutKind.Sequential)>
Structure HARDWAREINPUT
Public Msg As UInteger
Public ParamL As UShort
Public ParamH As UShort
End Structure
''' <summary>入力情報構造体</summary>
<StructLayout(LayoutKind.Explicit)>
Structure INPUT
<FieldOffset(0)>
Public Type As Integer
<FieldOffset(4)>
Public Mouse As MOUSEINPUT
<FieldOffset(4)>
Public Keybd As KEYBDINPUT
<FieldOffset(4)>
Public Hardware As HARDWAREINPUT
End Structure
''' <summary>キーストローク、マウスの動き、ボタンのクリックを合成する</summary>
''' <param name="InputSize">入力イベントの数</param>
''' <param name="Input">送信する入力イベント</param>
''' <param name="Size">入力イベント構造体のサイズ</param>
''' <returns></returns>
''' <remarks>送信できた入力イベント数</remarks>
Declare Function SendInput Lib "user32.dll" (ByVal InputSize As UInteger, ByRef Input As INPUT, ByVal Size As Integer) As UInteger
''' <summary>マウス入力</summary>
Const INPUT_MOUNSE As Integer = 0
''' <summary>スクリーンセーバー起動を防ぐ</summary>
Public Sub Execute()
' 処理は繰り返す
Do While True
' 仮想マウスのカーソルを動かす
VirtualMouse.Send()
' 1分間待機
Thread.Sleep(60 * 1000)
Loop
End Sub
''' <summary>仮想マウスカーソルを動かす</summary>
''' <remarks>正常送信されたイベントの数、0の場合は別のスレッドでロックされている</remarks>
Private Sub Send()
' 入力イベントを作成
Dim Input As INPUT = New INPUT()
Input.Type = INPUT_MOUNSE
Input.Mouse = New MOUSEINPUT()
Input.Mouse.ExtraInfo = IntPtr.Zero
Input.Mouse.X = 0
Input.Mouse.Y = 0
Input.Mouse.Time = 0
Input.Mouse.MouseData = 0
Input.Mouse.Flags = &H1 ' MOVE (RELATIVE)
' 入力イベント構造体のサイズ
Dim size As Integer = Marshal.SizeOf(GetType(INPUT))
' 入力イベントを送信し、結果を取得する
Dim result As UInteger = SendInput(1, Input, size)
End Sub
End Class