Windows API で PC サスペンド

PC をスタンバイ状態に移行する Windows アプリケーションをつくった。ソースコードの言語は C だ。コンパイルは gccgcc -mwindows suspend.c -o suspend.exe -s -Wall として行った。

以下が、suspend.c のソースコードである。

#include <windows.h>
int WINAPI WinMain(HINSTANCE hi, HINSTANCE hp, LPSTR cl, int cs) {
  HMODULE lib = LoadLibrary("powrprof.dll");
  FARPROC SetSuspendState = GetProcAddress(lib, "SetSuspendState");
  SetSuspendState(FALSE, FALSE, FALSE);
  return 0;
}

あとがき

powrprof.dll をロードし、その中に入っている SetSuspendState という関数を呼び出して、スタンバイ状態に移行している。このアプリケーションが行う処理はそれだけだ。

ゴルフすると以下となる。

#include<windows.h>
WINAPI WinMain(HINSTANCE h,HINSTANCE p,LPSTR c,int s){GetProcAddress(LoadLibrary("powrprof.dll"),"SetSuspendState")(0,0,0);}

型に迷わなくていい分、案外、いい書き方かもしれない。

本来は、LoadLibrary でなく、powrprof.h を通じて SetSuspendState を使用したほうが良い気がするが、やり方がよく分からなかった。gcc の提供する include フォルダにある powrprof.h には以下のような記述がある。

BOOLEAN WINAPI SetSuspendState(BOOLEAN, BOOLEAN, BOOLEAN);

これを呼び出して実行したかったのだが、コンパイル時にエラーとなってできなかった。powrprof.dll 内の関数を使えばスタンバイ状態に移行できるという知識だけはあったので、その方法を調べたら、思ったより、簡単にできてしまった。

HMODULE lib = LoadLibrary("powrprof.dll");

DLL を呼び出すには、LoadLibrary という関数を使う。MSDN によると、この関数の戻り値は、HMODULE という型であることがわかったので、変数 lib を HMODULE 型にしてある。HMODULE 型とは、どんな型なのかは、全く知らない。

FARPROC SetSuspendState = GetProcAddress(lib, "SetSuspendState");

呼び出した DLL 内の関数への参照を得るには、GetProcAddress という関数を使って、関数名を指定する。FARPROC なる型の SetSuspendState 変数に突っ込んでいる。

SetSuspendState(FALSE, FALSE, FALSE);

SetSuspendState 変数は関数として実行可能であり、かつ、以下のようにも書けることから、FARPROC 型は、関数ポインタ型であることがわかる。

(*SetSuspendState)(FALSE, FALSE, FALSE);`