The Art of Unit Testingの表紙がすごい

本家スラドに気になる題名『The Art of Unit Testing』の本がブックレビューされていたので見てみた。

すると…本の内容より表紙の絵が気になって仕方なくなってしまい。だた、それだけで珍しく更新している次第です :)

The Art of Unit Testing: With Examples in .net
The Art of Unit Testing: With Examples in .net

あ、内容は至って真面目なものでサンプルは.net向けのようですが….net使い以外でも読む価値はあるかも。もし、翻訳されたら読んでみるかもってレベルですかね。

TrackBack URL :

ErrorProviderの自分メモ

.NET Frameworkの流儀に従うならば、バリデーションチェックはErrorProviderクラス(System.Windows.Forms)を使うのが粋ってものらしい。

ならば一度使ってみるかと思い初体験してみた :) え、今まで何で使ってないんだって…C#でバリデーションの必要なUI作るの初めてだし、Compact Frameworkにはないしね~と言い訳 ;)

デモプログラムなんで、入力は一箇所だし非常に簡単なので以下のあたりを参考に適当に実装してみた。

ほぉ、簡単にできるなぁ~入力異常時に表示されるデフォルトのアイコンがちょっとウザイけど…まぁ、こんなもんだろうと。

ところが…エラーがある状態だとウィンドウクローズでプログラムの終了ができない罠 :shock:

フォームのAutoValidateプロパティがデフォルトでEnablePreventFocusChangeになっているためのようです。かと言って、他のに変えるのも面倒だし…と言うことで検索。

おぉ、すごいちゃんとカスタムコントロール化してる人が居るじゃないですかぁ。

ちょっとソースを拝見…ここまでのものは今は要らないけどテストプログラムも付いてるので動きを見るのに最高です :!:

で、少し追ってみると :idea: なるほど、エラーがある状態でもプログラム終了できるようにしたければ…フォームのCloseingイベントでe.Cancelをfalseにしちゃえば良いみたいですね ;)

C#クックブック 第3版 C#クックブック 第3版
鈴木 幸敏

絶対現場主義Visual C#実践講座―開発の現場から生まれた実践テクニック&TIPS集 LINQテクノロジ入門~Microsoft Visual Studio 2008による新たなクエリ構築技法~ (マイクロソフトコンサルティングサービステクニカルリファレンスシリーズ) (マイクロソフトコンサルティングサービステクニカルリファレンスシリーズ) Microsoft Silverlight 2テクノロジ入門 (マイクロソフト公式解説書) C#エッセンシャルズ 第2版 プログラミングMicrosoft ASP.NET 3.5 (マイクロソフト公式解説書 Microsoft Visual Studi)
by G-Tools

TrackBack URL :

ハンドルされていない例外の捕捉でハマル

C#でシリアル通信のプログラムを書いてたわけですが…最近はCOMポートを持っていないマシンが多く、わたしの使ってるマシンも標準ではCOMポートがありません。

そこで、以下のUSB-シリアル変換器を使ってるわけです。COM番号etc.の設定もできるしなかなかの優れもの。

B000ANR7T4 REX-USB60F USB-Serial Converter
ラトックシステム 2005-06-30

by G-Tools

アプリケーションから見ると普通のCOMポートとなんら変わりなく扱えます。

そこで、ちょっとした出来心が…実行途中でUSB-シリアル変換機を抜いてからアプリケーションを終了すると。COMポートを閉じに行くところで…うぎゃ~system.dllでハンドルしてない例外が飛び出てアプリケーションエラー発生 :| ポートをクローズするところのtry…catchでは捕まえられないんですね :shock:

まぁ、以下にあるMSDNのサンプルでも同じ現象なのでヨシですね(違。

まぁ、実段階ではCOMポートを装備したマシンを使うので、ポートがなくなるなんて事態はありえないわけですが :arrow:

でも、アプリケーションエラーがでるのはキモチ悪いので『@IT:.NET TIPS 適切に処理されなかった例外をキャッチするには?』あたりを参考に捕捉してみました。

確かに捕捉はできたのですが、MessageBoxをわざわざ表示することもないかと思いUnhandledExceptionを握りつぶすだけにすると…。

ぎゃあ~アプリケーションエラー復活

仕方ないので、さらに検索してみると…

のようにUnhandledExceptionハンドラでEnvironment.Exitを呼び出してる人が結構いるようなので真似してみたら…アプリケーションエラーはでなくなりました ;)

どうも、UnhandledExceptionが発生した時の状態にはMessageBoxで止まったり、止まらなかったり数種の状態がある感じがします。

なので、UnhandledExceptionのハンドラではMessageBoxとかは使わずにコンソールやログ出力だけして、Environment.Exitを呼び出して終わるのが「吉」っぽいと言うのが結論でした。

ちゃんちゃん :roll:

TrackBack URL :

"愛々,1".IndexOf(",")は1?

結構ヒドイバグですね :roll:

ちなみに.NET Compact Framework 2.0では大丈夫でした。

ちゃんとマイクロソフトには、報告を入れてくれてますが…。

いつ直るかなぁ :arrow: もしや、コレもIMEとかのようにチャイナクオリティですか :?: それとも、日本語が亡びる前兆ですか :mrgreen:

TrackBack URL :

複数選択可能なListViewコントロール

いや、もちろんCompact Frameworkでなければ…ListViewのMultiSelectプロパティをTrueにするだけ ;)

なので、ListViewコントロールを見ると…ないよ :shock: でたぁ~また、Compact Frameworkにはない :arrow:

要するにチェックボックス付きがあるだろう…ってのがMS様の言い分なのかな :?: 仕方ないので、Google先生に訊いてみるが…なかなか答えてくれない :cry:

そんな中、CodeProjectで見つけたのはCompact Frameworkとは全く関係ない…以下のXPTableというListView拡張で、何かの機会に使うためにメモ :)

あ、Compact Frameworkでした。調べてると同じことで質問してる人は居るんだけど…なかなか望んだ回答がでていないなぁ~と思っていると以下のページを発見。

ページの中にuuencodeされたMultiSelectListView.zipというファイルが貼り付けられてるなぁ~内容はわからないけど、どにかくエディタに貼り付けて…改行コードをLFで保存して、Cygwinのuudecodeでファイルを取り出してみた。なんか、uudecodeなんて使うの超ひさしぶりだなぁ~なんて思いつつ。

でてきた、MultiSelectListView.zipを展開すると…おぉ、VB.netのコードだったのね。量からみて、大きくないのはわかっていたので中身を見てみる。

なるほどポイントは、P/Invokeを使ってSetWindowLongを呼び出して、ウィンドウ(ListView)のLVS_SINGLESEL属性を外してやることだけなのね :idea: わかってみれば、なるほどなんだけど…思いつかなかったなぁ。

と言うことで、C#に書き直したポイントだけのコードをペタっとしておきます ;) ありゃ、わざわざGetCaptureしてウィンドウハンドルを取らなくてもListViewのプロパティから取れますね :arrow:

    private const int GWL_STYLE = -16;
    private const int LVS_SINGLESEL = 0x4;
 
    [DllImport("coredll.dll")]
    static extern IntPtr GetCapture();
    [DllImport("coredll.dll", SetLastError = true)]
    private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
    [DllImport("coredll.dll", SetLastError = true)]
    private static extern UInt32 GetWindowLong(IntPtr hWnd, int nIndex);
 
    private void EnableMultiSelect(ListView listView)
    {
        listView.Capture = true;
        IntPtr hWnd = GetCapture();
        listView.Capture = false;
        uint style = GetWindowLong(hWnd, GWL_STYLE);
        SetWindowLong(hWnd, GWL_STYLE, (int)(style & ~LVS_SINGLESEL));
    }

このEnableMultiSelectメソッドをListViewを使うフォームのコンストラクタあたりで、複数選択させたいListViewを引数にして呼べば幸せになれるかも知れません。

さらに、CtrlキーやShiftキーを同時押下するのが面倒(ソフトウェアキーボードだもんね)なんて場合は、ListViewのフォーカスイン時とフォーカスアウト時にCtrlキーを制御してフォーカスのある間はCtrlキーを押した状態にしておけば…さらに幸せになれるかも知れません ;)

Ctrlキーを制御するコードもついでなのでペタっと。

    private const byte VK_CONTROL = 0x11;
    private const int KEYEVENTF_KEYDOWN = 0x0;
    private const int KEYEVENTF_KEYUP = 0x2;
 
    [DllImport("coredll.dll", EntryPoint = "keybd_event", SetLastError = true)]
    internal static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);
 
    private void FocusIn()
    {
        keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYDOWN, 0);
    }
 
    private void FocusOut()
    {
        keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);
    }

あ、あと選択されている項目を取り出すコードもペタっとしとかなきゃ。

    ListView.SelectedIndexCollection collection = listViewMulti.SelectedIndices;
    int count = collection.Count; // 選択されている個数がcountに
    foreach (int i in collection)
    {
        // iに選択されているリストのインデックスが順次入る(当然0からの値)
    }

追記 2008-11-10 21:24:25
Ctrlキーの同時押しですが…FocusInとFocusOut時の制御では、やはり制御しきれないみたいです :|
結局、ListViewのWinProcをフックしてWM_LBUTTONDOWN時にMK_CONTROLビットをORすることで同時に押されている状態としました。
さらに、WM_LBUTTONDBLCLKとWM_KILLFOCUSメッセージを無視するようにすると…さらに幸せになれるかも知れません。

さらに追記 2008-11-13 01:13:25
WinProcのフックですが…『WndProcHooker クラスを使用する』のやり方を忠実に実装しました。当初、安易な方法で実装したら…最小化、最大化などを行うと思わぬ挙動をして半泣き。
なので、結局カスタムコントロール化してEnableMultiSelectと同様の処理をコンストラクタで行うようにして、ようやく最終形ができあがりました。
確かにカスタムコントロール内で全て閉じたのでコードは綺麗になったけど…超面倒ですね :|

TrackBack URL :

C#+Compact Frameworkでグリッドコントロール

まだ、開発言語が決まってないので(と言ってもC++かC#なんだけど)…C++の場合は「MFC Grid Control…使い方を忘れてる」で書いたMFC Grid controlを使うことに決定。そこでC#版のグリッドコントロールでよいものはないかと探している。C#版と言っても開発対象はWindowsCEなので、.NET Compact Frameworkで動くもの。

標準で用意されてるのは、DataGridクラス。残念ながら、DataGridViewクラスはCompactにはない :| あれば、DataGridViewクラスの機能で十分なんだけど…。

探してでてきたのは、FlexGrid for Mobile Devices…残念ながら製品でソコソコのお値段。まぁ、このくらいの価格なら問題ないんだけど。とにかく試使用版があるのでダウンロードして試用してみる。

さすがに製品、非常によくできてると言うか簡単に使えますね~これで十分なんですが…フリーで良いものがないか、もう少し探してみる ;)

う~ん、細々したソフトでいくつかCompactにも対応してるものを見つけたのですが…どれも欲しい機能がない。セルにチェックボックスやコンボボックスを貼れるようにするなどDataGridTextBoxColumnクラスを拡張するものがほとんどで希望と違う :cry:

Compact Frameworkでなければ絶対使うだろうと思ったのが、Source Grid…コレ良いですね~残念ながらFAQに以下のように書かれてる。

Q: Can I use these controls with .NET Compact Framework? And with Mono?
A: Currently this project is compatible only with Microsoft .NET Framework and Windows platforms. I’m working for porting some of the code to Mono and Compact Framework. Consider anyway that all the code is written with managed C# so probably it is not too difficult to use this library with other frameworks.

う~ん、Compact Frameworkで使えるグリッドコントロールでFrozen column(スクロールしないようにカラムを固定)機能を持ったものはないかなぁ :?:

TrackBack URL :

FxCop 1.36…少し使ってみた、手ごわいなぁ

Code Analysis Team Blog : FxCop 1.36 Released!と言うことで、FxCopが1.36になっていたので試してみた。

「Microsoft StyleCop 4.3(C#静的解析ツール)リリース」で書いたStyleCopはソースコードから解析するが、FxCopはCIL(Common Intermediate Language)側から静的解析するツール。なので、C#以外でも使えるのが良いですね ;) 当然、CILにはインデントやコメントetc.の情報は含まれてないので、FxCopとStyleCopの棲み分けはチャンとあります。

Microsoft FxCop 1.36からダウンロードして、とりあえず単体のアプリケーションとして使ってみた。

警告、警告、警告、警告、警告…

うがぁ~警告が一杯 :roll: うへ、確かにそうです…わたしが悪いですって指摘が一杯 :cry:

でも、これを全部直すのは結構面倒だなぁ~FxCop手ごわいなぁ :arrow:

しかし、コンストラクタでメンバー変数をゼロで初期化してたらCLRが自動でやってるから、パフォーマンス落ちるから書くなって言われるのね。ふ~ん :|

で、どうせならVisualStudioに組み込みたいってことで…「豆魂 – 技術記事-VisualStudio2005とFxCopを利用した静的コード分析(1)」を参考にさせてもらって設定してみました。

さて、どこまで警告がなくなることやら :mrgreen:

TrackBack URL :

Compact Framework+C#で二重起動防止

まぁ、わざわざ載せておくほどでもないんですけど…自分用メモ。

Windows CE上のC#アプリケーションで二重起動を防止したかった。ググってみた、例によってWindowsでのページが引っかかる。例えば以下のページ…非常に親切に書かれてる。もちろん、WindowsというかCompactじゃない.NET Frameworkならコレでバッチリ ;)

でも、Compact Frameworkでは…上記ページの最初のアプローチ「現在起動しているプロセスを調べる方法」では、System.Diagnostics.ProcessクラスにGetProcessesByNameメソッドがない :arrow: ついでに言うと、ProcessNameプロパティもない :roll:

仕方ないので、上記ページの次のアプローチ「Mutexを使用する方法」を試す。Mutexを使う方法は以下のページのコードの方が良いと思ったのでコチラを試す(基本は同じですけど…ReleaseMutexとかチャンとしてたので)。

一応、先にCompact Frameworkでクラスやメソッドがあることを確認(習慣になりつつあります) :arrow: 大丈夫みたい。じゃぁ、コンパイル………ありゃエラー :shock: どこで…ぎゃあ~Mutexのコンストラクタに2引数のものがない。

うぐぁ~コンストラクタの引数まで確認してなかったよ :roll:

仕方ないので、ググってみるとみなさん同じようなこと(2引数のコンストラクタがないと)を書いている。結局、P/InvokeでCreateMutexを使えと :cry:

と言うことで、Compact Framework+VB.NET版は以下のページで見つけたけど…C#版がなかったのでコードをペタっと貼っておく。

    using HANDLE = System.IntPtr;
 
    static class Program
    {
        [MTAThread]
        static void Main()
        {
            HANDLE hMutex = CreateMutex(IntPtr.Zero, false, Assembly.GetExecutingAssembly().GetName().Name);
            if (GetLastError() != ERROR_ALREADY_EXISTS)
            {
                Application.Run(new Form1());
            }
            else
            {
                MessageBox.Show("アプリケーションは既に起動しています。");
            }
            ReleaseMutex(hMutex);
            CloseHandle(hMutex);
        }
 
        private const int ERROR_ALREADY_EXISTS = 183;
        [DllImport("coredll.dll", SetLastError = true)]
        private static extern HANDLE CreateMutex(IntPtr lpMutexAttributes, bool bInitiaOwner, string lpName);
        [DllImport("coredll.dll")]
        private static extern int GetLastError();
        [DllImport("coredll.dll")]
        private static extern bool ReleaseMutex(HANDLE hMutex);
        [DllImport("coredll.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool CloseHandle(HANDLE hObject);
    }

適当な部分はよしなに ;)

ReleaseMutexやCloseMutexは引数がIntPtr.Zeroでも問題ないようなので常に呼び出してます。

GotDotNetにCompact Frameworkでの二重起動防止のサンプルが在ったようなので…そちらの方が良い可能性が高いです。でも、見つけられなかったのよね :arrow:

しかし、Microsoftさま…Mutexに2引数(名前付きMutex)のコンストラクタを実装するのは、そんなに大変なのでしょうか :?: それともコレを実装するとCompact Frameworkが肥大化するのでしょうか :?: まぁ、何でも要求に沿って入れていけばCompactじゃなくなるので、取捨選択は重要だと思いますけど…。

小一時間問い詰めたい選択が多すぎです

TrackBack URL :

VS2005でスマートデバイス用MFCアプリが作れない?

世間は、CodeZineなど各所で取り上げられているように『Microsoft、Visual Studio SP1および.NET Framework SP1公開』と言うことでVS2008 SP1と.NET Framework 3.5 SP1がリリースされたと盛り上がってる :?: ところですが…客先の指定でVS2005を使ってます。

まぁ、それは良いのですが…Windows CEでグローバルフックを実装しようとしたのですが、どうも.NETの世界だけでは無理っぽい(P/Invokeを使ってもダメっぽい) :| 仕方ないので、C++で書いてみようと…。

プロジェクト新規作成で、Visual C++のスマートデバイスを選んで…ウィザードが表示され…ないよ :shock: なんか、スクリプトエラーっぽいダイアログがでてるよ。

仕方ないので、デバッグしてみる…VS2005のエラーをVS2005でデバッグするなんて本末転倒っぽいけど仕方ない :arrow: むむ、Common.jsの中でエラーって、どこだよCommon.jsって :|

Google先生に聞いてみた。MSDN Forumsでまったく同じ場所で落ちている人を発見…「error using Smart Device Walkthroughs in VS 2005 Professional : Visual C++ General : Visual C++」。ココから辿って行って、同じくMSDN Forumsで解決方法の書かれたページを発見…「Re: message “project creation failed”」 :idea:

で、その対処方法は以下のようにレジストリを弄れと言うもの。

  1. とりあえずVS2005を終了
  2. レジストリエディタを起動
  3. 以下のレジストリを探し出すこと
    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Ext\PreApproved
  4. 以下のレジストリ名を追加すること
    {D245F352-3F45-4516-B1E6-04608DA126CC}
  5. レジストリエディタを終了
  6. VS2005を起動
  7. VC++のスマートデバイスプロジェクトを作成してみて

はぁ :?: 何のことですかぁ~意味わからないんですけど…と思いながら仕方ないので書かれている通りにレジストリを弄ってみた :roll:

おぉ、ウィザードがちゃんと開いてプロジェクトでけた。

いつ、VS2005がこのような状態に陥ったのかもわからないし、直った理由もまったくわからない。アドインを入れたり、消したりしているから不安定になるのかな :?: 最近、VSの不調に何度か悩まされてます :cry:

その点、Eclipseとかだとレジストリなんて訳のわからないものを使ってないので、プラグインを入れたり外したりして、おかしくなってもフォルダだけ管理しておけば何とかできるのが良いですね ;)

肝心のグローバルフックの実装はこれから…とほほ

TrackBack URL :

P/Invokeをお便利に?

ここのところ、C#でコードを書くことが多くなってきてます。

マネージドコードだけで書ければ、それが一番幸せなのですが…残念ながら、現状では動的ライブラリ(DLL)内のネイティブコードを呼び出さないとどうしょうもない壁に結構ぶちあたります :|

そんな時に使うのが、P/Invoke(Platform Invoke、プラットフォーム呼び出し)なんですが…結構、面倒臭いんですね~コレが。

まぁ、pinvoke.netで調べるのが王道なんですかね :?:

ブラウザでpinvoke.netにアクセスして、検索とかで調べて~コードをコピペするという結構面倒な手間を楽にしてくれるのが…Red Gate Softwareが提供してくれているVisual Studio内から、直接pinvoke.netへアクセスできるようにしてくれるVSアドオンです ;) このアドオンは、メールアドレスなどの登録は必要ですが…試用期限もなくフリーで利用できます。

VSのメニューから以下のようなダイアログを呼び出し、検索して即コードを挿入できるので非常に快適になります。

Invoke Addon

あと、ローカルで動作するPInvoke Interop Assistantというツールもなかなかお薦めです ;)

大きく3つの機能を持っていて、それぞれ以下のような感じで使えます。

Invoke Spy

EXEやDLLを開いて、その中で使われているアンマネージ・シグネチャの一覧が表示できます :!:

Invoke Search

定数やAPIを検索して、P/Invoke用のコードを表示できます :!:

Invoke Code

P/Invokeしたいネイティブコードから、P/Invoke用のコードを表示できます :!:

でも、たまにナイものがあるんですよね~ :cry:

TrackBack URL :