HSP3 あれこれ <システム>

Last Update : 2009/01/xx

システムサウンドを鳴らす

 Windowsが用意してる警告音などのシステムサウンドをMessageBeep関数を利用して再生してみます。どのような音が再生されるかは、Windowsの設定次第です。

//	システムサウンドの再生1 by Kpan

#include "user32.as

;	$30は警告メッセージ音。その他はちょくとさんのページ参照。
	MessageBeep $30

 ちなみに、WAVEファイルの再生を行うPlaySound関数でも可能です。

//	システムサウンドの再生2 by Kpan

#include "winmm.as"

;	第1パラには以下のようなパラメータを指定。
;		「SystemAsterisk」(情報)、「SystemExclamation」(警告)、
;		「SystemHand」(エラー)、「SystemQuestion」(問い合わせ)、
;		「SystemStart」(Windows起動)、「SystemExit」(Windows終了)
;	第3パラには再生方法を指定。
;		$1=再生終了まで待たない、$8=ループ再生、など
	PlaySound "SystemStart", 0, $1

↑TOP↑

特殊なダイアログを開く

 Windowsの少し特殊なダイアログを開きます(一部特殊な処理)。キー送信のkeybd_event関数で同じ効果が得られる処理もいくつかあります。

//	特殊処理いろいろサンプル (by Kpan)

#include "user32.as"

#define WM_COMMAND $111

;	タスクバーのハンドルを取得
	FindWindow "shell_traywnd", 0
	hTraywnd = stat

;	以下、sendmsg命令でWM_COMMANDメッセージを送信送る

;	ファイル名を指定して実行 ダイアログ
	sendmsg hTraywnd, WM_COMMAND, $191

;	Windowsのログオフ ダイアログ
;	sendmsg hTraywnd, WM_COMMAND, $192

;	日付と時刻のプロパティ
;	sendmsg hTraywnd, WM_COMMAND, $198

;	タスクバーとスタートメニューのプロパティ
;	sendmsg hTraywnd, WM_COMMAND, $19D

;	すべてのウィンドウを最小化する
;	sendmsg hTraywnd, WM_COMMAND, $19F

;	最小化したウィンドウを元に戻す
;	sendmsg hTraywnd, WM_COMMAND, $1A0

;	Windows タスクマネージャ
;	sendmsg hTraywnd, WM_COMMAND, $1A4

;	コントロールパネル
;	sendmsg hTraywnd, WM_COMMAND, $1F9

;	コンピュータの電源を切る ダイアログ
;	sendmsg hTraywnd, WM_COMMAND, $1FA

;	プリンタとFAX
;	sendmsg hTraywnd, WM_COMMAND, $1FE

↑TOP↑

バージョン情報ダイアログ

 dialog命令で普通のダイアログボックスは表示できますが、こちらはWindowsのシステムが用意してるバージョン情報ダイアログです。ShellAbout関数を呼びます。HSP2のllmod.asモジュールに用意されてたabout命令と同機能です。

//	システムのバージョン情報表示1 (by Kpan)

#include "shell32.as"

;	バージョン情報ダイアログ+アイコンなし
	ShellAbout hwnd, "あいうえおー", "最後の部分", 0

;	「#」(シャープ)を含めると、前がタイトル名、後がダイアログ内文字として反映
	ShellAbout hwnd, "タイトル名#ダイアログ内文字列", "最後の部分", 0
//	システムのバージョン情報表示2 (by Kpan)
//	<実行ファイルのアイコン表示バージョン>

#include "user32.as"
#include "shell32.as"

	LoadIcon hinstance, 128
	ShellAbout hwnd, "Let's HSP!#HSP情報サイトだよーん", "よろしこ、ちょりーす!", stat

↑TOP↑

Windows OSの種類の判別

 HSP2にはWindowsの種類(バージョン情報)を取得するllmod.asモジュールのwinver命令が用意されていましたが、Win32 API関数のGetVersionEx関数を呼び出していただけです。この関数を利用してOSの種類(商品名)を表示してみるサンプルコードです。

 ちなみに、この関数内で登場する「OSVERSIONINFO構造体」については、ちょくとさんのページMSDNのページ(英語)を参照してください。また、このMSDNページには、sysinfo関数で取得できるバージョン情報文字列の一覧も掲載されてます。たとえば、Windows XPは「5.1」、Vistaは「6.0」、7は「6.1」です。この数値から判別する手法でもいいですなー。o(^^ )

バージョン Windowsの商品名
メジャーバージョン 4 Windows 95 / Windows 98 / Windows Me
5 Windows 2000 / Windows XP / Windows Server 2008
6 Windows Server 2008 / Windows Vista / Windows 7 / Windows 8
マイナーバージョン 0 Windows 95 / Windows 2000 / Windows Server 2008 /
Windows Vista
1 Windows XP / Windows 7
2 Windows Server 2003 / Windows XP Professional x64 Edition / Windows 8
10 Windows 98
90 Windows Me
プラットフォームID 1 [9x系] Windows 95 / Windows 98 / Windows Me
2 [NT系] Windows 2000 / Windows XP / Windows Server 2003 /
Windows Server 2008 / Windows Vista / Windows 7 / Windows 8
//	Windows OSの種類判別 (by Kpan)
//	(注) エディタの[HSP]メニュー→[HSP拡張マクロを使用する]を要有効。

#include "kernel32.as"

;	HSPの標準命令 sysinfo関数
	mes "sysinfo関数: "+sysinfo(0)+"\n"

	dim OSVERSIONINFO, 37
	OSVERSIONINFO = $94
	GetVersionEx varptr(OSVERSIONINFO)

;	OSVERSIONINFO構造体に以下のような数値が返る。
	mes "メジャーバージョン: "+OSVERSIONINFO.1
	mes "マイナーバージョン: "+OSVERSIONINFO.2
	mes "ビルドナンバー: "+OSVERSIONINFO.3
	mes "プラットフォームID: "+OSVERSIONINFO.4
	getstr csdversion, OSVERSIONINFO, 20	; Corrective Service Diskette
	mes "CSDバージョン: "+csdversion


;	上の数値を元に分類してみると以下のとーり。
;	(黄色部分は省略しても問題なさそうな処理)

;	プラットフォームIDが1だと、Windows 9x系OS
	if OSVERSIONINFO.4 = 1 {
		if OSVERSIONINFO.1 = 4 {
			if OSVERSIONINFO.2 = 0 {
				mes "\n[Windows 95]"
			}
			if OSVERSIONINFO.2 = 10 {
				mes "\n[Windows 98]"
			}
			if OSVERSIONINFO.2 = 90 {
				mes "\n[Windows Me]"
			}
		}
	}

;	プラットフォームIDが2だと、Windows NT系OS
	if OSVERSIONINFO.4 = 2 {
		if OSVERSIONINFO.1 = 4 {
			if OSVERSIONINFO.2 = 0 {
				mes "\n[Windows NT 4.0]"
			}
		}
		if OSVERSIONINFO.1 = 5 {
			if OSVERSIONINFO.2 = 0 {
				mes "\n[Windows 2000]"
			}
			if OSVERSIONINFO.2 = 1 {
				mes "\n[Windows XP]"
			}
			if OSVERSIONINFO.2 = 2 {
				mes "\n[Windows Server 3000]"
			}
		}
		if OSVERSIONINFO.1 = 6 {
			if OSVERSIONINFO.2 = 0 {
				mes "\n[Windows Vista]"
			}
			if OSVERSIONINFO.2 = 1 {
				mes "\n[Windows 7]"
			}
		}
	}

↑TOP↑

Windows OSの言語の判別

 たとえば、プログラムを日本語Windows上で動かしたならば日本語で、日本語以外のWindowsならば英語で、というような海外の人にも利用してもらうプログラムをこしらえたい場合の言語判別サンプルです。言語やら通貨やら、国や地域ごとに異なる表記方法(ロケール情報)を取得するGetLocaleInfo関数GetUserDefaultLCID関数を利用します。

 GetLocaleInfo関数の場合に日本語環境だと「0411」という文字列が返ります。この文字列以外だったら英語表記、というような感じの処理にすればいいわけです。ちなみに、MSDNのページ(英語)の中ほどに言語IDの一覧が掲載されているので参照してください。

//	Windows OSの設定言語取得サンプル1 (by Kpan)

#include "kernel32.as"

	sdim lpLCData

;	$1=LOCALE_ILANGUAGE(言語ID)
	GetLocaleInfo $800, $1, varptr(lpLCData), 64
	mes "言語ID: "+lpLCData
//	Windows OSの設定言語取得サンプル2 (by Kpan)

#include "kernel32.as"

;	1041=日本語、1033=英語、の数値が返る
	GetUserDefaultLCID
	mes stat

↑TOP↑

壁紙の変更

 Windowsのディスクトップの背景(壁紙)を変更します。Win32 APIのSystemParametersInfo関数を呼ぶ方法もありますが、ここではCOMコンポーネント(アクティブディスクトップ)を利用した手法です。英語ですがMSDNページ

//	ActiveDesktopインターフェイスによる壁紙の変更 (By Kpan)

#define CLSID_ActiveDesktop "{75048700-EF1F-11D0-9888-006097DEACF9}"
#define IID_IActiveDesktop "{F490EB00-1240-11D1-9888-006097DEACF9}"

#usecom IActiveDesktop IID_IActiveDesktop CLSID_ActiveDesktop
#comfunc IActiveDesktop_ApplyChanges 3 int
#comfunc IActiveDesktop_SetWallpaper 5 wstr, int
#comfunc IActiveDesktop_SetWallpaperOptions 7 int, int

;	壁紙の表示位置
#enum WPSTYLE_CENTER = 0	// 中央に表示
#enum WPSTYLE_TILE		// 並べて表示
#enum WPSTYLE_STRETCH		// 拡大して表示

	onexit *exit

	newcom adesktop, CLSID_ActiveDesktop

	sdim filepath, 256
	input filepath, 400, 22

	objsize 20, 22
	pos 400, 0
	button "...", *setpath

	pos 200, 40
	objsize 80, 22
	button "適用", *setwallpaper

	stop

*setpath
	dialog "bmp;*.gif;*.jpg;*.png;*.htm;*.html", 16, "背景ファイル"
	if stat = 0 : stop
	filepath = refstr

	objprm 0, filepath
	stop

*setwallpaper
;	壁紙ファイルの指定 (第2パラにファイルパス、空文字だと壁紙「なし」)
	IActiveDesktop_SetWallpaper adesktop, filepath

;	WALLPAPEROPT構造体 (要素1に表示位置)
	WALLPAPEROPT = 8, WPSTYLE_TILE
;	壁紙オプションの指定
	IActiveDesktop_SetWallpaperOptions adesktop, varptr(WALLPAPEROPT)

;	変更の反映
	IActiveDesktop_ApplyChanges adesktop, 7

	mes "done."
	stop

*exit
	delcom adesktop

	end

↑TOP↑

バッテリー情報の取得

 GetSystemPowerStatus関数を利用して、PC(ノートPC)の電源まわりの情報を取得してみます。この関数で登場する SYSTEM_POWER_STATUS構造体は以下のような感じです。

メンバ 説明 変数要素
ACLineStatus AC電源の状態。次の値のうちの1つ。
 0=オフ (バッテリー駆動)
 1=オン
 255=不明
0 (4バイト)
BatteryFlag バッテリー残量の状態。次の値の組み合わせ。
 1=多い (66%以上)
 2=少ない (33%未満)
 0=中間 (65〜33%?)
 4=危険 (5%未満)、
 8=充電中
 128=バッテリー機能なし
 255=不明
BatteryLifePercent バッテリー残量(0〜100%)。255=不明。
Reserved1 未使用。常に0。
BatteryLifeTime バッテリー残り持続時間(秒)。-1=不明。 1 (4バイト)
BatteryFullLifeTime フル充電時のバッテリー持続時間(秒)。-1=不明。 2 (4バイト)
//	バッテリー情報取得サンプル (by Kpan)

#include "kernel32.as"

;	SYSTEM_POWER_STATUS構造体用の領域確保 (12バイト分)
	dim SYSTEM_POWER_STATUS, 3

	GetSystemPowerStatus varptr (SYSTEM_POWER_STATUS)

;	peek命令なりで、1バイト分取り出す
	mes "AC電源の状態: "+peek (SYSTEM_POWER_STATUS.0, 0)+"
	mes "バッテリー残量の状態: "+peek (SYSTEM_POWER_STATUS.0, 1)+""
	mes "バッテリー残量: "+peek (SYSTEM_POWER_STATUS.0, 2)+" %"

	mes "バッテリー残り持続時間: "+SYSTEM_POWER_STATUS.1+" 秒"
	mes "フル充電時のバッテリー持続時間: "+SYSTEM_POWER_STATUS.2+" 秒"

↑TOP↑

日付と時間の取得

 現在の年月日、時刻、曜日を一気に知る。HSPのgettime関数で普通に取得できるわけですが、最初にgettime関数で年を取得した時点と、最後にgettime命令でミリ秒を取得した時点では、ズレが一応あるわけです。もちろん日常生活では全く差しさわりのない差ですが。

//	ローカル日時の取得 (by Kpan)

#include "kernel32.as"

	dim SYSTEMTIME, 4

;	日本語版Windowsなら日本時間が返る
	GetLocalTime varptr(SYSTEMTIME)

	mes ""+wpeek(SYSTEMTIME, 0)+" 年"
	mes ""+wpeek(SYSTEMTIME, 2)+" 月"
	mes ""+wpeek(SYSTEMTIME, 4)+" [曜日]"
	mes ""+wpeek(SYSTEMTIME, 6)+" 日"
	mes ""+wpeek(SYSTEMTIME, 8)+" 時"
	mes ""+wpeek(SYSTEMTIME, 10)+" 分"
	mes ""+wpeek(SYSTEMTIME, 12)+" 秒"
	mes ""+wpeek(SYSTEMTIME, 14)+" ミリ秒"

↑TOP↑

パソコンの稼動時間の取得

 パソコンを起動してから経過した時間の取得です。Win32 APIのGetTickCount関数やtimeGetTime関数を利用します。この2つの関数は精度比較でよく話題になるものです。HSP3に付属する擬似3Dレンダリングモジュール「d3module」のd3timer関数はtimeGetTime関数を呼んでます。

 システム変数statにミリ秒単位で経過時間が返ります。制限として、49.7日を過ぎるとリセットされるので注意。

//	パソコンの稼動時間の取得1

#include "kernel32.as"

	GetTickCount
	mes ""+(stat / 86400000)+" 日"
	mes ""+(stat / 3600000 \ 24)+" 時間"
	mes ""+(stat / 60000 \ 60)+" 分"
	mes ""+(stat / 1000 \ 60)+" 秒"
	mes ""+(stat \ 1000)+" ミリ秒"
//	パソコンの稼動時間の取得2

#include "winmm.as"

	timeGetTime
	mes ""+(stat / 86400000)+" 日"
	mes ""+(stat / 3600000 \ 24)+" 時間"
	mes ""+(stat / 60000 \ 60)+" 分"
	mes ""+(stat / 1000 \ 60)+" 秒"
	mes ""+(stat \ 1000)+" ミリ秒"

↑TOP↑

実行ファイルの二重起動防止

 1つの実行ファイルを複数個起動できないよう、二重起動(2重起動、多重起動)の防止を行う単純なサンプルコードです。CreateMutex関数でミューテックスを生成し、エラーコードが「ERROR_ALREADY_EXISTS」ならば2つ目が起動してるので終了させます。(ちょくとさんのページを参照あれ)

//	実行ファイルの二重起動防止 (by Kpan)

#include "kernel32.as"

#define ERROR_ALREADY_EXISTS $B7

;	第3パラに適当なユニーク文字列を指定する
	CreateMutex 0, 0, "HSPTEST"

;	エラーコードを確認
	GetLastError
	if stat = ERROR_ALREADY_EXISTS {
		dialog "すでに起動しとるから閉じるよーん"
		end
	}

	mes "起動!"

↑TOP↑

タスクバーの位置とサイズ

 デフォルトでモニタ画面の真下に付いているタスクバー。タスクバー上での右クリックメニューで「タスクバーを固定する」を無効にしている場合、バーのドラッグで表示場所を上下左右に移動する、またバーの端のドラッグで高さや横幅を変更する、というのが可能です。そのバーの状態を拾ってみーる。

//	タスクバーの情報取得 (by Kpan)

#include "shell32.as"

#define ABM_GETSTATE 0x4
#define ABM_GETTASKBARPOS 0x5

;	APPBARDATA構造体
	dim APPBARDATA, 9

;	タスクバーの表示設定 (1=自動的に隠す、2=手前に表示、3=両方)
	SHAppBarMessage ABM_GETSTATE, varptr(APPBARDATA)
	mes "表示設定: "+stat

	SHAppBarMessage ABM_GETTASKBARPOS, varptr(APPBARDATA)

;	タスクバーの場所 (0=左、1=上、2=右、3=下)
	mes "場所: "+APPBARDATA.3

;	タスクバーの座標位置
;	(隠れていない状態の位置、隠れている状態は2px分見えている)
	mes "左上X: "+APPBARDATA.4
	mes "左上Y: "+APPBARDATA.5
	mes "右上X: "+APPBARDATA.6
	mes "右下Y: "+APPBARDATA.7

;	上下の場合
	if APPBARDATA.3 = 1 | APPBARDATA.3 = 3 {
		mes "高さ: "+(APPBARDATA.7 - APPBARDATA.5 - 2)+" px
	}

;	左右の場合
	if APPBARDATA.3 = 0 | APPBARDATA.3 = 2 {
		mes "横幅: "+(APPBARDATA.6 - APPBARDATA.4 - 2)+" px
	}

↑TOP↑

〜HSP3 あれこれ〜
ウィンドウ | オブジェクト | ファイル | フォルダ | キーボード | マウス | メニュー | システム | 文字列 | COM | その他

Copyright © 2005-2012 . All rights reserved.