スクリーンセーバの起動を抑制する - アセンブラ バージョン

#はじめに
うちの会社のPCは10分でスリーンセーバが起動してしまう。その度にパスワードを入力して解除するのが面倒なため、スクリーンセーバを抑制する方法を考案している。
過去に下記3つの方法を試しており、Arduino Pro MIcroと vbsバージョンを常用しています。
[スクリーンセーバの起動を抑制する - Arduino Pro Micro(の互換機)を使用](https://qiita.com/tlab/items/c83981ab5a13b858a7da)
[スクリーンセーバの起動を抑制する - vbsバージョン](https://qiita.com/tlab/items/91aea996f68667b0a0ee)
[スクリーンセーバの起動を抑制する - mpgバージョン](https://qiita.com/tlab/items/90b6fbb4c75ec1bdceda)

今回はMASM32を使用してアセンブラでプログラムを作成してみました。

#MASM32とは
MASAM32とは32 bit Microsoft assemblerであり、x86系CPUのマイクロプロセッサ用のアセンブラです。Wikipediaによれば『マイクロソフトは社内外に抱える多数のアセンブリコードのために対応を続けている。』とのことです。

アセンブラはこちらからダウンロードできます。
[MASM32 SDK Version 11 Downloads](http://www.masm32.com/download.htm) 
Windows95時代のサイトデザインですね。

##インストール
インストーラ形式になっていますので、指示に従えば問題なくインストールが可能です。私はDドライブ直下にインストールしました。

##プログラムについて
invokeにて関数呼出と同様にWindows APIもコールすることが可能です。

```asm:sample
	invoke KeyDownFnc  ;関数コール
	invoke Sleep,420000 ; APIコール
```

私は[猫でもわかるプログラミング](http://www.kumei.ne.jp/c_lang/)のWindows SDK編でWindowsプログラムを学びました。
この当時のC言語でのWindowsプログラミングの知識があれば、MASM32でWindowsプログラムを記述することは用意に可能です。要はAPIをコール手法は同じで、順番も同じ、リソースの記述も同じで、Messageのハンドル方法が同じなのです。違いは

```asm:inc
	inc	i
```
と記述するか

```c:inc
	i++
```
と記述するかという違いです。画面処理だけなら計算はあまり有りませんので、当時Cで記述したプログラムがMASM32のコードに移植するのは難しいことではありません。(やる意味があるかは別)

#プログラム1 - マウスを動かす
##マウスを動かす事によりスクリーンセーバを抑制する
まずはマウスカーソルを一定時間間隔でプログラム指令により動かし、スクリーンセーバを抑制する方法を試してみます。
**結果から言うとこの方法では抑制できませんでした**。
環境はWin10ですが、他のバージョンでは試していません。

###コンパイル用バッチファイル

```bat:MAKEmmove.bat
@echo off

if exist mmove.obj del mmove.obj
if exist mmove.exe del mmove.exe

D:\masm32\bin\ml /c /coff /nologo mmove.asm
D:\masm32\bin\Link /SUBSYSTEM:WINDOWS /MERGE:.rdata=.text mmove.obj > nul

dir mmove.*

pause
```

###アセンブリコード
5分おきにマウスを動かすプログラムにしています。テスト用途なので10回ループして終了します。

```asm:mmove.ASM
; #########################################################################
;	スクリーンセーバーをキャンセルするためにマウスを0,0動かす -> NG
;	スクリーンセーバーをキャンセルするためにマウスを100,100動かす -> NG
;
;	2018.07.18	GetMouseCurのTest version
;
; #########################################################################
      .386
      .model flat, stdcall
      option casemap :none   ; case sensitive


; #########################################################################

	include \masm32\include\windows.inc
	include \masm32\include\user32.inc
	include \masm32\include\kernel32.inc
	include \masm32\include\masm32.inc

	includelib \masm32\lib\user32.lib
	includelib \masm32\lib\kernel32.lib
	includelib \masm32\lib\masm32.lib
; #########################################################################

	.data
	loopcount	dw	10	; loop counter


	;=================
	; Local prototypes
	;=================
	SetCur PROTO

	.code

start:

MouseMoveLoop:
	
	invoke SetCur
	invoke Sleep,300000		; sleep 5 min

	dec 	loopcount
	jnz	MouseMoveLoop	;
	
	invoke ExitProcess,eax

; #########################################################################

SetCur proc

	LOCAL MousePos	:POINT

	
	invoke GetCursorPos , ADDR MousePos				; Get Mouse Pos
	add	MousePos.x, 100
	add MousePos.y, 100
	invoke SetCursorPos , MousePos.x , MousePos.y	; Set Mouse Cursor (0,0) move
	invoke Sleep, 500
	sub	MousePos.x, 100
	sub MousePos.y, 100
	invoke SetCursorPos , MousePos.x , MousePos.y	; Set Mouse Cursor (0,0) move

	ret

SetCur endp

end start

```

#プログラム2 - SHIFTキーコードを送る
**こちらは成功しました。**
##シフトキーを押下するコードを記述することで抑制します。
###コンパイル用バッチファイル

```bat:MAKEkeycode.bat
@echo off

if exist keycode.obj del keycode.obj
if exist keycode.exe del keycode.exe

D:\masm32\bin\ml /c /coff /nologo keycode.asm
D:\masm32\bin\Link /SUBSYSTEM:WINDOWS /MERGE:.rdata=.text keycode.obj > nul

dir keycode.*

pause

```

###アセンブリ用コード
動作することがわかりましたので、メッセージボックスでスタート、終了を表示する等実用性を重視したコードにしました。

```asm:mmove.ASM
; #########################################################################
;	SHIFT KEYを送付する
;
;
;	2018.07.18	GetMouseCurのTest version
;
; #########################################################################
      .386
      .model flat, stdcall
      option casemap :none   ; case sensitive


; #########################################################################

	include \masm32\include\windows.inc
	include \masm32\include\user32.inc
	include \masm32\include\kernel32.inc
	
	includelib \masm32\lib\user32.lib
	includelib \masm32\lib\kernel32.lib
; #########################################################################

	.data
	loopcount	dw	35	; loop counter  35x7 = 245 (4Hrs)

	MsgBoxCaption	db	"AntiScreenSaver", 0	; Title of messageBox
	MsgBoxText_Strt		db	"Activate Anti-Screen Saver." ,0	; massege

	MsgBoxText_End		db	"Stopped Anti-Screen Saver." ,0	; massege

	;=================
	; Local prototypes
	;=================
	KeyDownFnc PROTO

	.code

start:

;	Show MessageBox
	invoke MessageBox, NULL, addr MsgBoxText_Strt, addr MsgBoxCaption, MB_OK + 40h	; 40h = MB_ICONINFORMATION

MouseMoveLoop:
	
	invoke KeyDownFnc
	invoke Sleep,420000		; sleep 7 min

	dec 	loopcount
	jnz	MouseMoveLoop	;
	
	invoke MessageBox, NULL, addr MsgBoxText_End, addr MsgBoxCaption, MB_OK + 10h ; 10h = MB_ICONSTOP
	invoke ExitProcess,eax

; #########################################################################

KeyDownFnc proc

	invoke		keybd_event , VK_LSHIFT , 0 , 0, 0
	invoke Sleep, 100
	invoke		keybd_event , VK_LSHIFT , 0 , KEYEVENTF_KEYUP, 0

	ret

KeyDownFnc endp

end start

```

#動作
##基本動作
コンパイル後に生成されるkeycode.exeを起動すると、メッセージボックスが表示されます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/211703/7fb5c538-439d-2c02-03ee-8bbfd0825146.png)

245分(7分ｘ35回)後プログラムは終了し下記のメッセージボックスを表示します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/211703/a13ecdba-c334-1eb9-061d-e9c77f282bbe.png)

##途中終了方法
用意していません。タスクマネージャでkeycode.exeを強制終了してください。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/211703/97103c0f-806e-ca4d-98bc-989f56aff3a9.png)


#おわりに
アセンブラを使用するとWindowsであっても、ワンチップマイコンのプログラムの様にCPUをコントロールしてる感じがします。今ではArduinoの様にC++でお手軽にプログラム可能ですが、初めてPIC16F84を使用したときのワクワク感を思いだしてしまいました。
趣味としてのプログラムであればMASMも面白いものです。

2018/07/19 Ikeda