イネマルのプログラミング備忘録

趣味プログラマーのメモ。ニッチなネタから暗黙知まで無保証で公開。

DXライブラリ向け 簡易キー入力クラス

はじめに

DXライブラリで、キー入力の開始や終了を取る際、自前で機能を用意する必要があります。
必要になるたびに作るのが面倒そうなので、キー入力クラステンプレート的なものを置いときます。
対象は、キーボードとマウスです。

昔、DxLibをラップした自作ライブラリで学習がてら作ったものから、
切り出しだけなので、気になる部分があれば、適当に調整してください。

実装

ビルド環境:Microsoft Visual C++ 2015

あとがき

たまたま、DXライブラリ製の小物プログラムを改修する機会がありました。
入力周りの制御をネットで調べると意外と簡易的なものが見つからなかったので、昔のコードを掘り返し備忘録行き。

DXライブラリは、よく使いそうな便利関数も自分で用意しないといけない部分が多い印象です。
この点において、イマドキだとUnityだったり、C++ならSiv3D(OpenSiv3D)が便利関数豊富で初心者が取っつきやすい環境かなと感じています。

WSH WSF を バッチに埋め込む方法 ( 現在時刻を読み上げるバッチファイル )

ちょっとしたメモ

タイトルの通り、wsf 形式のWSHスクリプトをバッチファイルに埋め込む方法です。
wsfを使えば、VBScriptJScript を混在させたり、
HTML の scriptタグ と同じように記述できるのでGoogle APIsから jQuery 使うようにしたりできます。
バッチに埋め込むメリットは、用途次第ということで省略。

コマンド

おまじない部分は、下記の通り。

<!-- :
@echo off
%windir%\System32\cscript.exe //nologo "%~f0?.wsf" %*
%ComSpec% /c exit %errorlevel%&goto:EOF
--->

これを駆使して、現在時刻を読み上げる機能を作ると下記のようになります。

参照

埋め込む方法は、下記から。 stackoverflow.com

VSCode Windows版 コマンドライン引数を使用する際の注意

ちょっとしたメモ

Windows版 の、VSCodeコマンドライン から使用する場合、
使用する実行ファイルは、「Code.exe」でないので、注意が必要。

コマンドラインから使用する際は、Code.exe と同じディレクトリ以下の、
「bin\code.cmd」を使用する必要があります。

コマンド

ヘルプを表示するコマンドは、下記の通り。

"%ProgramFiles%\Microsoft VS Code\bin\code.cmd" -h

もしくは、環境パスから

code -h

参照

コマンドライン引数の詳細は、下記を参照。

WSH JScript Chakra を使用した ES2015(ES6) 対応 ( スクリプトエンジン まとめ )

はじめに

WSH JScript (wscript cscript) で使用できる スクリプトエンジン まとめです。

サードパーティー製は含みません。
JavaScript限定、初期状態で使用可能な物だけなので注意。

JavaScript エンジン について

JScript (JavaScript) だけでも、4種類ほどスクリプトエンジンがあるようです。
以下、それぞれの cscript.exe で使用する際のサンプルコマンドです。

JScript

JScript を使用する際、一般的に指定されるスクリプトエンジンです。
バージョンは、環境によって異なりますが、
現時点のOSサポートを考慮すれば、5.7 か 5.8 でしょう。

rem jscript.dll
%windir%\System32\cscript.exe //nologo //E:JScript "%~f0" %*

JScript.Compact

JScript Compact Profile (ECMA 327) で実行する、スクリプトエンジンです。
MSの情報が少ないので、詳細は未確認ですが
簡単に説明すれば、「いくつかの機能を制限して、パフォーマンス向上を図る設定を使用する」と言った感じでしょうか。
機能の制限については、with ステートは、サポートされていないようです。

rem JScript Compact Profile (ECMA 327)
%windir%\System32\cscript.exe //nologo //E:JScript.Compact "%~f0" %*

JScript9

IE9 から使用されている、JScript9.dll をスクリプトエンジンとして指定できます。
ProgID が公開されていないので、CLSID を指定する必要があります。

ちなみに、JScript9 の 9 は、エンジンバージョンと言うわけでは無い様で、
Windows10 では、バージョン 11.0 として扱われていました。(中身は、Chakra っぽい?)

ES2015(ES6) ベースで書けるかと思いきや、
JScript 5.7 互換モードで動作しているらしく クラスとか便利機能は使えません。
それどころか、互換も完全ではなく WScript.Quit が使用できません。

rem jscript9.dll
%windir%\System32\cscript.exe //nologo //E:{16d51579-a30b-4c8b-a276-0ff4dc41e755} "%~f0" %*

Chakra

Microsoft EdgeJavaScriptエンジン です。
こちらも、ProgID が公開されていないので、CLSID を指定する必要があります。

Chakra を使用する場合は、ES2015(ES6) に対応している為、クラスなどが使用できます。
ただし、JScript9 と同様に、WScript.Quit は、使用できません。

rem chakra.dll
%windir%\System32\cscript.exe //nologo //E:{1B7CD997-E5FF-4932-A7A6-2A9E636DA385} "%~f0" %*

Chakraを使用したスクリプト を バッチに埋め込む場合

@if 等を使用して、バッチファイルにJScriptを埋め込むこと(shebangモドキ)がありますが、
Chakra を使用する場合は、構文エラーとなってしまうため、少し工夫が必要です。

自分の場合は、以下の様にしています。

rem=0;/*
echo off&cls&title %~n0
%windir%\System32\cscript.exe //nologo //E:{1B7CD997-E5FF-4932-A7A6-2A9E636DA385} "%~f0" %*
pause rem コンソールが、閉じないように止める
exit %errorlevel% */

JScript9 や Chakra で、戻り値を返したい場合

WScript.Quit が使えないのは、少々痛手なので、代替案です。
スクリプトをバッチに埋め込んで、戻り値をテキストでやり取りする方法が楽だと考えました。
スクリプト側で、exitcode.txt を出力し、バッチ側でexitcode.txtを読んで終了 といった流れです。

rem=0;/*
echo off&cls&title %~n0
%windir%\System32\cscript.exe //nologo //E:{1B7CD997-E5FF-4932-A7A6-2A9E636DA385} "%~f0" %*
rem テキストの値を戻り値にしてしまう。
set /p code=<exitcode.txt
exit %code% */

おわりに

WSH ってだけで、今更感満載のレガシーなのですが、
初期状態のWindowsで使用できる手軽さで、根強く?使われている様子。

今回のまとめは、WSH JScript で、クライアントの環境に依存せずに
ES2015 ベースのコードを使えないか調査したときの副産物です。

結果的に、ES2015 対応は行っていませんが、
TypeScript 経由で、対応できそうかなと言ったところでオチ。

参考リンク

WSH JScript JSONファイルを使用する

はじめに

WSH JScript で、設定ファイルに対応する際に使用した方法です。
WSH(VBScript, JScript) から設定ファイルを扱う場合、JSON を使用すると楽できます。

その他のフォーマットであれば、XMLMSXML を使用して対応できますが、JSON の方がコードが直感的になります。

注意

文字コードは、SJIS を使用しています。
それ以外の文字コードでは、動作検証していません。

実装

{
  "Date": {
    "Year": 2018,
    "Date": "03/21",
    "Time": "12:34"
  },
  "Users": [
    {
      "Country": "Austria",
      "Name": "Hans Meier",
      "Age": 18
    },
    {
      "Country": "Canada",
      "Name": "Joe Blow",
      "Age": 19
    },
    {
      "Country": "Japan",
      "Name": "山田 太郎",
      "Age": 20
    }
  ]
}

あとがき

ちなみに、保存機能を考慮しなければ、テキストを直接 eval に流すだけでも対応できます。

JScript で、JSON オブジェクトを取得する方法は、下記から。 stackoverflow.com

C++ Windowsで ini ファイルを読み込む

はじめに

Windows で、ini ファイルの読み込みと言えば、GetPrivateProfileStringです。
時間をかけずに、手っ取り早く設定ファイル対応を行うときに使えるかもしれない方法です。

注意

GetPrivateProfileString は、下記の表記の通り 16ビット互換 のために残されているAPIなので、非推奨と考えた方がよさそうです。

MSDN より引用
注意 この関数は、16 ビット Windows ベースのアプリケーションとの互換性を保つ目的でのみ提供されています。Win32 ベースのアプリケーションでは、初期化情報をレジストリに格納してください。

実装

  • config.ini
; 設定ファイル
[System]
WindowText = ウィンドウタイトル
WindowWidth = 1280
WindowHeight = 720
  • main.cpp

あとがき

APIの引数的に、情報取得毎にファイルを読み込みに行く疑惑があるので、
もしかすると、ファイルサイズの影響を受けて、遅くなるかもしれません。
そもそも、互換目的で残されているだけっぽいので、代替機能を用意するなり、適宜対応した方が良さそう。

C++ ビルド時の西暦を表示

ちょっとしたメモ

定義済みマクロ の、__DATE__ は文字列として扱えるので、
西暦部分の先頭アドレスがあれば事足りる。

実装

あとがき

西暦のみの定義済みマクロが無いのか調べた結果、無さそうという結論。
よく考えたら、__DATE__から取り出せるよねと言う話。