2008年12月30日火曜日

[.NET]Control.Updateの活用

たとえば100回ループする処理を実行中に状況を画面に表示したい場合、ループ内で単純にControl.Text属性を変更しても画面は更新されません。以下のbutton1_Clickがその例です。

回避方法としてすぐに思いつくのがDoEventsを使う方法です。以下のbutton2_Clickがその例です。しかしDoEventsは副作用があり、他の処理に影響を及ぼしてしまう場合があります。そのため、利用をできるだけ控えてきましたが、こういう処理の場合泣く泣くDoEventsを書いてきました。

しかし、button3_ClickのようにControl.Updateを使用する方法があること今日知りました。ということで確認の実装してみました。Control.Updateでも目的は達成できますね。

/// <summary>
/// 画面更新されない例
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object senderEventArgs e)
{
    for (int i = 0i < 100i++)
    {
        Thread.Sleep(100);
        // textBox1に値を設定しているけど、ループ中画面は更新されない。
        textBox1.Text = i.ToString();
    }
    textBox1.Text = "Finish!!";

}

/// <summary>
/// Application.DoEventsで画面を更新する例
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button2_Click(object senderEventArgs e)
{
    for (int i = 0i < 100i++)
    {
        Thread.Sleep(100);
        textBox1.Text = i.ToString();
        // DoEventsでメッセージQueueを処理する。
        Application.DoEvents();
    }
    textBox1.Text = "Finish!!";
}

/// <summary>
/// Control.Updateで画面を更新する例
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button3_Click(object senderEventArgs e)
{
    for (int i = 0i < 100i++)
    {
        Thread.Sleep(100);
        textBox1.Text = i.ToString();
        // Control.Updateで処理する。
        textBox1.Update();
    }
    textBox1.Text = "Finish!!";
}

2008年12月28日日曜日

[.NET]VB.NETの三項演算子

C#では、三項演算子を以下のように書きます。

int result = arg == null ? 0 : arg.Length;


しかし、VB.NETにはコレ相当の演算子はありません。が、新しいバージョンでは、Ifなる演算子が追加されていたようです。コードはこんなかんじ

Dim result As Integer = IIf(arg = Nothing0arg.Length'実行時エラーになる
Dim result2 As Integer = If(arg = Nothing0arg.Length)

2008年12月24日水曜日

[.NET]画像処理グレースケール化(4)

以前、Unsafeを使わずに配列処理の処理をし画像をグレースケール化するGDD Blog: [.NET]画像処理グレースケール化(1)
GDD Blog: [.NET]画像処理グレースケール化(2) GDD Blog: [.NET]画像処理グレースケール化(3) という記事を書きましたが、パフォーマンスの比較をするためにあえてUnsafeを使ってパフォーマンスを計測してみました。コードはこんな感じ。


//以下の構造体を別途定義
//private struct RGB
//{
//    public byte b;
//    public byte g;
//    public byte r;
//}

Bitmap bmp = new Bitmap(ctlPicture.Image);

//bitmapをメモリ上にロックします
Rectangle rect = new Rectangle(00bmp.Widthbmp.Height);
BitmapData bmpData = bmp.LockBits(rectImageLockMode.ReadWrite,
                                          PixelFormat.Format24bppRgb);

int stride = bmpData.Stride;
int size = stride * bmp.Height;

unsafe
{
    RGBpRGB = (RGB*)bmpData.Scan0.ToPointer();
    for (int j = 0j < sizej = j + sizeof(RGB))
    {
        byte val = (byte)Math.Round((pRGB->r + pRGB->g + pRGB->b) / 3.0d);
        pRGB->r = val//r
        pRGB->g = val//g
        pRGB->b = val//b
        pRGB++;
    }
}

bmp.UnlockBits(bmpData);
ctlPicture.Image = bmp;


5回の計測の平均値で20.2msでした。Unsafeを使った割にはアレですね。

2008年12月21日日曜日

[他]SQLServer2008 Express用 SMS

以前、VS2008 Express Editionを入れたときに、SQLServer2005から2008にバージョンアップしました。しかし、2005用のSMS(SQLServe Management Studio)ではSQLServer2008にはつながらないようです。

で、しらべてみると、Microsoft® SQL Server® 2008 Express with Toolsというのがありました。備忘録としてメモ。

ダウンロードしたツールの、「インストール」→「SQL Serverの新規スタンドアロン インストールまたは既存のインストールへの機能追加」を選択。あとはウィザードに従って次へボタンを押下。チェックボックスで何を入れるかを選択する画面があります。ここで管理ツールっぽいものをチェックすればOK。

しかし、PowerShellをインストールしていないと先に進めません。コレがまた面倒(個人的見解)なんです。
PowerShellを入れたくない人は入れれないことになりますね。

2008年12月15日月曜日

[.NET][Java]単体テストツール

現在、短期のJavaプロジェクトに携わっています。画面の無いサービス的なアプリケーション開発ということもあり、JUnitで単体テストを組むことにしました。
で、カバレッジ計測をしたかったため、JUnitと連動する計測ツールを探したところ、djUnitにたどり着きました。ツールをEclipseに導入して単体テストを動作させると、未通過のロジックにはしるしが付いたり、レポートが表示されたりと、至れり尽くせり。さらにこのdjUnitはMockとしての機能があり、特定のメソッドの戻り値を強引に書き換えたり、例外を発生させたりすることができます。
もう自分でMockを書かなくても大半はカバーできたりします。最近みたツールの中では最高かもしれません。

で、.NET系でも同じようなツールはないかと思い検索したところ、Typemockというツールがヒットしました。実際に使っていませんが、MSDNマガジン2008/6月号に記事が載っていました。
次回、機会があったら使ってみようと思います。

2008年12月10日水曜日

[.NET]FileSystemWatcher

VS2005以降だと思いますが、FileSystemWatcherというコンポーネントが存在します。
興味があったのでちょっと使ってみました。

FileSystemWatcherではEnableRaisingEventsというプロパティにて、イベント処理型と、変更待機のいずれかを選択することができます。
以下の例では、サブフォルダ配下も含め、ファイルの生成・更新・リネーム・削除を監視し何かあったら画面に表示するというサンプルです。イベント処理のタイプで実装しています。


public partial class Dust28Form : Form
{
    public Dust28Form()
    {
        InitializeComponent();
    }


    private void Dust27Form_Load(object senderEventArgs e)
    {
        //デザイナで以下のプロパティが設定してある

        ////サブディレクトリを含めるかどうか
        //fileSystemWatcher.IncludeSubdirectories = true;
        ////ファイル名のフィルタリング(ぜんぶ)
        //fileSystemWatcher.Filter = true;
        ////監視対象フォルダ
        //fileSystemWatcher.Path = "c:\temp";
        ////監視対象のイベント
        //fileSystemWatcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.LastWrite | NotifyFilters.DirectoryName;


        //イベント ハンドラ呼び出しをマーシャリングするために使用するオブジェクト
        fileSystemWatcher.SynchronizingObject = this;
        //初期状態は機能を無効にする
        fileSystemWatcher.EnableRaisingEvents = false;
    }

    private void btnMonitor_Click(object senderEventArgs e)
    {
        //ボタン押下イベント。機能の有効無効を排他的に切り替えている

        //今のステータスと入れ替える
        fileSystemWatcher.EnableRaisingEvents = !fileSystemWatcher.EnableRaisingEvents;
        //ボタンのキャプションを変更する
        btnMonitor.Text = fileSystemWatcher.EnableRaisingEvents ? "監視停止" : "監視開始";
    }

    private void fileSystemWatcher_Changed(object senderSystem.IO.FileSystemEventArgs e)
    {
        //更新
        AddLog("Changed"e);
    }

    private void fileSystemWatcher_Created(object senderSystem.IO.FileSystemEventArgs e)
    {
        //生成
        AddLog("Created"e);
    }

    private void fileSystemWatcher_Deleted(object senderSystem.IO.FileSystemEventArgs e)
    {
        //削除
        AddLog("Deleted"e);
    }

    private void fileSystemWatcher_Renamed(object senderSystem.IO.RenamedEventArgs e)
    {
        //名前変更
        AddLog("Renamed"e);
    }

    private void AddLog(String evtSystem.IO.RenamedEventArgs e)
    {
        //画面への出力(ファイル名変更)
        textLog.AppendText(String.Format("{0} Event={1} File={2} OldFile={3}\n"evte.ChangeTypee.FullPath,e.OldFullPath));
    }

    private void AddLog(String evtSystem.IO.FileSystemEventArgs e)
    {
        //画面への出力(更新・削除・作成)
        textLog.AppendText(String.Format("{0} Event={1} File={2}\n"evte.ChangeTypee.FullPath));
    }

}

2008年12月7日日曜日

[.NET]log4netのPatternにTabを含める

先日@itの掲示板を見ていると「【Log4net】エラーログをタブ区切りにしたい」という話題が挙がりました。

私も興味があったので調べてみましたが、結局わからず、PatternConverterを使ってがんばれば。という結論に達しました。しかし、そのレスを見ると、xml的な解決策を提示していました。
目からうろこです。すばらしい発想の転換ですね。しかし、当然といえば当然なんですけどね。

2008年12月5日金曜日

[.NET]埋め込みリソース

VS.NET2003以前はよく知りませんが、VS2005以降では、プロジェクトの中に好きなリソースを埋め込むことができます。画像やHTMLをアセンブリの中に埋め込むイメージです。

作業としては、以下のとおりです。
  1. 該当のリソースを右クリックし、「ビルドアクション」を「埋め込まれたりソース」にする
  2. Assembly.GetManifestResourceStreamを使用し情報を取り出す


コードのほうはこんな感じ。以下の例ではプロジェクト内にhtmlというフォルダがある前提。
(ネームスペース+フォルダ+ファイル名というところがアレ)

string result = string.Empty;

//タイプからリソース名を組み立てる(namespace + フォルダ名 + ファイル名)
//プロジェクトに「html」というフォルダがある
string resName = GetType().Namespace + ".html." + name;

try
{
    Assembly asm = Assembly.GetExecutingAssembly();
    using (StreamReader rd = new StreamReader(asm.GetManifestResourceStream(resName)))
    {
        result = rd.ReadToEnd();
    }
}
catch
{
    //特にないもしない
}

2008年12月1日月曜日

[.NET]MenuStripで左の余白を消す方法

ContextMenuStripでは、AutoSizeとShowImageMargine属性を使うことにより、左側のイメージが表示されている余白を削除することができます。しかしどういうわけかMenuStripにはShowImageMargine属性が無いため、左の余白を消すことができないみたいなのです。

コレに対し、MenuStripからContextMenuStripを表示する方法が紹介されていました。結構強引なやり方だと思いますが、ありはありですね。

方法 : ContextMenuStrip コントロールでチェックの余白とイメージの余白を有効にする