ラベル C# の投稿を表示しています。 すべての投稿を表示
ラベル C# の投稿を表示しています。 すべての投稿を表示

2013年2月8日金曜日

LTSVが流行っているみたいなのでパーサーを書いてみた。

C# で動くLTSVパーサーです。


https://github.com/mezashi184/LTSV



using

using LTSV

parse line

Record record = Parser.Line("host:127.0.0.1\tident:-\tuser:frank");
Console.WriteLine(record["host"]); // "127.0.0.1"
Console.WriteLine(record["ident"]); // "-"
Console.WriteLine(record["user"]); // "frank"

parse file

IEnumerable records = Parser.Line("host:127.0.0.1\tident:-\tuser:frank");

foreach (Record record in records)
{
    Console.WriteLine(record); // "host:127.0.0.1\tident:-\tuser:frank"
}

create line

Record record = new Record();
record["test"] = "sample";
record["foo"] = "bar";
Console.WriteLine(record.ToString()); // "test:sample\tfoo:bar"


2012年11月14日水曜日

C# .NET2.0で使えるParserクラスを作ってみた。

HaskellのParsecに触発されて、
C# .NET2.0で使えるParserクラスを作ってみた。


https://github.com/mezashi184/Parq


サンプル
----

   Parser parser = CharParser.Range('0', '9');
   using (StringSource source = new StringSource("012"))
   {
      Assert.That(parser.Run(source), Is.EqualTo('0'));
   }
----



2012年6月29日金曜日

ファイルの排他制御のサンプル

C#でファイルの排他制御の動作確認用プログラム。 FileShareの使い方のサンプルです。

using System;
using System.IO;

namespace sample
{
    class Program
    {
        static void Main(string[] args)
        {


            File.WriteAllText("aaa.txt", "sample");

            // 読み込み中に書き込み可能
            Console.WriteLine("------------------");
            Console.WriteLine("FileShare.ReadWrite");
            using (FileStream stream = new FileStream("aaa.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                using (new StreamWriter("aaa.txt", true))
                {
                    Console.WriteLine("OK write");
                }
                using (new StreamReader("aaa.txt"))
                {
                    Console.WriteLine("OK read");
                }
            }

            // 読み込み中に読み込み可能
            Console.WriteLine("------------------");
            Console.WriteLine("FileShare.Read");

            // FileStreamのデフォルトはFileShare.Read
            using (FileStream stream = new FileStream("aaa.txt", FileMode.Open, FileAccess.Read))
            {
                using (new StreamReader("aaa.txt"))
                {
                    Console.WriteLine("OK read");
                }
                try
                {
                    using (new StreamWriter("aaa.txt", true))
                    {
                        Console.WriteLine("OK write");
                    }
                }
                catch (IOException ex)
                {
                    Console.WriteLine("NG write");
                }
            }
            // 読み込み中に読み込み可能
            Console.WriteLine("------------------");
            Console.WriteLine("FileShare.Write");

            // FileStreamのデフォルトはFileShare.Read
            using (FileStream stream = new FileStream("aaa.txt", FileMode.Open, FileAccess.Read, FileShare.Write))
            {
                using (new StreamWriter("aaa.txt", true))
                {
                    Console.WriteLine("OK write");
                }
                using (new StreamWriter("aaa.txt", true))
                {
                    Console.WriteLine("OK read");
                }
            }
        }
    }
}

2010年10月2日土曜日

FlowLayoutControlにInsertしてみる。

色々困ったことはあったけど、ある程度動くようになってきました。
困ったことはまた別の機会に整理して書いてみようかと思います(たぶん)

C#で作っているのですが、UIで悩みました。
一覧表示するのに、DataGridViewを使うとあまりにもシンプルすぎて、見た目が悪いなーと。
で、UserControl+FlowLayoutPanelを使うことに。
読み込んだTimeLineの一覧を表示するだけならFlowLayoutPanelのControlsにUserControlをAddするだけでよかったのです。
が。。。
差分だけTimeLineを更新するときにAddすると?リストの最後にUserControlが追加される。
考えてみたら当たり前のことなですがね…

Insertとかいう便利なメソッドはFlowLayoutPanelのControlsにはついていないワケでして、
ControlsのメソッドをMSDNでみているとSetChildIndexと言うものがあるじゃないですか!
Controls.Add → Controls.SetChildIndex(追加したControl, 0) でリストの一番上に追加することが出来ました。

あまり使わないコントロールは使いにくいなー。

2010年6月30日水曜日

IDisposable実装のテンプレート

毎回調べてたので、テンプレートとして残しておく。
Disposeメソッドはusingでかこっても、非同期例外によってDisposeが呼び出されないことがあるので、IDisposableを実装する際には、アンマネージドオブジェクトを解放するためにファイナライザを実装しておく必要があります。

非同期例外恐ろしいですね。



public class DisposableImplClass : IDisposable
{
    private bool disposed;

    public DisposableImplClass()
    {
        disposed = false;
    }

    public void Dispose()
    {
        GC.SuppressFinalize(this);
        Dispose(true);
    }

    ~DisposableImplClass()
    {
        Dispose(false);
    }

    private void Dispose(bool disposing)
    {
        if (disposed)
        {
            return;
        }
        disposed = true;
        if (disposing)
        {
            // マネージリソースの解放処理
        }
        // アンマネージリソースの解放処理
    }
}


.

2010年5月22日土曜日

HskellのMaybeクラスをC#で作ってみた。その3


HaskellのMaybeクラスをC#で作ってみた。その2
で作成した
Maybeクラスの単体テストもNUnitを使って書いているので、
それも一緒に公開しておきます。



[TestFixture]
public class MaybeTest
{
[Test]
public void MaybeNothingTest()
{
Maybe<int> nothing = Maybe<int>.Nothing;
Assert.IsFalse(nothing.HasValue);
Assert.Throws<InvalidOperationException>(delegate { int i = nothing.Value; });
}

[Test]
public void MaybeFromTset()
{
DoMaybeFromTest((int)1);
DoMaybeFromTest(DateTime.Now);
DoMaybeFromTest(new InvalidOperationException());
DoMaybeFromTest(new Action<int>(DoMaybeFromTest));
}
[Test]
public void MaybeFromArgumentNullTset()
{
Assert.Throws<ArgumentNullException>(delegate { Maybe<InvalidOperationException>.Just(null); });
}

private static void DoMaybeFromTest<T>(T value)
{
Maybe<T> maybe = Maybe<T>.Just(value);
Assert.IsTrue(maybe.HasValue);
Assert.AreEqual(value, maybe.Value);
}
[Test]
public void GetValueTest()
{
Maybe<int> nothing = Maybe<int>.Nothing;
Assert.AreEqual(1, nothing.GetValue(1));

Maybe<int> maybe = Maybe<int>.Just(20);
Assert.AreEqual(20, maybe.GetValue(1));
}
[Test]
public void EqualsTest()
{
Assert.IsTrue(Maybe<int>.Nothing.Equals(Maybe<int>.Nothing));
Assert.IsTrue(Maybe<int>.Just(1).Equals(Maybe<int>.Just(1)));
Assert.IsTrue(Maybe<DateTime>.Just(new DateTime(2000, 10, 10, 10, 10, 10)).Equals(Maybe<DateTime>.Just(new DateTime(2000, 10, 10, 10, 10, 10))));

Assert.IsFalse(Maybe<int>.Nothing.Equals(null));
Assert.IsFalse(Maybe<int>.Nothing.Equals(Maybe<int>.Just(1)));
Assert.IsFalse(Maybe<int>.Just(19).Equals(Maybe<int>.Just(1)));
}

[Test]
public void OperatorEqualsTest()
{
Assert.IsTrue(Maybe<int>.Nothing == Maybe<int>.Nothing);
Assert.IsTrue(Maybe<int>.Just(1) == Maybe<int>.Just(1));
Assert.IsTrue(Maybe<DateTime>.Just(new DateTime(2000, 10, 10, 10, 10, 10)) == Maybe<DateTime>.Just(new DateTime(2000, 10, 10, 10, 10, 10)));

Assert.IsFalse(Maybe<int>.Nothing == null);
Assert.IsFalse(null == Maybe<int>.Nothing);
Assert.IsFalse(Maybe<int>.Nothing == Maybe<int>.Just(1));
Assert.IsFalse(Maybe<int>.Just(19) == Maybe<int>.Just(1));
}
[Test]
public void OperatorNotEqualsTest()
{
Assert.IsFalse(Maybe<int>.Nothing != Maybe<int>.Nothing);
Assert.IsFalse(Maybe<int>.Just(1) != Maybe<int>.Just(1));
Assert.IsFalse(Maybe<DateTime>.Just(new DateTime(2000, 10, 10, 10, 10, 10)) != Maybe<DateTime>.Just(new DateTime(2000, 10, 10, 10, 10, 10)));

Assert.IsTrue(Maybe<int>.Nothing != null);
Assert.IsTrue(null != Maybe<int>.Nothing);
Assert.IsTrue(Maybe<int>.Nothing != Maybe<int>.Just(1));
Assert.IsTrue(Maybe<int>.Just(19) != Maybe<int>.Just(1));
}

[Test]
public void CastTest()
{
Maybe<Encoding> maybe = Maybe<Encoding>.Just(Encoding.UTF8);
Assert.AreEqual(Encoding.UTF8, (Encoding)maybe);
}
}

HaskellのMaybeクラスをC#で作ってみた。その2


HaskellのMaybeクラスをC#で作ってみた
のMaybeクラスではdefault(T)が気持ち悪かったので、
ガサゴソと、クラスを分離してみた。



public interface IMaybe<T>
{
bool HasValue { get; }

T Value { get; }
}

public class Maybe<T> : IMaybe<T>
{
private readonly IMaybe<T> _maybeValue;

public Maybe(IMaybe<T> maybeValue)
{
_maybeValue = maybeValue;
}
public bool HasValue { get { return _maybeValue.HasValue; } }

public T Value { get { return _maybeValue.Value; } }

public T GetValue(T defaultValue)
{
if (HasValue)
{
return Value;
}
return defaultValue;
}

public static bool operator ==(Maybe<T> left, Maybe<T> right)
{
if (ReferenceEquals(left, right))
{
return true;
}
if (ReferenceEquals(left, null))
{
return false;
}
return left.Equals(right);
}
public static bool operator !=(Maybe<T> left, Maybe<T> right)
{
return !(left == right);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(this, obj))
{
return true;
}

Maybe<T> maybe = obj as Maybe<T>;
if (ReferenceEquals(maybe, null))
{
return false;
}
if (HasValue != maybe.HasValue)
{
return false;
}
if (HasValue)
{
return Value.Equals(maybe.Value);
}
return true;
}
public override int GetHashCode()
{
if (HasValue)
{
return Value.GetHashCode() * 751;
}
return 0;
}
public static explicit operator T(Maybe<T> maybe)
{
return maybe.Value;
}
public static Maybe<T> Nothing = new Maybe<T>(new Nothing<T>());

public static Maybe<T> Just(T value)
{
return new Maybe<T>(new Something<T>(value));
}

}

internal class Nothing<T> : IMaybe<T>
{
public bool HasValue
{
get { return false; }
}

public T Value
{
get
{
throw new InvalidOperationException("No Value");
}
}
}
internal class Something<T> : IMaybe<T>
{
private readonly T _value;
public Something(T value)
{
if (ReferenceEquals(value, null))
{
throw new ArgumentNullException("value is null");
}
_value = value;

}
public bool HasValue
{
get { return true; }
}

public T Value
{
get
{
return _value;
}
}
}




NUnitのテストコード
も公開しています。
.

HaskellのMaybeクラスをC#で作ってみた。

Maybeクラスを作ってみました。
Nothingの場合にnullにしていたんですけど、コンパイルエラーに!
default(T)なんてのがあるんですね。

しかし、default(T)は必要あるのか?
Nothingの場合は値を持つ必要が無いので、Valueで例外、HasValueでfalseを返すだけのクラスがあっても良さそう。


HaskellのMaybeクラスをC#で作ってみた。その2

default(T)を消してクラスを分離したバージョンを作成しました。



public class Maybe<T>
{
private readonly T _value;
private readonly bool _hasValue;
public Maybe(T value)
: this(value, true)
{
if (ReferenceEquals(value, null))
{
throw new ArgumentNullException("value is null");
}
}
private Maybe(T value, bool hasValue)
{
_value = value;
_hasValue = hasValue;
}
public bool HasValue
{
get { return _hasValue; }
}

public T Value
{
get
{
if (_hasValue)
{
return _value;
}
throw new InvalidOperationException("No Value");
}
}

public T GetValue(T defaultValue)
{
if (_hasValue)
{
return _value;
}
return defaultValue;
}

public static bool operator ==(Maybe<T> left, Maybe<T> right)
{
if (ReferenceEquals(left, right))
{
return true;
}
if (ReferenceEquals(left, null))
{
return false;
}
return left.Equals(right);
}
public static bool operator !=(Maybe<T> left, Maybe<T> right)
{
return !(left == right);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(this, obj))
{
return true;
}

Maybe<T> maybe = obj as Maybe<T>;
if (ReferenceEquals(maybe, null))
{
return false;
}
if (_hasValue != maybe.HasValue)
{
return false;
}
if (_hasValue)
{
return _value.Equals(maybe.Value);
}
return true;
}
public override int GetHashCode()
{
if (_hasValue)
{
return _value.GetHashCode() * 751;
}
return 0;
}
public static explicit operator T(Maybe<T> maybe)
{
return maybe.Value;
}
public static Maybe<T> Nothing = new Maybe<T>(default(T), false);

public static Maybe<T> Just(T value)
{
return new Maybe<T>(value);
}
}



NUnitのテストコード
も公開しています。
.

2010年4月3日土曜日

Windows環境にCassandra Thriftをインストールしてみた。

CassandraをC#で使って遊んでみよーってことでWindows環境にほりこんでみたので
その忘却ログ。

CassandraのインタフェースがThiftで記述されているので、
まずThriftのインストールを行う。
早速Thriftのダウンロードページへ!
http://incubator.apache.org/thrift/download/

あれ?
Windows用のバイナリがない!
ソースコードしかない!

ってことでCygwinでコンパイルすることに。
参考にしたサイトは
http://wiki.apache.org/thrift/ThriftInstallationWin32

Cygwinで以下のライブラリをインストールする必要があるみたいなので、

探してインストール(面倒な人は、CygwinのDevel以下をすべて入れちゃえばOKです。)
  • GNU build tools (autoconf 2.60, automake 1.10, libtool 1.5.24)
  • boost 1.33.1+
  • g++ 4.0+
  • bison 2.3-1
  • boost 1.33.1-4
  • boost-devel 1.33.1-4
  • flex 2.5.33-1
  • pkgconfig
  • libtool
これでcygwinの環境構築はOK。
続いてThriftのバイナリを作成へ。
Thriftのダウンロードサイト(http://incubator.apache.org/thrift/download/)から


ソースコードをダウンロード
Thiftを解凍したフォルダへ移動して。
以下のコマンドを順番に実行。

./bootstrap.sh

export CXXFLAGS="-D PTHREAD_MUTEX_RECURSIVE_NP=PTHREAD_MUTEX_RECURSIVE"

./configure

cd compiler/cpp

make

make install

はいおしまい。

続いてCassandraのインストール
ここから0.5.1をダウンロードしました。
http://cassandra.apache.org/

解凍してCassandraのinterfaceフォルダに"cassandra.thrift"ってファイルがあるので、
そこのフォルダまで移動してThiftを実行すればC#のコードが完成!

僕はここにCassandraを解凍(/usr/local/src/apache-cassandra-0.5.1)

cd /usr/local/src/apache-cassandra-0.5.1/interface
$ thrift --gen csharp cassandra.thrift

C#のコードはgen-csharpに出来上がります。
/usr/local/src/apache-cassandra-0.5.1/interface/gen-csharp

ふぅ満足♪
.

2009年10月4日日曜日

SharpDevelopを使ってみた。

C#のオープンソースIDE『SharpDevelop』を使ってみました。
http://www.icsharpcode.net/OpenSource/SD/

標準でNUnit・PartCover・Subversionに対応しており、全てGUIから操作が可能で、
テストとカバレッジ表示もソースコードと連動していてかなり便利です。

C#のMono Compilerにも対応しているのも良い点です。

個人的に評価しているのはTODOなど特定の文字列でコメントした箇所を一覧で表示できることですね。
関数やクラス名の変更などリファクタリングに対する機能はVisualStudioがかなり充実している感じました。

コードを綺麗にするリファクタリングを行いにくい点以外はVisualStudioより良いと思いました。
※拡張機能を何もインストールしていない状態での個人的な意見となります。
あくまでもご参考までに。

.

2009年9月25日金曜日

NUnit で TestSuite の作成と実行

VS2008で、プロジェクト(DLL)毎に記述したテストクラスを
一度にまとめて実行したい!と思ったのが発端。

NUnitのドキュメントを見る限り、どうやらSuite属性を使えば出来る模様。
http://www.nunit.org/index.php?p=suite&r=2.5.2

で作成してみたサンプル
SmapleTest.DLL
------
namespace SmapleTest
{
[TestFixture]
public class SampleTest
{
[Test]
public void TestCase1
{
Assert.Fail("失敗するテストケース");
}
}
}
------

TestSuite.DLL
------
namespace TestSuite
{
public class AllTest
{
[Suite]
public static IEnumerable Suite
{
get
{
ArrayList suite = new ArrayList();
suite.Add(new SampleTest());
return suite;
}
}
}
}
------

これをNUnit.exeに読み込ませてみる。
これで完成!



と思いきや。


NUnitに表示されたのは一行のみ
『C:\TestSuiteSample\TestSuiteSample\bin\Release\TestSuite.DLL』
DLLの絶対パスやん。

おもむろにRUNボタンを押してみるが、動作しません。


再度NUnitのドキュメントを読み直しました今度はちゃんと。

NUnitの起動時に/fixtureのコマンドラインオプションをつけてねと書いてありました。

コマンドプロンプトで以下を実行(全て一行で書いてます。)
-----
C:\Program Files\NUnit 2.5.1\bin\net-2.0\nunit.exe /fixture:TestSuite.AllTest C:\TestSuiteSample\TestSuiteSample\bin\Release\TestSuite.DLL
-----

fixtureオプションでSuite属性のプロパティを持っているクラスの絶対パス(名前空間を含めたフルパス)を指定します。

これで立ち上がったNUnitにちゃんとSampleTestのテストケースが表示され、
実行することが出来ました!


英語を読むのに苦労しましたが、何とかテストスイートの作成に成功!
これで少しテストコードの作成が面白くなってきました♪

.

2009年9月12日土曜日

NUnitメモ

NUnit を使い始めたのでメモ書き。

・クラスと Test 属性をつけた関数は public にする必要がある。
・NUnitに読み込ませるのは DLL、EXE どちらの形式にしても OK 。


以下のような形でクラスを作成します。

----
[TestFixture]
public class TestSample
{
[SetUpFixture]
public void SetUpFixture()
{
// [TestFixture]の最初に一度だけ呼び出される関数。
}

[TestFixtureTearDown]
public void TestFixtureTearDown()
{
// [TestFixture]の最後に一度だけ呼び出される関数。
}

[SetUp]
public void SetUp()
{
// [Test]メソッドを呼び出す前に実行される。
//([Test]が複数あれば複数回呼び出される)
// 必要なインスタンスの生成などを行う。
}

[TearDown]
public void TearDown()
{
// [Test]メソッドを呼び出した後に実行される
//([Test]が複数あれば複数回呼び出される)
// リソースの解放処理などを行う。
}

[Test]
public void Test()
{
// ここにテストコードを記述

// 期待値とテスト結果の比較には以下のメソッドを使用する。
Assert.AreEqual("a", "a"); //OK
Assert.AreEqual("a", "b"); //NG
}

[Test]
[ExpectedException(typeof(ArgumentException))] // この場合はArgumentExceptionが発生しなければテスト失敗となる。
public void TestCatchException()
{
// ここにテストコードを記述
}
}
----
NUnitではAssertで失敗すると例外が発生してそこでテストが止まります。

私はテストする関数毎にテストクラスを用意して、
テストケース毎にテスト関数([Test]属性が付いた関数)を作成するようにしています。


.

2009年7月20日月曜日

クラスのプロパティを取得する。

クラスからプロパティの一覧を取得する方法です。

--------------------
using System.Reflection;

// クラスの定義
class TestData {
public Text{get; set;}
}

// 任意の関数に以下をコピー。
Type t = typeof(TestData);
PropertyInfo[] propertyies = t.GetProperties();

foreach(PropertyInfo info in propertyies)
{
Console.WriteLine(info.Name);
Console.WriteLine(info.CanRead);
Console.WriteLine(info.CanWrite);
}
--------------------


同様にメンバを取得するメソッドもありますので、
クラスの型が判ればメンバを取得するのは簡単に出来ます。


.

2009年5月18日月曜日

文字列の数値変換

文字列→数値
数値→文字列
Convertクラスを使うことでどちらも簡単に出来ます。
#2進数変換や16進数変換までも。。。

■数値変換
Convert.ToInt32("01234"); // 1234 10進数
Convert.ToInt32("FF",16); // 255  16進数
Convert.ToInt32("1111",2); // 7  2進数

■文字列変換
Convert.ToString(1234);// "1234"  10進数
Convert.ToString(255, 16);// "FF" 16進数
Convert.ToString(7,2);// "1111"  2進数

気をつけないといけないのは
変換に失敗した場合、Exceptionが発生するのでCatchしておく必要があります。


■例外が発生しない 文字列→数値変換
※各クラスのTryParseメソッドを使います。

Int32 number;
if (Int32.TryParse("1234, out number) == true){
// 変換成功
} else {
// 変換失敗
}

.

2009年4月26日日曜日

XMLの設定ファイル

設定ファイル作成に良く使っているクラスなので公開っと。
XMLシリアライズ

---------

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml.Serialization;

namespace SettingData
{
public class MyXmlSerializer
{
public void Serialize(T settingdata, string fileName)
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
using (FileStream stream = new FileStream(fileName, FileMode.Create))
{
serializer.Serialize(stream, settingdata);
}
}

public T Deserialize(string fileName)
{
if (File.Exists(fileName) == false)
{
throw new FileNotFoundException("ファイルが見つかりません、設定ファイルの読み込みに失敗しました。", fileName);
}

XmlSerializer serializer = new XmlSerializer(typeof(T));
T settingdata;
using (FileStream stream = new FileStream(fileName, FileMode.Open))
{
settingdata = (T)serializer.Deserialize(stream);
}
return settingdata;
}
}
}
---------



.

2009年3月28日土曜日

C#で typedef

ないのかー!
って探したけど。無かった。代替方法はあったよ。

無い理由は
C#では一つのクラスは一つのクラス名ってことみたいで、
typedef は考慮されずにC#の仕様がきまったことだそうです。
将来は typedef が仕様として組み込まれる可能性はありますが。。


代替方法としては、using を使うってこと。
ただし、宣言したファイル内のみでしか使えないのがネック。。

privateな宣言やったらそのファイルのみで良さそうなので、
使えそうやけど。
他のクラスでも使っていたりすると共通性が無くなってしまうので、
混乱しそうですね。


あんまし便利そうには見えない using の使い方でした。
頭の片隅においておこっと。

.

C#Win32APIの構造体を扱う

C#からWin32APIの構造体ここではRECTをとりあげますが、
他の構造体も同じように扱うことが出来ます。

直接C#のRectangleを使えたら。。便利なのに。
とは思いましたが、構造体のメモリ配置などの関係により、
直接Rectangleは使えません。

で、新しく構造体を定義して使うのですが、メモリ配置がネックになってきますので、
メモリ配置(レイアウト)を決める属性をつけて構造体を定義します。

詳しくはMSDNを参照のこと。
■LayoutKind 列挙体

http://msdn.microsoft.com/ja-jp/library/system.runtime.interopservices.layoutkind(VS.71).aspx


構造体の定義が出来れば後はただ使うだけっと。
コードは以下のようになります。
----------------
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
}
[DllImport("user32.dll")]
public static extern void GetWindowRect(IntPtr hWnd, out RECT wndRect);
----------------


こんな感じ。

.

2009年3月23日月曜日

C#でアクティブウィンドウの取得

アクティブウィンドウを取得する方法
アクティブプロセスからウィンドウハンドルを取得する。
直接アクティブウィンドウを取得する.NET FrameWorkのクラス(関数)は無いみたい。

Win32APIを使っての取得方法を紹介。
以下のクラス(関数)を使ってアクティブプロセスを取得し、
取得したプロセスのProcess.MainWindowHandle でウィンドウハンドルを取得します。

---------------
/// Win32API の extern 宣言クラス
public class WinAPI {
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();

[DllImport("user32.dll")]
public static extern int GetWindowThreadProcessId(IntPtr hWnd, out int lpdwProcessId);
}

public class sample {
///


/// アクティブなプロセスを取得する
///

/// アクティブプロセス
public static Process GetActiveProcess()
{
// アクティブなウィンドウハンドルの取得
IntPtr hWnd = WinAPI.GetForegroundWindow();
int id;
// ウィンドウハンドルからプロセスIDを取得
WinAPI.GetWindowThreadProcessId(hWnd, out id);
Process process = Process.GetProcessById(id)
return process;
}
}
---------------

取得したウィンドウハンドルとWin32APIを使って、
様々なプロセスに対しての操作が可能となります。

.

2009年3月22日日曜日

C#でWin32APIを呼び出す

方法はDLLをインポートして、メソッドを extern 宣言するだけ。
引数や戻り値はC#の型にあわせればOK。
あわない型であれば、コンパイル時にエラーが出ます。

MoveWindow 関数は以下のように宣言しました。

-------------
public class Test {
[DllImport("user32.dll")]
public static extern int MoveWindow(IntPtr hwnd, int x, int y, int nWidth, int nHeight, int bRepaint);
}
-------------

気をつけないといけないのは。。
Win32で使われている構造体ですね。
これらについてはまた書きます。

.

2008年12月24日水曜日

C#文字列のバイト数

何度調べたことか。。。
覚書として残しておきます。

.NET2.0 では、Stringクラスに文字数を取得するLengthというPropertyしかないんよね。
バイト数が知りたいと思ってもメソッドがありません。
全角文字やと1文字が2バイトになり。
入力制限を設けるのに嵌りました。

@ITにそのままの記事があったのでリンクを載せておきます。
http://www.atmarkit.co.jp/fdotnet/dotnettips/012strcount/strcount.html
----抜粋------------
String str;
Encoding sjisEnc = Encoding.GetEncoding("Shift_JIS");
int num = sjisEnc.GetByteCount(str);
--------------------

Encoding のGetByteCountメソッドを使ってバイト数を求めます。
文字コードがUTF-8の場合などはGetEncodingの引数を変更すればOKです。

.

ラベル