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

2020年2月分

2020/01/29 Processx64 の追加仕様
2020/01/25 Post-Action Starter Ver. up to 2.02
2020/01/18 Screen Saver Stopper Ver. up to 2.03
2020/01/11 デストラクターの働く場所
2020/01/01 あけましておめでとうございます


2020/01/29 Processx64 の追加仕様

今日は Screen Saver Stopper に追加された Processx64.exe の仕様追加について述べておきます。

以前はここでしたが、 Screen Saver Stopper の追加機能のために
@BreakScreenSaver を追加して、現在は以下のようになりました。
引数動作
なし「直接起動してはいけません」というメッセージを出す。
:(半角のコロン)DOSコマンドDOSコマンドを起動し終了を待つ。
/(半角のスラッシュ)DOSコマンドDOSコマンドを起動し自らはすぐに終了する。
@GetOpenFileName64 bit 用ファイル選択コモンダイアログを表示、
データの受け渡しはファイルマッピング
@GetOpenDirName64 bit 用フォルダー選択コモンダイアログを表示、
データの受け渡しはファイルマッピング
@BreakScreenSaver64 bit 用のスクリーンセーバー解除
その他引数そのままのメッセージを出す。

「ファイルマッピング」については自分で調べてください。


2020/01/25 Post-Action Starter Ver. up to 2.02

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

Ver.2.02 2020/01/25

1番目の変更は、エラー 329番を調べてみると、ERROR_OPERATION_IN_PROGRESS ということで
スクリーンセーバーを再び生かそうとしたときに、例えばモニターが電源管理で抑止状態になっていた場合発生します。

このエラーが出た時どのように対処すればいいかを考えましたが、どうしてもうまく行かず、
結論としてこのエラーが出ることが無いように電源管理の設定を変えておくことにしました。

既に Screen Saver Stopper でそのノウハウは得ていて、
それ用のクラスを共通ライブラリー化してそれを使うことにしました。
またしても他のソフトのノウハウを流用することができました。

Before Power Off も同様の問題が発生する可能性がありますが、
パソコンがビジー状態が多いので電源管理が変更されなかったのかもしれません。
Before Power Off はそのうち直します。

以下(3番目と4番目の変更)のネットワークを使っている場合は、電源管理が変更されるのかもしれません。
以下(3番目と4番目の変更)のような使い方をしている時に気づきました。

2番目の変更は、文字通りです。

3番目と4番目の変更は、最近作者はOneDrive のバックアップが終わった後パソコンの電源オフをするために
このソフトを使い始めたのですが、タスクトレイのアイコンの変化をチェックする方法にしました。

ところがこの指定をすると領域が小さくて指定時も実行時も見にくかったので、この変更をしました。
指定時の変更が4番目で実行時の変更が3番目です。

5番目の変更はここにあります。
詳細はそのうち...


2020/01/18 Screen Saver Stopper Ver. up to 2.03

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

Ver.2.03 2020/01/18

1番目の変更は、スクリーンセーバーを解除する場合2010年頃までのソースは
マウスの動きをシミュレートして解除していたのですが、その方法が使えなくなっていたのに気づきました。

対策として、もうちょっと厳密にシミュレートして解除することに成功していたのですが、
更に悪いことに、Windows 8.1 以降ではその方法も使えなくなっていることがわかりました。

最後の手段として、スクリーンセーバーのプロセスを Cmd Process Terminator と同じ方法で終了させることにしました。

幅広い分野のソフトを公開していると、他のソフトのノウハウを横流し、もとい流用できるところは大変楽です。
今回は共通ライブラリー化をしていた所なので更に楽でした。

問題に気が付いたのは実は 2019/11/30 Multi Function Alarm Ver. up to 2.01 の頃
スクリーンセーバーの変更時や3Dテキストのメッセージの変更時は、スクリーンセーバーを解除していたのですが、
うまく行っていなかった事になかなか気づきませんでした。

何も報告が無かったという事は、Multi Function Alarm のスクリーンセーバー関連の機能は余り使われていないということのようですが、
この機能を使うときは、スクリーンセーバーの変更時 Screen Saver Stopper にスクリーンセーバーの解除を行うようにセットすればうまくいきます。
Multi Function Alarm はそのうち直します。

2番目の変更は、文字通りです。

3番目の変更はここにあります。
詳細はそのうち...


2020/01/11 デストラクターの働く場所

以下のソースでデストラクターはどこで働くでしょうか?
	class T1
	{
		T1(...);
		...
	}
	class T2
	{
		T2();
		...
		const T2& operator+(const T2& a);
	}
	main()
	{
		...
		for(...){
			T1* a = new T1(...);
			T2* b = new T2[...];
			...
			T2 c, d, e;
			T2 f = c + d + e;
			...
			if ( ... ) { delete a; delete[] b ; return;}
			...
			if ( ... ) { delete a; delete[] b ; break;}
			...
			if ( ... ) throw("例外を投げますよ");
			...
			delete a;
			delete[] b;}
		...
	}

答えは明示的になっている delete, delete[] の所ばかりではありません。

明示的になっていない所でデストラクターが働くのは以下の丸付き数字が書いてあるところです。
	class T1
	{
		T1(...);
		...
	}
	class T2
	{
		T2();
		...
		const T2& operator+(const T2& a);
	}
	main()
	{
		...
		for(...){
			T1* a = new T1(...);
			T2* b = new T2[...];
			...
			T2 c, d, e;
			T2 f = c + d + e@;
			...
			if ( ... ) { delete a; delete[] b ; Areturn;}
			...
			if ( ... ) { delete a; delete[] b ; Bbreak;}
			...
			if ( ... ) throw("例外を投げますよ");
			...
			delete a;
			delete[] b;C}
		...
	}

まず@は計算の途中結果である c + d 等が削除されます。;(セミコロン)でデストラクターが働きます。
Aは new でなく宣言された変数 c, d, e, f が削除されます。Bでも同様です。
return や break 等のループを抜ける所でデストラクターが働きます。
Cではどうでしょうか?実は例外が起きようと起きまいと変数 c, d, e, f が削除されます。
}(波括弧閉じ)でデストラクターが働きます。

以上みてきたようにデストラクターというのは活躍範囲がすごく広いです。

それがわかっていないと C++ のデバッグはできません。

所で例外が起きた場合、変数 a と b はどうなるのでしょか?
a と b は削除されません。永遠に。メモリーリークの発生です。

メモリーリークは以下の簡単なソースで発生させられます。
	{
		T2* b = new T2[...];
	}
	D

変数 b はDのところに来ると削除もできません。変数 b は既に死んでいるからです。
Dの前の}(波括弧閉じ)で b のポインターとしての領域は削除されますが、b の中身までは削除されません。

よって new はなるべく使わない方がいいです。
2010年頃までのソースはかなり new を使っていましたが、なるべく減らしました。

かといって new を全く使わないことができるかというとそうでもなくて、
サイズが実行時にしかわからない配列を定義するときとか、
メンバー変数に引数が必要で引数の計算が初期化子では指定できない複雑な式になる場合は、 メンバー変数をポインターとして new を使わざるを得ません。

これを解決するにはスマートポインターを使うとよいのですが、その話は後々...

なお前回のネタ本に以下を追加しました。

More Effective C++、Scott Mayers 著、丸善出版株式会社


2020/01/01 あけましておめでとうございます

あけましておめでとうございます。今年もよろしくお願いします。

去年は、コンパイラーを Visual Studio 2017 に変えるとか、ソースを全面見直しするとか、Windows 10 ばかりではなく 64bitOS対応をするとか大変更をしましたが、
今年はそこまでの大変更はしません。しかしネズミ年なので中(チュー)変更位はしたいと思います。それは、

・C++最新文法で有用な記述へ変更(内部処理)

です。

2010年頃までのソースは、作者の無知もあったのですが、テンプレートすら使っていませんでした。
そのため、ポインターの配列を int の配列にしてキャストで相互の変換をしているとか、変なことをやっていました。

今のソースはコンテナをテンプレートにするとか、文字列処理も専用のクラスを作っているとか、かなりの改善が実現しています。
例えば、キャストもほとんどしなくなりました。

今回の変更のネタ本は以下です。

Effective C++、Scott Mayers 著、丸善出版株式会社

Effective modern C++、Scott Mayers 著、株式会社オライリージャパン

この変更によって、メモリーリークが少なくなるとか、バグが取りやすくなるとかになると思います。

今回の変更はそれほどかからないでしょう。形式的な変更で間違った場合コンパイルエラーが出てくれる性質のものです。

まだソフトに細かい不具合もありますが、それも含めて変更していきたいと思います。

本を読み切るまで暫く時間を下さい。


2019年12月分

戻る