C# Programming

Image

郵便番号−住所 検索 (非同期型)

開発環境: Visual Studio 2003 

1.目次

2.目的

 
注意
これは実験のために、郵政公社を使ってみただけです。
まねて、同じアプリを作らないように!!
手で検索するのと違って、プログラムで連続検索をかけるとサーバ側に相当な負荷をかけることができてしまいます。

.NETで作るんだったら、こんなことはせずに郵便番号のCSVファイルを郵政公社からダウンロードして、
データベースにぶち込む。それをXML Webサービスで公開して、XML Webサービス経由でアクセスするというのが正解。


Web アクセス時の POST データの受け渡し方法を調べていて、適当なテストできるサイトが無いか探していたところ、
郵政公社の郵便番号検索が POST を使っていたので、(7) 郵便番号−住所 検索ツール (同期型)のように、
同期型で作ってみましたが、やっぱり非同期にしないとかっちょ悪いので、非同期版を作ってみました。

非同期は、HTML POST にとりあえずメモったんですが、実際に組んでみないとわからない細かいところがありますね。
例えば、
1.WaitOne で、タイムアウトさせるようにしないと、そこで止まってしまうことがあります。
2.タイムアウトしたときのアボート方法。
3.エラー処理のときに、ストリームをクローズしないと、処理が止まってしまうことがある。

ということで、メモっておきます。

Image

3.参考書

(1) 郵政公社の郵便番号検索のホームページ
(2) MSDN 正規表現言語要素
(3) MSDN RegEx
(4) バリデーションへの応用例
(5) GotDotNet サンプル: ”タスクの例 : POST 要求を作成する”
(6) RegEx 正規表現
(7) 郵便番号−住所 検索ツール (同期型)

4.郵政公社の郵便番号検索へのアクセス

郵政公社の郵便番号検索のホームページがあって、郵便番号を Web で検索できます。
http://www.post.japanpost.jp/zipcode/index.html

そのページは、POST によるHTMLスクリプトで動作しています。
そこで、WebRequest を使って、C# で POST データをプログラムから書き込み、
結果を受け取って、それを表示するようにしています。
注意
本来ならば、XML Web Service でこのような郵便番号検索機能が提供されていれば、何の問題も無いのですが、
HTML でしか検索できません。
検索ページのHTML を調べて、その結果に基づいて処理た処理を行っています。
このため、該当ページが変更されてしまうと、動作しなくなります。

5.POST の非同期の流れ

非同期処理しないと、POST 処理時にフォームの描画が停止してしまいます。
非同期処理の処理は次のような感じです。
(1) 結果をフォームに返す必要があるので、メインフォームのメソッドをコールバックする必要がある。
そのデリゲートを cb で保持しておく。
        public delegate void CallBack(...);

        private CallBack cb;

        public void SetCallBack(CallBack del)
        {
            cb = del;
        }
(2) POST のメインルーチン
        public void POST(string data)
        {
            try
            {
                WebRequest webReq = HttpWebRequest.Create( URL );
                // 1秒でタイムアウトさせる。
                webReq.Timeout = timeout;  // mSec
                // IE のプロキシ設定を使用する。
                webReq.Proxy = System.Net.WebProxy.GetDefaultProxy(); 
                webReq.Method = "POST";
                webReq.ContentType = "application/x-www-form-urlencoded";
                                
                // 非同期要求に対するコールバックを設定します。
                AsyncCallback writeCallBack = new AsyncCallback(this.WriteCallBack); 
                // 非同期で要求します。
                IAsyncResult r = webReq.BeginGetRequestStream(writeCallBack, webReq);

                // 待つ
                if (r.AsyncWaitHandle.WaitOne(timeout, true) == false)
                {
                    webReq.Abort();
                    return;
                }
                ///////////////////////////////////////////////

                // 非同期要求に対するコールバックを設定します。
                AsyncCallback readCallBack = new AsyncCallback(this.Zip2AddressReadCallBack); 
                // 非同期で要求します。
                IAsyncResult rAr = webReq.BeginGetResponse(readCallBack, webReq);
                // 待つ
                if (rAr.AsyncWaitHandle.WaitOne(timeout, true) == false)
                {
                    webReq.Abort();
                    return;
                }
                // 結果をコールバックする
                cb(...);
            }
            catch (Exception exc)
            {
                 ...
            }
        }
(3) POST パラメータ送信用コールバック
        private void WriteCallBack(IAsyncResult ar)
        {
            StreamWriter sw = null;
            try
            {
                HttpWebRequest req = (HttpWebRequest) ar.AsyncState;

                Encoding enc = System.Text.Encoding.GetEncoding("SHIFT-JIS");
                
                sw = new StreamWriter(req.EndGetRequestStream(ar), enc);
                sw.Write(parameters);
            }
            catch (WebException)
            {
                ...
            }
            catch (Exception exc)
            {
                ...
            }
            finally
            {
                if (sw != null)
                    sw.Close();
            }
        }
(4) POST 結果読み込み用コールバック
        private void ReadCallBack(IAsyncResult ar)
        {
            StreamReader sr = null;
            try
            {
                HttpWebRequest req = (HttpWebRequest) ar.AsyncState;
                HttpWebResponse response = (HttpWebResponse) req.EndGetResponse(ar);

                Encoding enc = System.Text.Encoding.GetEncoding("SHIFT-JIS");
                sr = new StreamReader(response.GetResponseStream(), enc);

                string str = null;
                while( true )
                {
                    str = sr.ReadLine();
                    if (str == null)
                        break;
                }            
            }
            catch (WebException)
            {
                ...
            }
            catch (Exception exc)
            {
                ...
            }
            finally
            {
                if (sr != null)
                    sr.Close();
            }
        }

5.未解決問題

Proxy 経由で無い場合はうまく動作しています。
しかし、Proxy 経由で試してみたら、動作しませんでした。

Proxy のところは、次のように IE のプロキシ設定を使用するようにしても、直接プロキシを指定するようにしてもだめでした。
webReq.Proxy = System.Net.WebProxy.GetDefaultProxy(); // IE のプロキシ設定を使用する。

また、http://ja.gotdotnet.com/quickstart/howto/doc/WebRequests/clientPOST.aspx
のサンプルコードにこのようにプロキシの設定をしてもだめでした。

しかし、プロキシ経由ではなくアクセスするとOKなので、ひょっとしてバグ?

6.ダウンロード

提供していません。

7.ソースコード

変更履歴
2003/6/2   非同期バージョン V1.1 ZipCodeForm.cs, ZipCodeUtil.cs, About.cs
      
      
ZipCodeForm.cs
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Net;
using System.IO;
using System.Text.RegularExpressions;
using Uchukamen.Util.ZipCodeJapan;
using System.Configuration;

namespace ZipCode
{
    /// <summary>
    /// Form1 の概要の説明です。
    /// </summary>
    public class Form1 : System.Windows.Forms.Form
    {
        private System.Windows.Forms.TextBox tbZipCode;
        private System.Windows.Forms.TextBox tbCity;
        private System.Windows.Forms.TextBox tbTown;
        private System.Windows.Forms.ComboBox cbKen;
        private System.Windows.Forms.ListBox listBox1;
        private System.Windows.Forms.GroupBox groupBox1;
        private System.Windows.Forms.GroupBox groupBox2;
        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.Label label2;
        private System.Windows.Forms.Label label3;
        private System.Windows.Forms.ToolTip toolTip1;
        private System.Windows.Forms.Label label4;
        private System.Windows.Forms.Button btnClear;
        private System.Windows.Forms.ErrorProvider errorProvider1;
        private System.Windows.Forms.MainMenu mainMenu1;
        private System.Windows.Forms.MenuItem menuItem1;
        private System.Windows.Forms.MenuItem menuItem2;
        private System.Windows.Forms.ContextMenu contextMenu1;
        private System.Windows.Forms.MenuItem menuItem3;
        private System.Windows.Forms.StatusBar statusBar1;
        private System.Windows.Forms.StatusBarPanel statusBarPanel1;
        private System.Windows.Forms.Button btnSearchByZip;
        private System.Windows.Forms.Button btnSearchByAddress;
        private System.ComponentModel.IContainer components;

        public Form1()
        {
            //
            // Windows フォーム デザイナ サポートに必要です。
            //
            InitializeComponent();

            //
            // TODO: InitializeComponent 呼び出しの後に、コンストラクタ コードを追加してください。
            //
        }

        /// <summary>
        /// 使用されているリソースに後処理を実行します。
        /// </summary>
        protected override void Dispose( bool disposing )
        {
            if( disposing )
            {
                if (components != null) 
                {
                    components.Dispose();
                }
            }
            base.Dispose( disposing );
        }

                #region Windows Form Designer generated code
        /// <summary>
        /// デザイナ サポートに必要なメソッドです。このメソッドの内容を
        /// コード エディタで変更しないでください。
        /// </summary>
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            this.btnSearchByZip = new System.Windows.Forms.Button();
            this.tbZipCode = new System.Windows.Forms.TextBox();
            this.tbCity = new System.Windows.Forms.TextBox();
            this.tbTown = new System.Windows.Forms.TextBox();
            this.cbKen = new System.Windows.Forms.ComboBox();
            this.listBox1 = new System.Windows.Forms.ListBox();
            this.contextMenu1 = new System.Windows.Forms.ContextMenu();
            this.menuItem3 = new System.Windows.Forms.MenuItem();
            this.groupBox1 = new System.Windows.Forms.GroupBox();
            this.label4 = new System.Windows.Forms.Label();
            this.groupBox2 = new System.Windows.Forms.GroupBox();
            this.btnSearchByAddress = new System.Windows.Forms.Button();
            this.btnClear = new System.Windows.Forms.Button();
            this.label3 = new System.Windows.Forms.Label();
            this.label2 = new System.Windows.Forms.Label();
            this.label1 = new System.Windows.Forms.Label();
            this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
            this.errorProvider1 = new System.Windows.Forms.ErrorProvider();
            this.mainMenu1 = new System.Windows.Forms.MainMenu();
            this.menuItem1 = new System.Windows.Forms.MenuItem();
            this.menuItem2 = new System.Windows.Forms.MenuItem();
            this.statusBar1 = new System.Windows.Forms.StatusBar();
            this.statusBarPanel1 = new System.Windows.Forms.StatusBarPanel();
            this.groupBox1.SuspendLayout();
            this.groupBox2.SuspendLayout();
            ((System.ComponentModel.ISupportInitialize)(this.statusBarPanel1)).BeginInit();
            this.SuspendLayout();
            // 
            // btnSearchByZip
            // 
            this.btnSearchByZip.Anchor = (System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right);
            this.btnSearchByZip.Location = new System.Drawing.Point(296, 24);
            this.btnSearchByZip.Name = "btnSearchByZip";
            this.btnSearchByZip.Size = new System.Drawing.Size(48, 23);
            this.btnSearchByZip.TabIndex = 2;
            this.btnSearchByZip.Text = "検索";
            this.toolTip1.SetToolTip(this.btnSearchByZip, "郵便番号より検索");
            this.btnSearchByZip.Click += new System.EventHandler(this.btnSearchByZip_Click);
            // 
            // tbZipCode
            // 
            this.tbZipCode.Anchor = ((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
                | System.Windows.Forms.AnchorStyles.Right);
            this.tbZipCode.Location = new System.Drawing.Point(104, 24);
            this.tbZipCode.Name = "tbZipCode";
            this.tbZipCode.Size = new System.Drawing.Size(56, 19);
            this.tbZipCode.TabIndex = 1;
            this.tbZipCode.Text = "";
            this.toolTip1.SetToolTip(this.tbZipCode, "例:123-4567");
            this.tbZipCode.Validating += new System.ComponentModel.CancelEventHandler(this.tbZipCode_Validating);
            // 
            // tbCity
            // 
            this.tbCity.Anchor = ((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
                | System.Windows.Forms.AnchorStyles.Right);
            this.tbCity.ImeMode = System.Windows.Forms.ImeMode.Katakana;
            this.tbCity.Location = new System.Drawing.Point(104, 56);
            this.tbCity.Name = "tbCity";
            this.tbCity.Size = new System.Drawing.Size(160, 19);
            this.tbCity.TabIndex = 4;
            this.tbCity.Text = "";
            this.toolTip1.SetToolTip(this.tbCity, "カタカナで入力");
            this.tbCity.Validating += new System.ComponentModel.CancelEventHandler(this.tbCity_Validating);
            // 
            // tbTown
            // 
            this.tbTown.Anchor = ((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
                | System.Windows.Forms.AnchorStyles.Right);
            this.tbTown.ImeMode = System.Windows.Forms.ImeMode.Katakana;
            this.tbTown.Location = new System.Drawing.Point(104, 88);
            this.tbTown.Name = "tbTown";
            this.tbTown.Size = new System.Drawing.Size(160, 19);
            this.tbTown.TabIndex = 7;
            this.tbTown.Text = "";
            this.toolTip1.SetToolTip(this.tbTown, "カタカナで入力");
            this.tbTown.Validating += new System.ComponentModel.CancelEventHandler(this.tbTown_Validating);
            // 
            // cbKen
            // 
            this.cbKen.Anchor = ((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
                | System.Windows.Forms.AnchorStyles.Right);
            this.cbKen.Items.AddRange(new object[] {
                                                       "全国",
                                                       "北海道",
                                                       "青森県",
                                                       "岩手県",
                                                       "宮城県",
                                                       "秋田県",
                                                       "山形県",
                                                       "福島県",
                                                       "茨城県",
                                                       "栃木県",
                                                       "群馬県",
                                                       "埼玉県",
                                                       "千葉県",
                                                       "東京都",
                                                       "神奈川県",
                                                       "新潟県",
                                                       "富山県",
                                                       "石川県",
                                                       "福井県",
                                                       "山梨県",
                                                       "長野県",
                                                       "岐阜県",
                                                       "静岡県",
                                                       "愛知県",
                                                       "三重県",
                                                       "滋賀県",
                                                       "京都府",
                                                       "大阪府",
                                                       "兵庫県",
                                                       "奈良県",
                                                       "和歌山県",
                                                       "鳥取県",
                                                       "島根県",
                                                       "岡山県",
                                                       "広島県",
                                                       "山口県",
                                                       "徳島県",
                                                       "香川県",
                                                       "愛媛県",
                                                       "高知県",
                                                       "福岡県",
                                                       "佐賀県",
                                                       "長崎県",
                                                       "熊本県",
                                                       "大分県",
                                                       "宮崎県",
                                                       "鹿児島県",
                                                       "沖縄県"});
            this.cbKen.Location = new System.Drawing.Point(104, 24);
            this.cbKen.MaxDropDownItems = 20;
            this.cbKen.Name = "cbKen";
            this.cbKen.Size = new System.Drawing.Size(88, 20);
            this.cbKen.TabIndex = 1;
            this.cbKen.Text = "全国";
            this.toolTip1.SetToolTip(this.cbKen, "都道府県名を選択");
            // 
            // listBox1
            // 
            this.listBox1.Anchor = (((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
                | System.Windows.Forms.AnchorStyles.Left) 
                | System.Windows.Forms.AnchorStyles.Right);
            this.listBox1.ContextMenu = this.contextMenu1;
            this.listBox1.ItemHeight = 12;
            this.listBox1.Location = new System.Drawing.Point(8, 208);
            this.listBox1.Name = "listBox1";
            this.listBox1.Size = new System.Drawing.Size(368, 184);
            this.listBox1.TabIndex = 3;
            this.listBox1.SelectedIndexChanged += new System.EventHandler(this.listBox1_SelectedIndexChanged);
            // 
            // contextMenu1
            // 
            this.contextMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
                                                                                         this.menuItem3});
            // 
            // menuItem3
            // 
            this.menuItem3.Index = 0;
            this.menuItem3.Shortcut = System.Windows.Forms.Shortcut.CtrlC;
            this.menuItem3.Text = "コピー(&C)";
            this.menuItem3.Click += new System.EventHandler(this.menuItem3_Click);
            // 
            // groupBox1
            // 
            this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
                | System.Windows.Forms.AnchorStyles.Right);
            this.groupBox1.Controls.AddRange(new System.Windows.Forms.Control[] {
                                                                                    this.tbZipCode,
                                                                                    this.btnSearchByZip,
                                                                                    this.label4});
            this.groupBox1.Location = new System.Drawing.Point(8, 8);
            this.groupBox1.Name = "groupBox1";
            this.groupBox1.Size = new System.Drawing.Size(368, 56);
            this.groupBox1.TabIndex = 1;
            this.groupBox1.TabStop = false;
            this.groupBox1.Text = "郵便番号より検索";
            // 
            // label4
            // 
            this.label4.Location = new System.Drawing.Point(16, 24);
            this.label4.Name = "label4";
            this.label4.Size = new System.Drawing.Size(56, 16);
            this.label4.TabIndex = 0;
            this.label4.Text = "郵便番号";
            // 
            // groupBox2
            // 
            this.groupBox2.Anchor = ((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
                | System.Windows.Forms.AnchorStyles.Right);
            this.groupBox2.Controls.AddRange(new System.Windows.Forms.Control[] {
                                                                                    this.btnSearchByAddress,
                                                                                    this.btnClear,
                                                                                    this.label3,
                                                                                    this.label2,
                                                                                    this.label1,
                                                                                    this.tbCity,
                                                                                    this.cbKen,
                                                                                    this.tbTown});
            this.groupBox2.Location = new System.Drawing.Point(8, 80);
            this.groupBox2.Name = "groupBox2";
            this.groupBox2.Size = new System.Drawing.Size(368, 120);
            this.groupBox2.TabIndex = 2;
            this.groupBox2.TabStop = false;
            this.groupBox2.Text = "住所の読みがなより検索";
            // 
            // btnSearchByAddress
            // 
            this.btnSearchByAddress.Anchor = ((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
                | System.Windows.Forms.AnchorStyles.Right);
            this.btnSearchByAddress.Location = new System.Drawing.Point(296, 24);
            this.btnSearchByAddress.Name = "btnSearchByAddress";
            this.btnSearchByAddress.Size = new System.Drawing.Size(48, 23);
            this.btnSearchByAddress.TabIndex = 0;
            this.btnSearchByAddress.Text = "検索";
            this.toolTip1.SetToolTip(this.btnSearchByAddress, "市町村名より検索");
            this.btnSearchByAddress.Click += new System.EventHandler(this.btnSearchByAddress_Click);
            // 
            // btnClear
            // 
            this.btnClear.Anchor = (System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right);
            this.btnClear.Location = new System.Drawing.Point(296, 56);
            this.btnClear.Name = "btnClear";
            this.btnClear.Size = new System.Drawing.Size(48, 23);
            this.btnClear.TabIndex = 5;
            this.btnClear.Text = "クリア";
            this.toolTip1.SetToolTip(this.btnClear, "市町村名、町域名をクリアします。");
            this.btnClear.Click += new System.EventHandler(this.btnClear_Click);
            // 
            // label3
            // 
            this.label3.Location = new System.Drawing.Point(8, 88);
            this.label3.Name = "label3";
            this.label3.Size = new System.Drawing.Size(80, 16);
            this.label3.TabIndex = 6;
            this.label3.Text = "町域名(カナ)";
            // 
            // label2
            // 
            this.label2.Location = new System.Drawing.Point(8, 56);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(88, 16);
            this.label2.TabIndex = 3;
            this.label2.Text = "市町村名(カナ)";
            // 
            // label1
            // 
            this.label1.Location = new System.Drawing.Point(16, 24);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(56, 16);
            this.label1.TabIndex = 0;
            this.label1.Text = "都道府県";
            // 
            // toolTip1
            // 
            this.toolTip1.AutomaticDelay = 100;
            // 
            // mainMenu1
            // 
            this.mainMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
                                                                                      this.menuItem1});
            // 
            // menuItem1
            // 
            this.menuItem1.Index = 0;
            this.menuItem1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
                                                                                      this.menuItem2});
            this.menuItem1.Text = "ヘルプ(&H)";
            // 
            // menuItem2
            // 
            this.menuItem2.Index = 0;
            this.menuItem2.Text = "バージョン情報(&A)";
            this.menuItem2.Click += new System.EventHandler(this.menuItem2_Click);
            // 
            // statusBar1
            // 
            this.statusBar1.Location = new System.Drawing.Point(0, 395);
            this.statusBar1.Name = "statusBar1";
            this.statusBar1.Panels.AddRange(new System.Windows.Forms.StatusBarPanel[] {
                                                                                          this.statusBarPanel1});
            this.statusBar1.ShowPanels = true;
            this.statusBar1.Size = new System.Drawing.Size(384, 22);
            this.statusBar1.TabIndex = 0;
            // 
            // statusBarPanel1
            // 
            this.statusBarPanel1.AutoSize = System.Windows.Forms.StatusBarPanelAutoSize.Spring;
            this.statusBarPanel1.ToolTipText = "Status";
            this.statusBarPanel1.Width = 368;
            // 
            // Form1
            // 
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 12);
            this.ClientSize = new System.Drawing.Size(384, 417);
            this.Controls.AddRange(new System.Windows.Forms.Control[] {
                                                                          this.statusBar1,
                                                                          this.listBox1,
                                                                          this.groupBox1,
                                                                          this.groupBox2});
            this.Menu = this.mainMenu1;
            this.MinimumSize = new System.Drawing.Size(392, 448);
            this.Name = "Form1";
            this.Text = "Product Name";
            this.Load += new System.EventHandler(this.Form1_Load);
            this.groupBox1.ResumeLayout(false);
            this.groupBox2.ResumeLayout(false);
            ((System.ComponentModel.ISupportInitialize)(this.statusBarPanel1)).EndInit();
            this.ResumeLayout(false);

        }
                #endregion

        /// <summary>
        /// アプリケーションのメイン エントリ ポイントです。
        /// </summary>
        [STAThread]
        static void Main() 
        {
            Application.Run(new Form1());
        }

        /// <summary>
        /// 検索結果を格納する。
        /// </summary>
        private ArrayList zipList = new ArrayList();

        /// <summary>
        /// 検索クラスのインスタンス
        /// </summary>
        private ZipCodeSearcher zipCodeSearcher = null;

        /// <summary>
        /// フォームの初期化
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_Load(object sender, System.EventArgs e)
        {
            this.Text = Application.ProductName;
            this.Icon = new Icon(GetType(), "App.ico"); 
            toolTip1.SetToolTip(this.tbCity, "例:チヨダク、ケセンヌマシ、シラハマチョウなど");
            toolTip1.SetToolTip(this.tbTown, "検索のヒント:町・村を省いたよみがな");
            string defaultKen = ConfigurationSettings.AppSettings["ZipCode.DefaultKen"];
            this.cbKen.Text = defaultKen;

            zipCodeSearcher =
                new Uchukamen.Util.ZipCodeJapan.ZipCodeSearcher();

            // 結果を受け取るコールバック CallBack のデリゲートを作る。
            ZipCodeSearcher.CallBack myCallBack = new ZipCodeSearcher.CallBack(CallBack);   
        
            // 結果を受け取るコールバック CallBack をzipCodeSearcherにセットする。
            zipCodeSearcher.SetCallBack(myCallBack);
        }

        # region 検索関連メソッド
        /// <summary>
        /// 検索結果を受け取るコールバック
        /// </summary>
        /// <param name="zipList"></param>
        public void CallBack(ArrayList zipList, string status)
        {

            if (zipList != null)
            {
                this.zipList = zipList;
                this.listBox1.BeginUpdate();
                this.listBox1.Items.Clear();
                this.statusBarPanel1.Text = zipList.Count.ToString() + " 件見つかりました";
                foreach(Uchukamen.Util.ZipCodeJapan.ZipCode zip in zipList)
                {
                    this.listBox1.Items.Add(zip.Code+ "\t" + zip.Ken+zip.City+zip.Town);
                }
                this.listBox1.EndUpdate();
            } 
            else
            {
                // 何らかのエラー
                this.statusBarPanel1.Text = status;
                MessageBox.Show(status, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            // カーソルを元に戻す。
            this.Cursor = Cursors.Arrow;
            this.btnSearchByZip.Enabled = true;
            this.btnSearchByAddress.Enabled = true;
        }

        private void btnSearchByZip_Click(object sender, System.EventArgs e)
        {
            try
            {
                // カーソルを WaitCursor にする。
                this.Cursor = Cursors.WaitCursor;
                this.btnSearchByZip.Enabled = false;
                this.errorProvider1.SetError(this.tbZipCode, "");
                zipCodeSearcher.GetAddressFromZipCode(this.tbZipCode.Text);
            }
            catch (Exception exc)
            {
                this.statusBarPanel1.Text = exc.Message;
            }
            finally
            {
                this.Cursor = Cursors.Arrow;
                this.btnSearchByZip.Enabled = true;
            }
        }

        private void btnSearchByAddress_Click(object sender, System.EventArgs e)
        {
            try
            {
                // カーソルを WaitCursor にする。
                this.Cursor = Cursors.WaitCursor;
                this.btnSearchByAddress.Enabled = false;
                this.errorProvider1.SetError(this.tbZipCode, "");
                zipCodeSearcher.GetZipCodeFromAddress(this.cbKen.Text, this.tbCity.Text, this.tbTown.Text);
            }
            catch (Exception exc)
            {
                this.statusBarPanel1.Text = exc.Message;
            }
            finally
            {
                this.Cursor = Cursors.Arrow;
                this.btnSearchByZip.Enabled = true;
            }
        }
        #endregion

        #region メニュー
        private void menuItem2_Click(object sender, System.EventArgs e)
        {
            Form about = new Uchukamen.Util.AboutZipCodeSearcher.About();
            about.ShowDialog();
        }

        private void menuItem3_Click(object sender, System.EventArgs e)
        {
            Clipboard.SetDataObject(this.listBox1.SelectedItem.ToString());
        }
        #endregion

        # region 入力審査
        private void tbZipCode_Validating(object sender, System.ComponentModel.CancelEventArgs e)
        {
            // 郵便番号のみの文字列
            Regex regex = new System.Text.RegularExpressions.Regex("^[0-9]{0,3}$|^[0-9]{1,3}-[0-9]{0,4}$|^[0-9]{1,7}$");
            if ( ! regex.IsMatch( ((TextBox)sender).Text )) 
            {
                this.errorProvider1.SetError( (TextBox)sender, "例:123-4567" );
                e.Cancel = true;
            }
            else
                this.errorProvider1.SetError( (TextBox)sender, "" );
        }

        private void tbCity_Validating(object sender, System.ComponentModel.CancelEventArgs e)
        {
            // カタカナのみの文字列
            Regex regex = new System.Text.RegularExpressions.Regex("^[あ-んー0-9]*$|^[ア-ンー0-9]*$");

            if ( ! regex.IsMatch( ((TextBox)sender).Text )) 
            {
                this.errorProvider1.SetError( (TextBox)sender, "ひらがな、またはカタカナで入力してください。" );
                e.Cancel = true;
            }
            else
                this.errorProvider1.SetError( (TextBox)sender, "" );
        }

        private void tbTown_Validating(object sender, System.ComponentModel.CancelEventArgs e)
        {
            // カタカナのみの文字列
            Regex regex = new System.Text.RegularExpressions.Regex("^[あ-んー0-9]*$|^[ア-ンー0-9]*$");

            if ( ! regex.IsMatch( ((TextBox)sender).Text )) 
            {
                this.errorProvider1.SetError( (TextBox)sender, "ひらがな、またはカタカナで入力してください。" ); 
                e.Cancel = true;
            }
            else
                this.errorProvider1.SetError( (TextBox)sender, "" );        
        }
        #endregion

        #region その他メソッド
        private void listBox1_SelectedIndexChanged(object sender, System.EventArgs e)
        {
            int i = this.listBox1.SelectedIndex;
            this.cbKen.Text = ((Uchukamen.Util.ZipCodeJapan.ZipCode)zipList[i]).Ken;
            this.tbZipCode.Text = ((Uchukamen.Util.ZipCodeJapan.ZipCode)zipList[i]).Code;
            this.tbCity.Text = ((Uchukamen.Util.ZipCodeJapan.ZipCode)zipList[i]).CityKana;
            this.tbTown.Text = ((Uchukamen.Util.ZipCodeJapan.ZipCode)zipList[i]).TownKana;
        }

        private void btnClear_Click(object sender, System.EventArgs e)
        {        
            this.cbKen.Text = "全国";
            this.tbZipCode.Text = "";
            this.tbCity.Text = "";
            this.tbTown.Text = "";
        }
        #endregion
    }
}
ZipCodeUtil.cs
using System;
using System.Collections;
using System.Text.RegularExpressions;
using System.Text;
using System.IO;
using System.Net;
using System.Web;
using System.Diagnostics;
using ZipCode;
using System.Threading;

namespace Uchukamen.Util.ZipCodeJapan
{    
    #region MultipleKenException
    /// <summary>
    /// 複数の県が該当する場合の例外クラス
    /// KenList に県のリストをセットする
    /// </summary>
    public class MultipleKenException: Exception
    {
        private ArrayList kenList = new ArrayList();

        public MultipleKenException(string message) : base(message)
        {
        }

        public void Add(string ken)
        {
            kenList.Add(ken);
        }
        
        public ArrayList KenList
        {
            get 
            {
                return kenList; 
            }
        }
    }
    #endregion

    # region ZipCodeクラス
    /// <summary>
    /// 郵便番号クラス
    /// </summary>
    public class ZipCode
    {
        public ZipCode()
        {
        }

        private string code     = "";
        private string ken      = "";
        private string kenKana  = "";
        private string city     = "";
        private string cityKana = "";
        private string town     = "";
        private string townKana = "";

        public string Code
        {
            get 
            {
                return code; 
            }
            set 
            {
                code = value; 
            }
        }

        public string Ken
        {
            get 
            {
                return ken; 
            }
            set 
            {
                ken = value; 
            }
        }

        public string KenKana
        {
            get 
            {
                return kenKana; 
            }
            set 
            {
                kenKana = value; 
            }
        }

        public string City
        {
            get 
            {
                return city; 
            }
            set 
            {
                city = value; 
            }
        }

        public string CityKana
        {
            get 
            {
                return cityKana; 
            }
            set 
            {
                cityKana = value; 
            }
        }

        public string Town
        {
            get 
            {
                return town; 
            }
            set 
            {
                town = value; 
            }
        }

        public string TownKana
        {
            get 
            {
                return townKana; 
            }
            set 
            {
                townKana = value; 
            }
        }

        /// <summary>
        /// 郵便番号で検索した場合のHTMLからセットする。
        /// "<TR><TD> 210-0854<BR>(210  )</TD><TD>カナガワケン<BR>神奈川県</TD>
        /// <TD>カワサキシカワサキク<BR>川崎市川崎区</TD><TD>アサノチョウ<BR>浅野町"
        /// </summary>
        /// <param name="col"></param>
        public void Set1(MatchCollection col)
        {
            // 郵便番号
            if (col.Count > 0) this.Code = col[0].Value;
            // 都道府県名(かな)
            if (col.Count > 1) this.KenKana = col[1].Value;
            // 都道府県名
            if (col.Count > 2) this.Ken = col[2].Value;
            // 市町村名(かな)
            if (col.Count > 3) this.CityKana = col[3].Value;
            // 市町村名
            if (col.Count > 4) this.City = col[4].Value;
            // 町域名(かな)
            if (col.Count > 5) this.TownKana = col[5].Value;
            // 町域名
            if (col.Count > 6) this.Town = col[6].Value;
        }

        /// <summary>
        /// 住所のよみがなで検索した場合のHTMLからセットする。
        /// <TR><TD>210-0854</TD><TD>神奈川県<BR>
        /// <TD>カワサキシカワサキク<BR>川崎市川崎区</TD><TD>アサノチョウ<BR>浅野町</TD></TR>
        /// </summary>
        /// <param name="col"></param>
        public void Set2(MatchCollection col)
        {
            // 郵便番号
            if (col.Count > 0) this.Code = col[0].Value;
            // 都道府県名
            if (col.Count > 1) this.Ken = col[1].Value;
            // 市町村名(かな)
            if (col.Count > 2) this.CityKana = col[2].Value;
            // 市町村名
            if (col.Count > 3) this.City = col[3].Value;
            // 町域名(かな)
            if (col.Count > 4) this.TownKana = col[4].Value;
            // 町域名
            if (col.Count > 5) this.Town = col[5].Value;
        }
    }
    #endregion

    /// <summary>
    /// 郵政公社のホームページから、郵便番号・住所を Web 経由で取得する。
    /// 注意: 2003/5/11 時点での検索ページの構成に依存しています。
    ///         このページの構成が変更になると動作しなくなります。
    /// 郵政公社のホームページ http://www.japanpost.jp/
    /// 郵政公社の郵便番号検索ページ http://www.post.japanpost.jp/zipcode/
    /// </summary>
    public class ZipCodeSearcher
    {
        public ZipCodeSearcher()
        {
        }

        #region メンバ変数、プロパティ
        // 郵便番号→住所のためのURL
        private const string Zip2AddressURL = "http://search.post.japanpost.jp/7zip/zip.cgi";
        // 住所→郵便番号のためのURL(かな検索)
        private const string Address2ZipURL = "http://search.post.japanpost.jp/7zip/kana.cgi";
        // コールバックへ ZipCode を引き渡すためのメンバー変数
        private string parameters = null;

        private string status = "";
        public string Status
        {
            get 
            {
                return status; 
            }
            set 
            {
                status = value; 
            }
        }
        
        /// <summary>
        /// タイムアウト。デフォルトで1秒。
        /// </summary>
        private int timeout = 1000; // mSec
        public int Timeout
        {
            get 
            {
                return timeout; 
            }
            set 
            {
                timeout = value; 
            }
        }
        #endregion

        # region コールバック
        /// <summary>
        /// 検索結果を返すためのコールバック
        /// 結果は、引数(ArrayList)として返す。
        /// </summary>
        public delegate void CallBack(ArrayList arrayList, string status);

        /// <summary>
        /// コールバックメンバー変数
        /// </summary>
        private CallBack cb;

        /// <summary>
        /// コールバックをセットするメソッド
        /// </summary>
        /// <param name="del"></param>
        public void SetCallBack(CallBack del)
        {
            cb = del;
        }
        #endregion

        #region 郵便番号→住所、住所→郵便番号 共通メソッド
        /// <summary>
        /// 郵便番号→住所、住所→郵便番号 共通POST パラメータ送信用コールバック
        /// </summary>
        /// <param name="ar"></param>
        private void WriteCallBack(IAsyncResult ar)
        {
            StreamWriter sw = null;
            try
            {
                Debug.WriteLine("Start WriteCallBack");

                HttpWebRequest req = (HttpWebRequest) ar.AsyncState;

                Encoding enc = System.Text.Encoding.GetEncoding("SHIFT-JIS");
                
                sw = new StreamWriter(req.EndGetRequestStream(ar), enc);
                sw.Write(parameters);
            
                Debug.WriteLine("End WriteCallBack");
            }
            catch (WebException)
            {
                cb(null, "通信に失敗しました。");
            }
            catch (Exception exc)
            {
                cb(null, exc.Message);
            }
            finally
            {
                if (sw != null)
                    sw.Close();
            }
        }

        /// <summary>
        /// 県名から県のコードを返す。
        /// </summary>
        /// <param name="ken">県名</param>
        /// <returns>県コード</returns>
        private string GetKenCode(string ken)
        {
            switch (ken)
            {
                case "全国":        return "00";
                case "北海道":      return "01";
                case "青森県":      return "02";
                case "岩手県":      return "03";
                case "宮城県":      return "04";
                case "秋田県":      return "05";
                case "山形県":      return "06";
                case "福島県":      return "07";
                case "茨城県":      return "08";
                case "栃木県":      return "09";
                case "群馬県":      return "10";
                case "埼玉県":      return "11";
                case "千葉県":      return "12";
                case "東京都":      return "13";
                case "神奈川県":    return "14";
                case "新潟県":      return "15";
                case "富山県":      return "16";
                case "石川県":      return "17";
                case "福井県":      return "18";
                case "山梨県":      return "19";
                case "長野県":      return "20";
                case "岐阜県":      return "21";
                case "静岡県":      return "22";
                case "愛知県":      return "23";
                case "三重県":      return "24";
                case "滋賀県":      return "25";
                case "京都府":      return "26";
                case "大阪府":      return "27";
                case "兵庫県":      return "28";
                case "奈良県":      return "29";
                case "和歌山県":    return "30";
                case "鳥取県":      return "31";
                case "島根県":      return "32";
                case "岡山県":      return "33";
                case "広島県":      return "34";
                case "山口県":      return "35";
                case "徳島県":      return "36";
                case "香川県":      return "37";
                case "愛媛県":      return "38";
                case "高知県":      return "39";
                case "福岡県":      return "40";
                case "佐賀県":      return "41";
                case "長崎県":      return "42";
                case "熊本県":      return "43";
                case "大分県":      return "44";
                case "宮崎県":      return "45";
                case "鹿児島県":    return "46";
                case "沖縄県":      return "47";
                default:            return "00";
            }
        }
        #endregion

        #region 郵便番号→住所検索関連メソッド
        /// <summary>
        /// 郵便番号→住所検索用 POST パラメータ構築用メソッド
        /// </summary>
        /// <param name="zipCode"></param>
        private void SetParameters(string zipCode)
        {
            // 正確なパラメータを渡すために HttpUtility.UrlEncode()でエンコードする。
            parameters = "mode=search&start=0&end=400&keyword=";
            parameters += HttpUtility.UrlEncode(zipCode);
            parameters += "&new=on";
        }

        /// <summary>
        /// 郵便番号→住所検索専用リードコールバック
        /// </summary>
        /// <param name="ar"></param>
        private void Zip2AddressReadCallBack(IAsyncResult ar)
        {
            StreamReader sr = null;
            try
            {
                Debug.WriteLine("Start Zip2AddressReadCallBack");

                ArrayList array = new System.Collections.ArrayList();

                HttpWebRequest req = (HttpWebRequest) ar.AsyncState;
                HttpWebResponse response = (HttpWebResponse) req.EndGetResponse(ar);

                Encoding enc = System.Text.Encoding.GetEncoding("SHIFT-JIS");
                sr = new StreamReader(response.GetResponseStream(), enc);

                // チェック用正規表現
                Regex regShort = new Regex("(番号が短すぎます)|(新番号の場合は5桁以上入れてください)");
                Regex regHit = new Regex(@"(?<=該当数 \[ )[0-9]+");
                Regex regInfo = new Regex(@"(?<=^<TR><TD> )[0-9]{3}-[0-9]{4}|(?<=<TD>)\w+|(?<=<BR>)\w+");
                
                string str = null;
                while( true )
                {
                    str = sr.ReadLine();
                    if (str == null)
                        break;

                    // 番号が短すぎかどうかチェックする。

                    Match matchShort = regShort.Match(str);
                    if (matchShort.Success) 
                    {
                        Debug.WriteLine(matchShort.Value);
                        throw(new Exception(matchShort.Value));
                    }

                    // 検索を成功し、該当数が返されたかチェックする。
                    Match match = regHit.Match(str);
                    if (match.Success) 
                    {
                        Debug.WriteLine("該当数" + match.Value);
                        continue;
                    }
                
                    // 結果から、正規表現を使って住所を切り出す。
                    MatchCollection matchCol = regInfo.Matches(str);
                    if (matchCol.Count > 3)
                    {
                        ZipCode zipCode = new ZipCode();
                        zipCode.Set1(matchCol);
                        array.Add(zipCode);
                        // デバッグ用 
                        Debug.WriteLine(str);
                        for(int i = 0; i < matchCol.Count; i++)
                        {
                            Debug.WriteLine(matchCol[i].Value);
                        }                
                    }
            
                    Debug.WriteLine("End Zip2AddressReadCallBack");
                }            
                cb(array, "");
            }
            catch (WebException)
            {
                cb(null, "通信に失敗しました。");
            }
            catch (Exception exc)
            {
                cb(null, exc.Message);
            }
            finally
            {
                if (sr != null)
                    sr.Close();
            }
        }
        
        /// <summary>
        /// 郵便番号検より住所を索するメソッド
        /// </summary>
        /// <param name="zCode">郵便番号の文字列</param>
        /// <returns>ArrayList of ZipCode Class</returns>
        public void GetAddressFromZipCode(string zCode)
        {
            try
            {
                Debug.WriteLine("Start GetAddressFromZipCode");
                this.SetParameters(zCode);
                WebRequest webReq = HttpWebRequest.Create( Zip2AddressURL );
                // 5秒でタイムアウトさせる。
                webReq.Timeout = timeout;  // mSec
                // IE のプロキシ設定を使用する。
                webReq.Proxy = System.Net.WebProxy.GetDefaultProxy(); 
                webReq.Method = "POST";
                webReq.ContentType = "application/x-www-form-urlencoded";
                                
                // 非同期要求に対するコールバックを設定します。
                AsyncCallback writeCallBack = new AsyncCallback(this.WriteCallBack); 
                // 非同期で要求します。
                IAsyncResult r = webReq.BeginGetRequestStream(writeCallBack, webReq);

                // 待つ
                if (r.AsyncWaitHandle.WaitOne(timeout, true) == false)
                {
                    webReq.Abort();
                    return;
                }
                ///////////////////////////////////////////////

                // 非同期要求に対するコールバックを設定します。
                AsyncCallback readCallBack = new AsyncCallback(this.Zip2AddressReadCallBack); 
                // 非同期で要求します。
                IAsyncResult rAr = webReq.BeginGetResponse(readCallBack, webReq);
                // 待つ場合
                if (rAr.AsyncWaitHandle.WaitOne(timeout, true) == false)
                {
                    webReq.Abort();
                    return;
                }
                Debug.WriteLine("End GetAddressFromZipCode");
            }
            catch (Exception exc)
            {
                cb(null, exc.Message);
            }
        }
        # endregion
        
        # region 住所→郵便番号検索関連メソッド
        /// <summary>
        /// 住所→郵便番号検索用 POST パラメータ構築用メソッド
        /// </summary>
        /// <param name="zipCode"></param>
        private void SetParameters(string ken, string city, string town)
        {
            // 正確なパラメータを渡すために HttpUtility.UrlEncode()でエンコードする。
            parameters = "enctype=text/plain&ken=";                
            parameters += GetKenCode(ken);
            parameters += "&city=";
            parameters += HttpUtility.UrlEncode(city, Encoding.GetEncoding("SHIFT-JIS"));
            parameters += "&town=";
            parameters += HttpUtility.UrlEncode(town, Encoding.GetEncoding("SHIFT-JIS"));
        }
        
        private void Address2ZipReadCallBack(IAsyncResult ar)
        {
            StreamReader sr = null;
            try
            {
                Debug.WriteLine("Start Address2ZipReadCallBack");

                ArrayList array = new System.Collections.ArrayList();

                HttpWebRequest req = (HttpWebRequest) ar.AsyncState;
                HttpWebResponse response = (HttpWebResponse) req.EndGetResponse(ar);

                Encoding enc = System.Text.Encoding.GetEncoding("SHIFT-JIS");
                sr = new StreamReader(response.GetResponseStream(), enc);

                // チェック用正規表現
                Regex regMultiKen = new Regex("(該当する都道府県が複数あります。)");
                Regex regShort = new Regex("(市区町村名が短がすぎます)|(市区町村名が特定できませんでした。条件をみなおしてみてください)");
                Regex regOp = new Regex("(?<=^<OPTION value=\"[0-9]{2}\">)\\w+$");
                Regex regHit = new Regex(@"(?<=該当数 \[ )[0-9]+");
                Regex regInfo = new Regex(@"(?<=^<TR><TD>)[0-9]{3}-[0-9]{4}|(?<=<TD>)\w+|(?<=<BR>)\w+");

                string str = null;
                while( true )
                {
                    str = sr.ReadLine();
                    if (str == null)
                        break;                    
                
                    // 検索を成功し、該当数が返されたかチェックする。
                    Match match = regHit.Match(str);
                    if (match.Success) 
                    {
                        Debug.WriteLine("該当数" + match.Value);
                        this.Status = match.Value;
                    }

                    // 市区町村名が短がすぎかどうかチェックする。
                    Match matchShort = regShort.Match(str);
                    if (matchShort.Success) 
                    {
                        Debug.WriteLine(matchShort.Value);
                        throw(new Exception(matchShort.Value));
                    }

                    // 該当する都道府県が複数あるかどうかチェックする。
                    Match match1 = regMultiKen.Match(str);
                    if (match1.Success) 
                    {
                        status = "都道府県を";
                        Debug.WriteLine(matchShort.Value);
                        while( true )
                        {
                            str = sr.ReadLine();
                            if (str == null)
                                break;
                            Match match2 = regOp.Match(str);
                            if (match2.Success) 
                            {
                                status +=  " " + match2.Value;
                                Debug.WriteLine(match2.Value);
                            }
                        }
                        status += " から指定してください。";
                        MultipleKenException exc = new MultipleKenException(status);
                        throw (exc);
                    }

                    MatchCollection matchCol = regInfo.Matches(str);
                    if (matchCol.Count > 3)
                    {
                        ZipCode zipCode = new ZipCode();
                        zipCode.Set2(matchCol);
                        array.Add(zipCode);
                        // デバッグ用 
                        Debug.WriteLine(str);
                        for(int i = 0; i < matchCol.Count; i++)
                        {
                            Debug.WriteLine(matchCol[i].Value);
                        }                
                    }
            
                    Debug.WriteLine("End Address2ZipReadCallBack");
                }            
                cb(array, "");
            } 
            catch (MultipleKenException exc)
            {
                cb(null, exc.Message);
            }
            catch (Exception exc)
            {
                cb(null, exc.Message);
            }
            finally
            {
                if (sr != null)
                    sr.Close();
            }
        }
        
        /// <summary>
        /// 住所より郵便番号を検索するメソッド
        /// </summary>
        /// <param name="ken">県名</param>
        /// <param name="city">市町村名</param>
        /// <param name="town">町域名</param>
        /// <returns>ArrayList of ZipCode Class</returns>
        public void GetZipCodeFromAddress(string ken, string city, string town)
        {
            try
            {
                Debug.WriteLine("Start GetZipCodeFromAddress");
                WebRequest webReq = HttpWebRequest.Create( Address2ZipURL );
                webReq.Method = "POST"; 
                // 5秒でタイムアウトさせる。
                webReq.Timeout = timeout;   // mSec
                // IE のProxy 設定を使用する。
                webReq.Proxy = System.Net.WebProxy.GetDefaultProxy();
                webReq.ContentType = "application/x-www-form-urlencoded"; 
                // POST パラメータを書く。
                // 正確なパラメータを渡すために HttpUtility.UrlEncode()でエンコードする。
                this.SetParameters(ken, city, town);
                                
                // 非同期要求に対するコールバックを設定します。
                AsyncCallback writeCallBack = new AsyncCallback(this.WriteCallBack); 
                // 非同期で要求します。
                IAsyncResult r = webReq.BeginGetRequestStream(writeCallBack, webReq);

                // 待つ
                if (r.AsyncWaitHandle.WaitOne(timeout, true) == false)
                {
                    webReq.Abort();
                    return;
                }
                ///////////////////////////////////////////////

                // 非同期要求に対するコールバックを設定します。
                AsyncCallback readCallBack = new AsyncCallback(this.Address2ZipReadCallBack); 
                // 非同期で要求します。
                IAsyncResult rAr = webReq.BeginGetResponse(readCallBack, webReq);
                // 待つ場合
                if (rAr.AsyncWaitHandle.WaitOne(timeout, true) == false)
                {
                    webReq.Abort();
                    return;
                }
                Debug.WriteLine("End GetZipCodeFromAddress");
            }
            catch (Exception exc)
            {
                cb(null, exc.Message);
            }
        }
        #endregion
    }
}
about.cs
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;

namespace Uchukamen.Util.AboutZipCodeSearcher
{
    /// <summary>
    /// About の概要の説明です。
    /// </summary>
    public class About : System.Windows.Forms.Form
    {
        private System.Windows.Forms.LinkLabel linkLabel1;
        private System.Windows.Forms.Button button1;
        private System.Windows.Forms.Label labelVersion;
        private System.Windows.Forms.Label labelProductName;
        /// <summary>
        /// 必要なデザイナ変数です。
        /// </summary>
        private System.ComponentModel.Container components = null;

        public About()
        {
            //
            // Windows フォーム デザイナ サポートに必要です。
            //
            InitializeComponent();

            this.labelProductName.Text = Application.ProductName.ToString();
            this.labelVersion.Text = "Ver." + Application.ProductVersion.ToString();
        }

        /// <summary>
        /// 使用されているリソースに後処理を実行します。
        /// </summary>
        protected override void Dispose( bool disposing )
        {
            if( disposing )
            {
                if(components != null)
                {
                    components.Dispose();
                }
            }
            base.Dispose( disposing );
        }

                #region Windows Form Designer generated code
        /// <summary>
        /// デザイナ サポートに必要なメソッドです。このメソッドの内容を
        /// コード エディタで変更しないでください。
        /// </summary>
        private void InitializeComponent()
        {
            this.linkLabel1 = new System.Windows.Forms.LinkLabel();
            this.labelProductName = new System.Windows.Forms.Label();
            this.button1 = new System.Windows.Forms.Button();
            this.labelVersion = new System.Windows.Forms.Label();
            this.SuspendLayout();
            // 
            // linkLabel1
            // 
            this.linkLabel1.Location = new System.Drawing.Point(80, 80);
            this.linkLabel1.Name = "linkLabel1";
            this.linkLabel1.Size = new System.Drawing.Size(152, 23);
            this.linkLabel1.TabIndex = 0;
            this.linkLabel1.TabStop = true;
            this.linkLabel1.Text = "C# プログラミング";
            this.linkLabel1.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.OnLinkClicked);
            // 
            // labelProductName
            // 
            this.labelProductName.Font = new System.Drawing.Font("Arial Black", 20.25F, (System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Italic), System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
            this.labelProductName.ForeColor = System.Drawing.Color.#AAAAFF;
            this.labelProductName.Location = new System.Drawing.Point(16, 8);
            this.labelProductName.Name = "labelProductName";
            this.labelProductName.Size = new System.Drawing.Size(312, 40);
            this.labelProductName.TabIndex = 1;
            this.labelProductName.Text = "ProductName";
            // 
            // button1
            // 
            this.button1.DialogResult = System.Windows.Forms.DialogResult.OK;
            this.button1.Location = new System.Drawing.Point(272, 72);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(56, 24);
            this.button1.TabIndex = 2;
            this.button1.Text = "OK";
            // 
            // labelVersion
            // 
            this.labelVersion.Font = new System.Drawing.Font("Arial Black", 12F, (System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Italic), System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
            this.labelVersion.ForeColor = System.Drawing.Color.#AAAAFF;
            this.labelVersion.Location = new System.Drawing.Point(56, 48);
            this.labelVersion.Name = "labelVersion";
            this.labelVersion.Size = new System.Drawing.Size(199, 28);
            this.labelVersion.TabIndex = 3;
            this.labelVersion.Text = "Ver.";
            // 
            // About
            // 
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 12);
            this.ClientSize = new System.Drawing.Size(338, 104);
            this.Controls.AddRange(new System.Windows.Forms.Control[] {
                                                                          this.labelVersion,
                                                                          this.button1,
                                                                          this.labelProductName,
                                                                          this.linkLabel1});
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
            this.Name = "About";
            this.Text = "About";
            this.Load += new System.EventHandler(this.About_Load);
            this.ResumeLayout(false);

        }
                #endregion

        private void About_Load(object sender, System.EventArgs e)
        {
            this.linkLabel1.Links.Add(0, this.linkLabel1.Text.Length,  
                "http://ukamen.hp.infoseek.co.jp/");

        }

        private void OnLinkClicked(object sender, System.Windows.Forms.LinkLabelLinkClickedEventArgs e)
        {
            e.Link.Visited = true;
            System.Diagnostics.Process.Start(e.Link.LinkData.ToString());        
        }

    }
}