tomatomax.net

Every rule has its exception.

Archive for the .Net Category

treeViewコントロール

要素の追加方法。

TreeNode newNode;
treeView1.Nodes.Clear();
for(int i = 0; i < 3; i++)
{
newNode = new TreeNode(i.ToString() + "サーバ");
treeView1.Nodes.Add(newNode);
newNode = treeView1.SelectedNode;
for(int j = 0; j < 5; j++)
{
newNode = new TreeNode(j.ToString() + "村");
treeView1.Nodes[i].Nodes.Add(newNode);
}
}

CE.NETでのHTML表示

いろいろ調べてみたけれど、.NET Compact Framework用のブラウザコンポーネントはないのかな?eMbedded Visual C++ならあるみたいだけれど。

MicrosoftのPocketPCプログラミングガイドより

.NET Framework と .NET Compact Framework の相違点

.NET Framework の名前空間のうち、.NET Compact Framework ではサポートされない、または機能限定でサポートされるクラスがあります。

  • サポートされないクラス

Printing、ServiceProcess、Remoting、SessionState、HTML コントロールなど

さて、どうしたものか。

Rectangle

混乱しがちなのでメモ。

Delphi7以前

r := Rect(Left, Top, Right, Bottom);

Delphi8

r := Rectangle.Create(Left, Top, Width, Height);

Delphi8形式のほうが楽。

JoystickState.GetButtons()

以下はジョイスティックのボタン状態を得て、ボタンが押されていたらウィンドウを閉じる部分。

byte[] buttons = JS.GetButtons();
int cnt = 0;
foreach (byte b in buttons)
{
if (0 != (b & 0x80))
{
result = cnt;
this.DialogResult = DialogResult.OK;
this.Close();
}
cnt++;
}

Managedになってもやはり最上位ビットで判断するのか……。

キーコンフィグ

Serializeを使ってキー設定を保存してみようと画策。

http://hp.vector.co.jp/authors/VA013135/keyconfig.zip(ソース付)

どちらかというとDirectInput関連で手間取った。ジョイスティックは16本まで認識できるハズだけど、持ってないので2本までしか確認してない……m(_ _)m

Serialize

データ保存の方法としてSerializeが使えそうなのでテスト。

using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

// シリアライズするクラスによってシリアライズされるクラス
[Serializable]
internal class MyData
{
public int x, y;
// 引数ナシのコンストラクタを定義
public MyData()
{
x = 0;
y = 0;
}
// Deserialize時に使用するシグネチャコンストラクタを定義する
public MyData(SerializationInfo info, StreamingContext sc)
{
x = (int)info.GetValue("x", typeof(int));
y = (int)info.GetValue("y", typeof(int));
}
// Serialize時に使用するGetObjectDataの実装
public void GetObjectData(SerializationInfo info, StreamingContext sc)
{
info.AddValue("x", x);
info.AddValue("y", y);
}
}

// シリアライズするクラス
[Serializable]
internal class MyClass
{
public string Signature;
public uint Count;
public MyData Data;

// 引数ナシのコンストラクタを定義
public MyClass()
{
Signature = "SaRU";
Count = 0;
Data = new MyData();
}
// Deserialize時に使用するシグネチャコンストラクタを定義する
public MyClass(SerializationInfo info, StreamingContext sc)
{
Signature = (string)info.GetValue("Signature", typeof(string));
Count = (uint)info.GetValue("Count", typeof(uint));
Data = (MyData)info.GetValue("Data", typeof(MyData));
}

// Serialize時に使用するGetObjectDataの実装
public void GetObjectData(SerializationInfo info, StreamingContext sc)
{
info.AddValue("Signature", Signature);
info.AddValue("Count", Count);
info.AddValue("Data", Data);
}
}

class Class1
{
[STAThread]
static void Main(string[] args)
{
MyClass myclass = new MyClass();
myclass.Signature = "OSaRU";
myclass.Count = 24;
myclass.Data.x = 100;
myclass.Data.y = 200;

// シリアライズ
FileStream fs = new FileStream("test.dat", FileMode.Create);
BinaryFormatter bf = new BinaryFormatter();
try
{
bf.Serialize(fs, myclass);
}
catch (SerializationException e)
{
Console.WriteLine("Failed to serialize. Reason: " + e.Message);
throw;
}
finally
{
fs.Close();
}

// デシリアライズ
myclass = null;
fs = new FileStream("test.dat", FileMode.Open);
bf = new BinaryFormatter();

try
{
myclass = (MyClass)bf.Deserialize(fs);
}
catch (SerializationException e)
{
Console.WriteLine("Failed to deserialize. Reason: " + e.Message);
throw;
}
finally
{
fs.Close();
}

// 表示
Console.WriteLine("Signature:" + myclass.Signature.ToString());
Console.WriteLine("Count:" + myclass.Count.ToString());
Console.WriteLine("Data.x:" + myclass.Data.x.ToString());
Console.WriteLine("Data.y:" + myclass.Data.y.ToString());
Console.ReadLine();
}
}

結果

Signature:OSaRU

Count:24

Data.x:100

Data.y:200

iniファイルを利用しているような感覚。オブジェクトも格納できる(そのオブジェクトがSerializableになっている必要があるが)。

構造体と配列

構造体の中に配列を埋める方法がわからなかったのでメモ。

Unmanagedでは

struct box {
int a[10];
};

これをManagedで実現しようとしたとき。

[StructLayout(LayoutKind.Sequential)]
public struct box {
[MarshalAs(UnmanagedType.ByValArray, SizeConst=10)] public int[] a;
}

(;´∀`)……

さらに、使うときには配列のインスタンスを作成する必要があるようで。

はじめてのC#

というわけでHello, world!なんかを組んでみたり。

using System;

namespace Helloworld
{
/// <summary>
/// Class1 の概要の説明です。
/// </summary>
class Class1
{
/// <summary>
/// アプリケーションのメイン エントリ ポイントです。
/// </summary>
[STAThread]
static void Main(string[] args)
{
//
// TODO: アプリケーションを開始するコードをここに追加してください。
//
System.Console.WriteLine("Hello, world!");
}
}
}

実際に記述したのは一行だけですが。

構造体をファイルに書き込む

ファイルヘッダなどを構造体として作成し、そのままファイルに書き込むコードの移植を行っていたのだけれど。

f.write(header, 0, Sizeof(header));

上のようなコードに相当するものがワカラン……。一つ一つメンバを書き込んでいくしかないのか。

Int32

Sprite.Drawメソッドの引数は下のようになっている(C#)

public void Draw(

Texture srcTexture,

Rectangle srcRectangle,

Vector3 center,

Vector3 position,

int color

);

最後のcolorはint型で指定し、掛け合わせる色とα値を指定する。ARGB:8888であるので、そのまま表示したいときは0xFFFFFFFFを指定する、とヘルプにも書いてあるのだけれど。

Delphiの場合。

D3DSprite.Draw(SpriteTexture, FRect, Center, Pos, $FFFFFFFF);

と記述すると、

[警告]XXXX.pas(120): 定数式が範囲を超えました

と警告が出てくる。たかが警告と無視していたら

「プロジェクトXXXX.exeに処理されない例外クラス Borland.Delphi.System.ERangeErrorがあります。」

( ゜Д゜)ハァ?

対処法としてはColorをColor.Whiteとすればいいのだけれど、α値を適当にいじれないし。

とりあえずキャストしてみたら上手くいった。

D3DSprite.Draw(SpriteTexture, FRect, Center, Pos, Integer($FFFFFFFF));