列挙体の値の列挙と、int->Enum 変換
前回、ちらっと汎用のFlags列挙体用プロパティエディタを作成中と発言しましたが、当然ながら汎用性を持たせる為、列挙体の型は動的に取得しなければなりませんし、最後エディタが設定した値も、動的に正しい型の列挙体にして返す必要があります。このあたり、どうやればうまくいくのか、ちょっと悩みましたので、備忘録として書き残しておきます。
日 | 月 | 火 | 水 | 木 | 金 | 土 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | |
7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 | 30 | 31 |
« 2010年11月 | トップページ | 2011年1月 »
前回、ちらっと汎用のFlags列挙体用プロパティエディタを作成中と発言しましたが、当然ながら汎用性を持たせる為、列挙体の型は動的に取得しなければなりませんし、最後エディタが設定した値も、動的に正しい型の列挙体にして返す必要があります。このあたり、どうやればうまくいくのか、ちょっと悩みましたので、備忘録として書き残しておきます。
Label の AutoSize プロパティを True にしておくと、基本的に Text 全てを表示できるサイズに自動的に調整されるので、用途によっては重宝するプロパティだといえます。今回は、これでちょっとはまってしまった話です。
以前の記事「独自のプロパティエディタ作成(ドロップダウン形式)」で使用したドロップダウン型のプロパティエディタを、Flags 列挙体に使用出来る汎用プロパティエディタに改造しようと思い、そこそこ動くレベルまでには作成できました。
そこで、OSの表示環境が変わっても正しく表示可能な様に、コントロールの表示サイズ調整の実装を行なう事にしました。一応 C#2003 にて作成しているので、C#2005 から追加された AutoScaleMode プロパティが使用出来ません。しかしメイン部分を CheckListBox に変更している上、この CheckListBox の表示サイズ調整は、別の理由により既に実装済みだったので、簡単だろうと思っていました。CheckListBox 以外には、「閉じる」の Label が1つあるだけですから、AutoSize プロパティを true にするだけだと...
以下の記事を改訂しました。
「Sandcastle を使用したドキュメント作成(2)」
MASHER さんの御指摘により、該当部分を修正しました。
「7-zip32.dllでサロゲートペア文字を使用した場合の動作結果」
新しいバージョンの7-zip32.dllが公開されました。新バージョンでの動作確認の結果、問題部分が解決されたのを確認しました。その事を記事冒頭部に追加しました。
以上
.NETで用意されているクラスを利用する事により、ハッシュ値の取得は簡単です。
例えばSHA-1なら、以下の記述で充分です。
/// <summary>
/// 指定ファイルのSHA1ハッシュ値を取得する。
/// </summary>
/// <param name="fileName">ハッシュ値を求めるファイルのパス</param>
/// <returns>SHA1ハッシュ値</returns>
public static byte[] SHA1(string file)
{
using (FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read))
{
SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();
sha1.ComputeHash(fs);
return sha1.Hash;
}
}
ただ、これだと計算途中に処理を中断出来ません。また、計算途中の進捗状況を表示したいといった場合とかでも、これでは対処出来ません。
こんなときは、TransformBlock / TransformFinalBlock を使用します。これを使用して記述すると、以下の様な記述となります。
/// <summary>
/// 指定ファイルのSHA1ハッシュ値を取得する。
/// </summary>
/// <param name="fileName">ハッシュ値を求めるファイルのパス</param>
/// <returns>SHA1ハッシュ値</returns>
public static byte[] SHA1(string file)
{
using (FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read))
{
SHA1Managed sha1 = new SHA1Managed();
byte[] buffer = new Byte[4096];
int len = fs.Read(buffer, 0, buffer.Length);
while (fs.Position < fs.Length)
{
sha1.TransformBlock(buffer, 0, len, buffer, 0);
len = fs.Read(buffer, 0, buffer.Length);
}
sha1.TransformFinalBlock(buffer, 0, len);
return sha1.Hash;
}
}
余談ですが、最初 TransformBlock の引数指定でなぜ outputBuffer, outputOffset の指定がいるのか理解に苦しみました。どうやら暗号化クラスで使用している ICryptoTransform インターフェイスを使いまわしているだけの様です。実際使用してみると、outputBuffer は使用してないらしく、MSDNのサンプルの様に inputBuffer と同じバイト配列を指定して問題ない様です(バイト配列は書き換えられない)。
サロゲートペアのテストしたついでに、Unicode固有文字が含まれるかのチェック方法について、考えてみました。私の知る限り、直接その文字列中にUnicode固有文字があるかをチェックする Win32API や .NET クラスの類はない筈です。
では、どうすればよいでしょう。
※この記事を書いて間もない12/19に、7-zip32.dll Version 9.20.00.02 が公開されました。バージョン履歴の項に、『Unicode モード時に2バイト文字が化ける問題を修正。』とあり、改めてこのバージョンによる検証を行なった結果、このバージョンではサロゲートペアの文字化け問題は解決していました。従って、以下の記事はあくまでも Version 4.65.00.01 を対象としたものであり、最新バージョンでは問題ない事を踏まえた上で読んで下さい。
C#で 7-zip32.dll を使用してみたので、ついでながら、サロゲートペアを使用したファイル名の場合の動作確認も行なってみたいと思います。
さて、前回保留していた書庫一覧の取得を行ないます。
7-zip32.dll は、本来 7z 形式の書庫を扱うアンマネージドDLLですが、Zip 書庫自体も扱える様になっています。最新の 4.65.00.01 では、AESによる暗号化をサポートした事や、Zip 書庫でも UTF-8 のファイル名をサポートした事で、Zip 書庫操作用の DLL としても見逃せないものになっています。
さて、この 7-zip32.dll ですが、いざ Unicode ファイルを扱おうとすると、UTF-8 の文字コードを要求するので、C#では通常の呼び出し方が出来ません。
そこで、どうやればいいのかが、今回の研究テーマです。
アイコンネタ第4弾目です。今回は、タイトルの通り、下図のアイコンの変更ダイアログを出してみます。そして最終的にはコンポーネント化してみる事にします。
怒涛のアイコンネタ、第3弾です。
今回は、指定されたファイルからアイコンを抽出して、それを ImageList に登録する汎用的な関数を公開します。
指定対象となるファイルは、アイコンリソースが含まれたファイル(実行ファイル/DLLファイル、アイコンライブラリファイル、アイコンファイル)です。