始めにそもそも、なぜC#.NETに没頭したかと言うと、ある日のこと、紀伊国屋書店でVBAの本を見ていたら、VB6よりもC++よりもまったく新しい概念の”C#.NET”の見出しが目に飛び込んできました。
C#.NETってなんだろう?と思い次々と本を買うことになったのです。
これからC#.NETを始める方、私が辿ったC#.NET奮戦記を参考にして頂ければ超最速で習得出来ると思います。
題名:”VisualC#.netではじめるTCPネットワークプログラミング”
発行:趙 森
(ここではサーバーとクライアントの双方向通信を確認しました)
ステップ2:コンポーネントが理解出来なかったので、又本を買いました。
題名:”C#によるコンポーネントプログラミング”
発行:瀬尾佳隆
(ここではCOMコンポーネントが習得できます)
ステップ3:OCXコンポーネントが理解出来なかったので、又本を買いました。
題名:”C#.NETプログラミング入門”
発行:arton
(ここでは全体的なおさらいです)
題名:”VisualC#.NET基礎300の技
発行:ガリバー
(ここでは文法のおさらいです)
ステップ5:C++.NETとの違いを確認するため、本を買いました。
題名:”VisualC++.NETアプリケーション開発入門”
発行:日経BP
(ここではC++.NETに一部機能を移植しました)
お世話になったインターネットサイトのご紹介です。
1、宇宙仮面のC#プログラミング
2、第 5 回 VC# とおもしろコントロール
3、イベントを処理するとエラーが発生する
4、COMラッパーアセンブリに厳密名で署名
5、遅延バインディングによりアンマネージDLL関数を呼び出す
6、連載:C#入門 > 第3回 クラスとオブジェクト
7、INIファイルを読み書きするには?
8、バイト列と数値を変換するには?
だいたいどんなものかと言うと
1、OSをも包含していると言う概念のアプリケーション開発ツールであること。
2、CLR(コモンランゲージランタイム)にて実行されること。
3、画面作成はツールBOXから各種コントロールを貼付けて作成できること。
4、各種ActiveXコンポーネント(OCX)もツールBOXから画面に貼りつけて組込みできること。
5、必ず参照設定が必要なこと。
6、参照設定を通してメモリの自動開放(ガベージコレクションと言う)がされること。
7、環境設定はプロパテイで簡単に行えること。
8、イベント情報はイベントハンドラーで簡単に受取れること。
とにかく作ってみました。
”VisualC#.netではじめるTCPネットワークプログラミング”に記載の片方向通信ソースを
双方向通信に改造したソースです。
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
//追加した名前空間
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace Server
{
///
/// Form1 の概要の説明です。
///
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Button btn_start;
private System.Windows.Forms.Button btn_sleft;
private System.Windows.Forms.RichTextBox rtbox_show;
//追加した変数
private Socket mySock;
private TcpListener tcpL;
private NetworkStream netStream;
private Thread tMain;
private System.Windows.Forms.Button btn_msg;
///
/// 必要なデザイナ変数です。
///
private System.ComponentModel.Container components = null;
public Form1()
{
//
// Windows フォーム デザイナ サポートに必要です。
//
InitializeComponent();
//
// TODO: InitializeComponent 呼び出しの後に、コンストラクタコードを追加してください。
//
}
///
/// 使用されているリソースに後処理を実行します。
///
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
///
/// デザイナ サポートに必要なメソッドです。このメソッドの内容を
/// コード エディタで変更しないでください。
///
private void InitializeComponent()
{
/// 省略します。
}
#endregion
///
/// アプリケーションのメイン エントリ ポイントです。
///
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
//************************************************************
//ポート1888番を聞くモードにします
//************************************************************
private void btn_start_Click(object sender, System.EventArgs e)
{
tcpL = new TcpListener(1888);
tcpL.Start();
rtbox_show.AppendText("接続待ち......\r\n");
tMain = new Thread(new ThreadStart(waitConnect));
tMain.IsBackground=true;
tMain.Start();
}
//***********************************************************
//クライアントからの接続を受付ます
//***********************************************************
private void waitConnect()
{
while(true)
{
mySock = tcpL.AcceptSocket();
if(mySock.Connected)
{
rtbox_show.AppendText("\r\n接続しました。\r\n");
Thread t = new Thread(new ThreadStart(receive));
t.IsBackground = true;
t.Start();
}
}
}
//***********************************************************
//クライアントからデータを受信します
//***********************************************************
private void receive()
{
while(true)
{
try
{
netStream = new NetworkStream(mySock);
byte [] bb = new byte [1024];
netStream.Read(bb,0,bb.Length);
string msgFromClient = System.Text.Encoding.UTF8.GetString(bb);
rtbox_show.AppendText(msgFromClient);
}
catch
{
}
}
}
//*****************************************************************
//送信用関数です
//*****************************************************************
private void sendMsg()
{
try
{
byte [] bb = new byte[1024];
string sendMsg = "Server >>> " +rtbox_show.Text + "\r\n";
bb = System.Text.Encoding.UTF8.GetBytes(sendMsg.ToCharArray());
netStream.Write(bb,0,bb.Length);
netStream.Flush();
}
catch
{
MessageBox.Show("送信できません");
}
}
//*****************************************************************
// メッセージボタンがクリックしたら、送信する関数を呼び出します
//*****************************************************************
private void btn_msg_Click_1(object sender, System.EventArgs e)
{
sendMsg();
}
//***********************************************************
//サーバをストップします
//***********************************************************
private void btn_sleft_Click(object sender, System.EventArgs e)
{
try
{
rtbox_show.AppendText("\r\n停止しています\r\n");
netStream.Close();
mySock.Close();
tMain.Abort();
tcpL.Sleft();
}
catch
{
}
}
}
}
################################################################################################################################
下記は応用例で作ったIPカメラ(IO制御も可能)の監視制御画面です。
上記画面の作成手順です。
1、ActiveXコンポーネント(OCX)などツールBOXに無いものは、ツールBOXのカスタマイズで追加登録する。
2、ツールBOXから使いたいコントロール、コンポーネントをフォームに張付ける。
3、ソリューションエクスプローラーからコンポーネントの参照設定をする。
4、コントロール、コンポーネントの環境設定をプロパティで設定する。
5、コントロール、コンポーネントのイベントハンドラをプロパティで設定しておく。
6、画面ができたら一旦ビルドしておく。
7、コード表示にして、名前空間、変数を追加して各種プログラム、イベント処理を記述する。
8、時々ビルドしながらエラーを取り除く。
9、最終的にビルド成功で終了です。
驚いたことに、DOSコマンドからInterop.dllファイルを逆アセンブルして変更することができましたがこの機能は今後有効に使えますね。