「C#」カテゴリーアーカイブ

C#で16進数文字列をバイト配列に変換する方法

16進数文字列をバイト配列に変換したい。

「010203」とか「01 02 03」とか16進数の文字列をバイト配列に変換する必要があったのでその方法を調べてみた。

その方法は2種類あったが、次に使おうと思ったときに忘れていそうなので備忘録もかねて記録しておく。

Int32を使用する方法

[csharp]
// 16進数文字列
String[] hexStrings = new String[] { "01", "02", "03", "04" };

// バイト配列
byte[] bytes = new byte[hexStrings.Length];

// 16進数文字列をバイト配列へ変換
for (int i = 0; i < hexStrings.Length; i++ )
{
bytes[i] = (byte)Convert.ToInt32(hexStrings[i], 16);
}
[/csharp]

Convertを使用する方法

[csharp]
// 16進数文字列
String[] hexStrings = new String[] { "01", "02", "03", "04" };

// バイト配列
byte[] bytes = new byte[hexStrings.Length];

// 16進数文字列をバイト配列へ変換
for (int i = 0; i < hexStrings.Length; i++ )
{
bytes[i] = (byte)Convert.ToInt32(hexStrings[i], 16);
}
[/csharp]

hexStringsは「010203」だったらsubstringとか「01 02 03」だったら半角スペースでsplitとかで作ることを想定しています。

どちらも1度intに変換してからbyteにキャストするという点では一緒だ。

C#でフォームにPDFを表示させる方法

VisualStudioを使用したWindowsアプリ開発でフォームにPDFを表示させなければならない状況となり、調査しましたが、あまりわかりやすく説明されたページが存在しないので今回その方法を整理します。

ツールボックスにアイテムを追加

ツールボックスに追加する前提としてはAdobe Readerがインストールされている必要があると思います。

ツールボックスのすべてのWindowsフォームを右クリックして「アイテムの選択」をクリック

アイテムの追加

表示された画面で「COMコンポーネント」タブを選択し、「Adobe PDF Reader」にチェックしてOKボタンを押下

アイテムの選択

フォームに配置

ツールボックスから前の手順により追加された「Adobe PDF Reader」を選択し、フォームを配置。

フォームに配置

読み込むPDFを指定するコードを記述

フォームのLoadイベントで以下のコードを記述
※フォームに配置された「Adobe PDF Reader」コントロールのNameがaxAcroPDF1の場合の例です。
[csharp]
axAcroPDF1.LoadFile(@"C:\pdf_open_parameters.pdf");
[/csharp]

実行

PDFフォーム実行

上記の手順でPDFが表示されました。
たとえばHelp画面やマニュアル表示に役立ちそうですね。

C#やVB.NETでタイトルバーを消す方法

beforeForm

MDIアプリケーションの子フォームを作成する場合に上記の赤枠部分のタイトルバー(正式名称はなんだろう)を消したくなるケースがありますが、その方法は以下となります。

ControlBoxプロパティを変更

まずフォームのControlBoxプロパティをデフォルトのtrueからfalseに変更します。

変更した結果は以下となります。

after1Form

最大化、最小化、×ボタンは消えましたが、この状態だとまだタイトルバーが残ってしまいます。

Textプロパティを削除

Textプロパティに文字列が設定されている(今回の例の場合はForm1が設定されている)ので削除してください。

すると

after2Form

タイトルバーが消えましたね。
Textを消すことによってタイトルバーが消えるのは何か違和感があって、いつも忘れてしまうんですよね。

JavaとC#のListアクセス時の動作の違い

C#でListの要素を削除するコードを書いて実行したところInvalidOperationExceptionが発生した。
最初は原因がわからなかったが、foreachの途中でListの要素を削除したことによってループを継続することができなくなったようだ。

C#

[csharp]
try
{
List<String> list = new List<string>();
list.Add("OK");
list.Add("OK");
list.Add("NG");
list.Add("OK");

foreach (String str in list) {
if (str == "NG") {
list.Remove(str);
}
}
}
catch (Exception e)
{
Console.WriteLine(e.StackTrace);
Console.ReadLine();
}
[/csharp]

出力結果

場所 System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
場所 System.Collections.Generic.List`1.Enumerator.MoveNextRare()
場所 System.Collections.Generic.List`1.Enumerator.MoveNext()
場所 TestCSharp.Program.Main(String[] args)

IEnumeratorインターフェースのmoveNextを利用してループしても同様の結果となった。
ループの途中でListの要素を削除するには以下のようにindex指定でアクセスする必要がある。

[csharp]
List<String> list = new List<string>();
list.Add("OK");
list.Add("OK");
list.Add("NG");
list.Add("OK");

for (int i = 0; i < list.Count; i++ )
{
if (list[i] == "NG") {
list.RemoveAt(i);
}
}

foreach (String str in list) {
Console.WriteLine(str);

}
[/csharp]

OK
OK
OK

ちなみにJavaならIteratorでも問題なく削除できる。
[java]
List<String> list = new ArrayList<String>();
list.add("OK");
list.add("OK");
list.add("NG");
list.add("OK");

Iterator<String> itr = list.iterator();
while (itr.hasNext()) {
if (itr.next().equals("NG")) {
itr.remove();
}
}

System.out.println(list.toString());
[/java]

出力結果

[OK, OK, OK]

言語が変わると思わぬ動作の違いに驚いたりしますね。