杉山利幸の公開日誌 2020年4月分

2020年5月分

2020/04/25 Cmd MsgBox Ver. up to 2.02
2020/04/18 a! Menu Filer Ver. up to 3.01
2020/04/15 C++ に C# のreadonly が欲しい
2020/04/09 新型コロナウイルス(COVID-19)の抗体保有証明書
2020/04/04 a! Reg Analyzer Ver. up to 3.01
2020/04/01 ウインドウの作り方


2020/04/25 Cmd MsgBox Ver. up to 2.02

今日付けで Cmd MsgBox をバージョンアップしました。
バージョンアップ内容は以下の通りです。

Ver.2.02 2020/04/25

1番目の修正は、普段パソコンのボリュームを小さくして使っていて更に当ソフトを使う場合、
そのボリューム以上の大きさで再生することができませんでした。
Windows XP では、元のボリュームを修正して再生するという事ができていたのですが、
Windows Vista からはボリュームに対する考え方が全く変わったのでその方法がわかりませんでした。
今回その方法がわかったので修正しました。
それを詳しく知るためには「音声ミキサー」の開いて当ソフトを実行してみるとわかります。

2番目と3番目の修正は文字通りで、引数を順番通りに並べる形式の場合
追加を最後にしなければならず、順序がわかりにくくなってしまいます。
そこで思い切ってキーワード方式に変更し3番目の機能追加をすることにしました。
そのため過去からの互換がなくなりました。

4番目の修正はいつもの通りここにあります。
ここに詳しい解説があります。


2020/04/18 a! Menu Filer Ver. up to 3.01

今日付けで a! Menu Filer をバージョンアップしました。
バージョンアップ内容は以下の通りです。

Ver.3.01 2020/04/18

1番目と2番目の修正は、実は1つの修正で効果が2つ現れるというものです。

コンテキストメニューを表示させる機能は AMFTray.exe で実現しています。
AMFTray.exe は 32bit で作成していますが、
OSが x64 の場合、コンテキストメニューハンドラー(というのがあるのですが)が AMFList64.dll では全く効きません。
そこで AMFList32.dll もコンテキストメニューハンドラーとして登録することにしました。

登録の仕方で注意があります。
a! Reg Analyzer を使っているとわかるのですが、AMFList64.dll は 64bit ビューに、
AMFList32.dll は 32bit ビューに登録しなければいけません。

Vista x64 の場合はエクスプローラが 32bit と 64bit 2通りあるようです。
32bit のアプリケーションから起動すると、32bit のエクスプローラが起動し、
64bit のアプリケーションから起動すると、64bit のエクスプローラが起動します。
よってどちらのエクスプローラのコンテキストメニューにも「AMFファイル操作(F)」等を
表示させるようにしました。

3番目の修正は、「AMFファイル操作(F)」の実行も AMFTray.exe で実現しています。
c:\Windows\system32 へのアクセスは c:\Windows\sysnative を使うことにしました。

4番目、5番目の修正は、文字通りです。

6番目の修正はいつもの通りここにあります。
ここに詳しい解説があります。


2020/04/15 C++ に C# のreadonly が欲しい

ここでC++ の最新文法を勉強しました。

C# も勉強する機会があって、C# の方が後発の言語なのでよくできています。
その中でクラスに対してサブクラス化できないという C# sealed に対しては C++ final というのがあるのですが
メンバー変数でコンストラクタ、デストラクタ以外では変更できないという C# readonly にあたるものが C++ には見当たりません。

const というのがあるにはあるのですが、コンストラクターの初期化子で初期化しなければなりません。
式一つで書けるのものはいいですが、初期化子で書けないものも多くあります。

次回の C++ の仕様変更ではぜひ C# readonly にあたるものをサポートしてほしいと思います。


2020/04/09 新型コロナウイルス(COVID-19)の抗体保有証明書

新型コロナウイルス(COVID-19)対策の目的をおさらいしてみよう。

短期的

最終目的は医療崩壊を防ぐことなのだから、感染者数はあまり意味がないと思っている。
今病院のベッド(ホテルに隔離されている人も含む)を何床埋めているかが重要であって
マスコミも何人が退院したかを余り報じていない。
せめて都道府県別に発表してほしい。マスコミにも都道府県にもお願いしたい。

長期的な目的は、これだけ感染力が強いと「抗体を持っている人を増やす」しか人類には残された道はない。

抗体検査もそろそろできるようになるだろう。
充分抗体を持っている人は誰とでも濃厚接触が可能になる。
例えば一度症状が出て治った場合とか。

そのような人はどこからか抗体保有証明書を発行してもらいたいと思う。
どこかの国で発行しないかなあ。
そうすればその人に「STAY HOME」は必要ないので、
外で出歩くことが可能でおまわりさんに止められることもない。


2020/04/04 a! Reg Analyzer Ver. up to 3.01

今日付けで a! Reg Analyzer をバージョンアップしました。
バージョンアップ内容は以下の通りです。

Ver.3.01 2020/04/04

1番目と2番目の修正は、不具合修正で文字通りです。

3番目の修正は、レジストリーの中で「(既定)」は REG_SZ ばかりだと思っていましたが、
作者の環境で20,000程そうでない場合が見つかりました。
よってその編集機能を付けることにしました。
具体的には新しい値を作るときに、名前に空欄を指定すると「(既定)」を作成することになります。
レジストリーエディターにはその編集はできません。

4番目、6番目、8番目の修正は、機能向上で文字通りです。

5番目、7番目、9番目の修正は、仕様変更で文字通りです。

10番目の修正はいつもの通りここにあります。
ここに詳しい解説があります。

a! Reg Analyzer の補助説明も今まで
「詳細は後に」としていたところをちゃんと記述しました。


2020/04/01 ウインドウの作り方

ここ の中で「ウインドウの作り方」を解説すると言ったので解説します。

この辺りは人によってかなり流儀があると思いますが、1つのやり方として参考にしてください。

以下のソースを見てください。
#include <windows.h>
#include "DSample.h"
//---------------------------------------------------------------------------
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
//
//	hInstance
	CWinLib::hInstance = hInstance;//CWinLib の static の変数に入れておく
//
//	初期化
	OleInitialize(NULL);
	InitCommonControls();
//
	DSample sample(...);
	sample.Main();
//
//	後処理
	OleUninitialize();
	return 0;
}
//---------------------------------------------------------------------------

DSample.h
//---------------------------------------------------------------------------
#pragma once
//---------------------------------------------------------------------------
#include <windows.h>
...
//---------------------------------------------------------------------------
class DSample final : private CWinLib//CWinLib はウインドウ操作関連のライブラリ
{
public:
	DSample(...);
	void Main(void) const;
	COPYINHIBIT(DSample)
	NEWINHIBIT
private:
	static INT_PTR APIENTRY dlgSample(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
	static DSample* thisinst;
//
//	アイコン
	HICON hIcon;
	...
//
//	メッセージの処理
	LRESULT const OnInitDialog(HWND hDlg, WPARAM wParam, LPARAM lParam);
	...
	bool const Oncmdk(WORD wNotifyCode);
	LRESULT const OnDestroy(void) const;
};
//---------------------------------------------------------------------------

DSample.cpp
//---------------------------------------------------------------------------
#include "DSample.h"
#include "resource.h"
//---------------------------------------------------------------------------
DSample* DSample::thisinst = NULL;
//---------------------------------------------------------------------------
void DSample::DSample(...) : ...
{
	thisinst = this;//これが重要
	//ウインドウプロシジャーからはこれによりメンバー関数や変数にアクセス
//
//	その他変数の準備
	...
//
//	CreateWindow の場合はここで定義
//Handle = CreateWindow(...);//Handleは CWinLib の変数
//
//	CreateWindow(Ex)の場合は RegisterClass と共にここで定義
//
//	CreateWindow、CreateWindow(Ex)の場合はここで画面作り
}
//---------------------------------------------------------------------------
void DSample::Main(void) const
{
	DialogBox(CWinLib::hInstance, MAKEINTRESOURCE(IDD_SAMPLE), NULL, dlgSample);
	//CreateWindow(Ex), CreateDialog の時はメッセージループ
}
//---------------------------------------------------------------------------
INT_PTR APIENTRY DSample::dlgSample(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg)
	{
	case WM_INITDIALOG:
		return thisinst->OnInitDialog(hDlg, wParam, lParam);
		//thisinst によりメンバー関数の OnInitDialog にアクセス
	...
	case WM_COMMAND:
		{
		switch LOWORD(wParam)
		{
		...
		case IDC_CMDCANCEL:
			APICall(EndDialog(hDlg, false), "EndDialog");
			return 0;
		case IDC_CMDOK:
			if ( !thisinst->OnOk(HIWORD(wParam)) ) return 1;
			APICall(EndDialog(hDlg, true), "EndDialog");
			return 0;
		}
		return 1;
		}
	case WM_CLOSE:
		APICall(EndDialog(hDlg, false), "EndDialog");
		return 0;
	case WM_DESTROY:
		return thisinst->OnDestroy();
 	}
//
	return false;
}
//---------------------------------------------------------------------------
LRESULT const DSample::OnInitDialog(HWND hDlg, WPARAM wParam, LPARAM lParam)
{
//
//	ハンドルのセット
	Handle = hDlg;//ここは重要
	//Handleは CWinLib の変数で CWinLib の関数で使う
//
//	アイコンの設定
	hIcon = SetIcon(IDI_AMA);//SetIcon は CWinLib の関数のひとつ
//
//	画面作り
	...
//
	return true;
}
//---------------------------------------------------------------------------
bool const DSample::OncmdOk(WORD wNotifyCode) const
{
	if ( wNotifyCode != BN_CLICKED ) return false;
//
//	OKの処理
	...
//
	return true;
}
//---------------------------------------------------------------------------
LRESULT const DSample::OnDestroy(void) const
{
//
//	画面を作った後始末
	APICall(DestroyIcon(hIcon), "DestroyIcon");
	return 0;
}
//---------------------------------------------------------------------------

CWinLib はここに解説があります。

ウインドウプロシジャーをクラスの中の private かつ static な関数として定義して
thisinst という static な変数を設定することで、ウインドウプロシジャーからの
クラス関数・変数へのアクセスを可能にしています。

コメントを色々付けているのでそのまま読めば大丈夫でしょう。


2020年3月分

戻る