杉山利幸の公開日誌 2018年12月分

2019年1月分

2018/12/29 Post-Action Starter Ver. up to 2.00
2018/12/22 独自のライブラリについて
2018/12/15 C++ Builder VCL の代わりに独自のライブラリ化をしています
2018/12/08 何故 Virus Mail Killer を C++ Builder から Visual C++ に変更したか
2018/12/01 Virus Mail Killer Ver. up to 1.99


2018/12/29 Post-Action Starter Ver. up to 2.00

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

Ver.2.00 2018/12/29

1番目から3番目までの修正は、いつもの通りです。

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

5番目の修正は、Ver.1.18 の Readme.txt に以下のようなことが書いてありました。
・待ち状態:そのプロセスの処理が終了し、他のプロセスに制御を渡せる状態に
 なったことを意味します。CPUリソースを他のプロセスに開放しない行儀が
 悪いプロセスしか意味がありません
 (プログラマ向けコメント:WaitForInputIdle API を使っています)

この行儀悪いプロセスを作ってみましたが、うまくいきませんでした。これを何故入れたのか記憶がありませんが、9x系で有効だったのかもしれません。特に検証の必要性も感じないのでこのまま機能を削除することにしました。


2018/12/22 独自のライブラリについて

今回は独自のライブラリを少し紹介します。

文字列処理関連(AnsiStringの代わり)
以下で名前の「CString」は MFC のクラスと名前がかぶっていますが、MFC は使わないということで
class CString
{
#define ALLOC_CHAR_COUNT 30
//
//	コンストラクタ、デストラクタ
public:
	CString(LPCTSTR str);
	CString(LPCWSTR wstr);
	CString();//デフォールトコンストラクタ
private:
	explicit CString(int size);
public:
	CString(const CString& cstr);//コピーコンストラクタ
	virtual ~CString();
//
//	変数
private:
//public://一時的
	int	size;//アロケートサイズ
	LPTSTR string;//文字列
	int len;//文字列の長さ、クラスの中で管理する
//
//	関数
public:
//
//	オブジェクト内の値を返す
	LPTSTR str(bool newflg = false) const;
	inline int Length() const { return len; };
//
//	operator[]等
	inline const char& operator[](int nIndex) const {return string[nIndex];};
	//添字チェックなし cstr[3] = ... のような使い方はできないので別途 SetAt を用意
	bool SetAt(int nIndex, char ch);
//
//	代入演算子
	CString& operator=(LPCTSTR str);//ないと浅いコピーになってしまう。
	inline CString& operator=(const CString& cstr) {return (*this = cstr.string);};
	//friend void operator=(LPCTSTR str, const CString& cstr);//コンパイルエラー
	CString& operator|=(LPCTSTR str);//ないと浅いコピーになってしまう。
	inline CString& operator|=(const CString& cstr) {return (*this |= cstr.string);};
//
//	連結演算子
	CString operator|(LPCTSTR str) const;
	inline CString operator|(const CString& cstr) const {return (*this | cstr.string);};
	friend CString operator|(LPCTSTR str, const CString& cstr);//external functions
	...(以下略)

連結演算子が特徴的で縦棒「|」を使っています。

次は TStringList の代わりについて
template <class Obj = LPVOID>
class CStrList
{
//
//	コンストラクタ、デストラクタ
public:
	CStrList(bool Sorted = false);
	virtual ~CStrList();
//
//	変数
public:
	int	Count;
	CString* Strings;
	Obj* Objs;
	bool Sorted;
private:
	int	AllocCount;
//
//	関数
public:
	void Clear(void);
	int  Add(CString cstr);
	int  AddWithObj(const CString cstr, Obj ob);
	int  IndexOf(const CString cstr) const;
	int  IndexOfi(const CString cstr) const;
	bool Insert(int ind, CString cstr);
	bool Delete(int ind);
	bool ModString(int ind, const CString cstr);
	void Sort(void);
	void LoadFromFile(CFile fn);
	void LoadFromText(const CString text);
	bool SaveToFile(const CFile fn) const;
	char* ToMultiString(int* Length);//戻り値は delete[] 要
};

テンプレートになっています。

次はウインドウのコントロール(部品)関連
class CWinLib
{
public:
	HWND Handle;
protected:
	CString GetText(int id);
	inline int GetTextCount(int id)
		{ return GetWindowTextLength(GetDlgItem(Handle, id));};
	inline void SetText(const CString str)
		{ SetWindowText(Handle, str.str());};
	inline void SetText(int id, const CString str)
		{ SetWindowText(GetDlgItem(Handle, id), str.str());};
	...(途中略)
	inline void Enable(bool b)
		{ EnableWindow(Handle, b);};
	inline void Enable(int id, bool b)
		{ EnableWindow(GetDlgItem(Handle, id), b);};
	void Enable(int id, int no, bool b);
	inline bool Enabled(void)
		{ return (IsWindowEnabled(Handle) == TRUE);};
	inline bool Enabled(int id)
		{ return (IsWindowEnabled(GetDlgItem(Handle, id)) == TRUE);};
	...(途中略)
	inline void Visible(bool b)
		{ ShowWindow(Handle, b ? SW_SHOW : SW_HIDE);};
	inline void Visible(int id, bool b)
		{ ShowWindow(GetDlgItem(Handle, id), b ? SW_SHOW : SW_HIDE);};
	...(途中略)
//
	inline void chkSetCheck(int id, bool b)
		{ SendDlgItemMessage(Handle, id, BM_SETCHECK, b ? BST_CHECKED : BST_UNCHECKED, 0);};
	inline bool chkGetCheck(int id)
		{ return (SendDlgItemMessage(Handle, id, BM_GETCHECK, 0, 0) == BST_CHECKED);};
//
	void rdgSetValue(int id, int no, int value);
	int  rdgGetValue(int id, int no);
	...(以下略)

これを親クラスにして Handle に親ウインドウのハンドルを入れて使います。


2018/12/15 C++ Builder VCL の代わりに独自のライブラリ化をしています

C++ Builder の VCL が優秀であることはここで述べています。AnsiString とTStringList には大変お世話になっていました。それ以外にも VCL のコントロールのクラスは大変優秀でした。MSC のクラスよりはるかに優秀です。従って、MSC は使いたくはないです。VCL の使用をあきらめるにあたり、それの代わりになるものを作る必要があります。もちろん、VCL にかなうものは作れませんが...。

特に AnsiString の代わりになるものを独自に改良を加えて作りました。これは文字列を表す char* の代わりになるものですが、文字列処理はプログラムの7割以上を占めています。これへの変更は結局プログラムのほとんどを見直さざるを得ないということになります。

ソフトの更新で「ソースの全面見直しによる細かなバグ取りと改良(内容は細かすぎて忘れた)」というのが必ず入っているのは、こういう理由です。見直すうちに、「これはバグっていたのではないかな?」とか「これでよく動いていたな!」とかいうのがかなりありました。検証も記録もめんどくさいので、更新理由をさっきのようにまとめて書いています。

独自に作ったライブラリがプログラムにどこまで貢献しているかは、ステップ数に現れるのでそれを書いておきます。
内容ステップ数説明
Virus Mail Killer Ver.1.864705 行Aとする
Virus Mail Killer Ver.1.996887 行Bとする
独自ライブラリ1653 行Cとする
MD5関係でもらってきたソース321 行Dとする
A−D4384 行Ver.1.86 での実質のステップ数、Eとする
B−D−C4913 行Ver.1.99 での実質のステップ数、Fとする

E(4384行)とF(4913行)を比べると、VCL には当然かないませんが独自ライブラリもそんなに悪くないと思われます。

独自ライブラリは今でも進化中です。

今日はこの辺で。


2018/12/08 何故 Virus Mail Killer を C++ Builder から Visual C++ に変更したか

何故 Virus Mail Killer を C++ Builder から Visual C++ に変更したかは主に以下の2つの理由です。

・PCには1つのコンパイラーだけを置き、環境の混在はしたくない。ノウハウの統一化のためにもコンパイラーは複数に手を出ださずに統一しておきたい。

・C++ Builder は将来性が不安

C++ Builder は今日まで開発会社が、Borland(Inprise)⇒CodeGear⇒Embarcadero と目まぐるしく変わりました。開発ツール部門で、色々と Microsoft とのシャア争いとかがあったようです。以下が参考になります。

BORLAND

Embarcadero Technologies, Inc.

実は作者は C++ Builder は 3 までしか持っていない(相当古い!)ので、このような混乱には巻きこまれなかったのですが...。
C++ Builder

シェアが取れなかった場合、どんなにいい製品を出しても行く末が案じられてしまいます。

最新の価格を見ると(ここ)とても個人が買えるような価格ではありません。無料版というのもあり最近64bitの開発もできるようになったようですが、いつ切られるかわからないことがここの一番下に書いてあります。

ただ、C++ Builder には非常に優秀な VCL(Visual Component Library) というのがついていて、Microsoft の Visual C++ よりも開発しやすかったです(詳細はここ)。この辺をどうしたかは次回あたりに。


2018/12/01 Virus Mail Killer Ver. up to 1.99

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

Ver.1.99 2018/12/01

1番目の修正は、作者の環境にはすでにモデムはありません。
昔はありましたが...。機能をそのままにしておいても何かあったときにデバッグできません。常時接続が当たり前になった今は削除することにしました。

2番目の修正は、作者がソフトの修正を停止した8年程前から増えてきたメールで、対応しないわけにもいかなくなってしまったので対応することにしました。

3番目の修正は、最近ではスパムメールが生意気にも https を使うようになったのでその対応です。

4番目の修正は、HTML メールは嫌いだったのですが、増えてきて誤判定をするのも嫌なので対応しました。

5番目と6番目の修正はいつもの通りなのですが、今回は事情が異なります。前バージョン Ver.1.86 は「Visual Studio 6.0(MFC なし)」ではなく「C++Builder3」で作っていました。そのためほとんど作り直しになりました。この辺の苦労話は後に。このおかげで今使っているPCにC++Builderを入れる必要がなくなったのは大きいです。

Ver.1.99 という中途半端なバージョン番号を付けたのは、このソフトも時代遅れなところも出てきたので、次回のバージョンアップで大幅変更をしようかと考えています。ただ他のソフトの Visual Studio 2017 対応が終わってからになるでしょう。

ところが一つ気が付いてしまったことがあります。大きく時代遅れになっている項目がありました。まだ調査段階です。その対応に対してはお金がかかるのかもしれません。その場合ソフトの公開を止めてしまうかもしれません。いずれにしてもその対応は Ver.2.00 には間に合わないと思っています。


2018年11月分

戻る