Adsense_top

2009年8月31日月曜日

C# 変形ウインドウの作成

通知用に通常の形でないウインドウが必要になったので、試してみました。
とりあえず基本ということで丸いウインドウ。


public Form1()
{
InitializeComponent();
System.Drawing.Drawing2D.GraphicsPath path =
new System.Drawing.Drawing2D.GraphicsPath();
path.AddEllipse(0, 0, this.Width, this.Height);
this.Region = new Region(path);
}

本当はWPFでやればいいのでしょうが、簡単だったのでメモしておきます。


2009年8月22日土曜日

C# Twitter API ストリーム系.. その3

C# Twitter API ストリーム系に挑戦してみる」「C# Twitter API ストリーム系.. その2」の続きです。
前回までに書いたコードの使用方法を確認の意味で書いていきます。まだ読まれていいない方はそちらもお読みください。


分かりやすいようにForm1上にstartButtonとstopButtonがあるものとして書いていきます。
まずは、Twitterサーバーへの要求の開始のしかたです。



private void startButton_Click(object sender, EventArgs e)
{
this.Received += new ReceiveEventHandler(Form1_Received);
ArgsObject obj = new ArgsObject("user", "password",
@"http://stream.twitter.com/follow.xml",
HttpMethod.POST,
new string[] { "follow=42123706" }, 2048);
Thread thread = new Thread(this.Execute);
thread.Start(obj);
}

ArgsObjectクラスのコンストラクタの引数は、順に アカウント名・パスワード・ファイル形式を指定した形でのAPIのURL・HTTPメソッド・APIの引数の配列・読み取りストリームのバッファサイズです。

ここで引数に使用しているIDは、「Google_News_jp」のものです。


受信待機を中止する場合は、Stopメソッドを呼び出します。


最初のコードで割り当てているイベントで受信内容を受け取ります。



void Form1_Received(string result)
{
Console.WriteLine(result);
}

ここでは、コンソールに書きだしていますが実際にコントロール上に表示するのであれば、「InvokeRequired」の確認して、delegateを介して操作するように変更してください。また今回は、「stream.twitter.com/follow.format」APIの受信内容が一度に受けられるバッファサイズを指定しましたが、イベントはバッファサイズ毎に起動されますので、一度のイベントで1レコードではないので、レコードの切れ目などを判定する必要がある場合がありますので注意してください。
他注意点としては、接続維持のための決まったデータが一定時間ごとに送られて来ますので捨てる必要があります。実際の受信間隔、受信データはテストして実際に確認してみてください。


2009年8月19日水曜日

C# Twitter API ストリーム系.. その2

昨日の「C# Twitter API ストリーム系に挑戦してみる」の続きです。
先ずは、残りのメソッドや列挙型


受信イベントの発行



private void OnReciveded(string content)
{
if (Received != null)
Received(content);
}

メソッドで使用するデータを格納するオブジェクトの構造体



public struct ArgsObject
{
public string UserId;
public string Password;
public HttpMethod Method;
public string Url;
public int BufferSize;
public string[] Parameters;
public ArgsObject(string userId, string password,
string url, HttpMethod method,
string[] parameters, int bufferSize)
{
this.UserId = userId;
this.Password = password;
this.Url = url;
this.Method = method;
this.Parameters = parameters;
this.BufferSize = bufferSize;
}
}

受信待機を終了させるメソッド



private void Stop()
{
state.Request.Abort();
}

非同期要求で使用する状態オブジェクトのクラス



public class RequestState
{
public int BufferSize = 1024;
public StringBuilder StringValue = new StringBuilder
public byte[] Buffer
public HttpWebRequest Request = null;
public HttpWebResponse Response = null;
public Stream Stream
public RequestState(int bufferSize)
{
BufferSize = bufferSize;
Buffer = new byte[BufferSize];
}
public RequestState()
{
Buffer = new byte[BufferSize];
}
public void DataClear()
{
StringValue.Length = 0;
}
}

HTTP使用するメソッドを指定する列挙型



public enum HttpMethod
{
POST,
GET,
DELETE
}

Twitterから受信するファイル形式を指定する列挙型



public enum ResultFormat
{
json,
xml,
rss,
atom
}

まぁ、ここまでのソースを読めば大体の使い方は読めているとは思いますが...
そろそろ眠たくなってきましたので、使用方法などは次回にまわさせていただきます。


2009年8月18日火曜日

C# Twitter API ストリーム系に挑戦してみる

久しぶりに書くことが出来ました。
Twitter API にβらしいのですが、ストリーム系のものがあります。
リアルタイムにフォローしたりすることが出来ます。Twitterらしい機能ですので、書いてみました。
MSDNのサンプルを参考にしました。


先ずはクラス変数とイベント



public event ReceiveEventHandler Received;
RequestState state = null;
public delegate void ReceiveEventHandler(string result);

ワーカースレッドとして呼び出すメソッドです。



private void Execute(object obj)
{
// 引数オブジェクトを実際の型にキャスト
// ArgsObjectクラスについては後述します。
ArgsObject args = (ArgsObject)obj;
// ワーカースレッドでエラーを処理しないと
// プログラム自体が落ちてしまうため処理は必須
try
{
StringBuilder paramBuilder = new StringBuilder();
foreach (string param in args.Parameters)
{
if (paramBuilder.Length > 0)
paramBuilder.Append("&");
paramBuilder.Append(param);
}
HttpWebRequest request =
(HttpWebRequest)WebRequest.Create(args.Url);
System.Net.ServicePointManager.Expect100Continue = false;
request.Method =
Enum.GetName(typeof(HttpMethod), args.Method);
request.ContentType =
"application/x-www-form-urlencoded";
request.Credentials =
new NetworkCredential(args.UserId, args.Password);
// 非同期動作で使用する状態オブジェクト
state = new RequestState(args.BufferSize);
state.Request = request;

StreamWriter writer =
new StreamWriter(request.GetRequestStream());
if (paramBuilder.Length > 0)
writer.Write(paramBuilder.ToString());
writer.Close();

// 非同期要求
IAsyncResult iAasyncResult =
(IAsyncResult)request.BeginGetResponse(
new AsyncCallback(ResponseCallback), state);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}

レスポンス受信



private void ResponseCallback(IAsyncResult ar)
{
try
{
// 非同期要求用状態オブジェクト
RequestState state = (RequestState)ar.AsyncState;
HttpWebRequest request = state.Request;
state.Response =
(HttpWebResponse)request.EndGetResponse(ar);
// ストリームから読み込む
Stream stream = state.Response.GetResponseStream();
state.Stream = stream;
// 非同期読み込み開始
IAsyncResult iAsyncResult =
stream.BeginRead(
state.Buffer, 0, state.BufferSize,
new AsyncCallback(ReadCallBack), state);
}
catch(Exception e)
{
Console.WriteLine(e.Message);
}
}

レスポンスのデータの読み込み



private void ReadCallBack(IAsyncResult ar)
{
try
{
RequestState state = (RequestState)ar.AsyncState;
// 非同期読み込み(待機)
Stream stream = state.Stream;
int read = stream.EndRead(ar);
if (read > 0)
{
state.StringValue.Append(
Encoding.ASCII.GetString(state.Buffer, 0, read));
if (state.StringValue.Length > 1)
{
string stringContent =
state.StringValue.ToString();
// 受信イベントを
OnReciveded(stringContent);
state.DataClear();
}
IAsyncResult iAsyncResult =
stream.BeginRead(state.Buffer, 0, state.BufferSize,
new AsyncCallback(ReadCallBack), state);
}
else
{
if (state.StringValue.Length > 1)
{
string stringContent = state.StringValue.ToString();
OnReciveded(stringContent);
state.DataClear();
}
stream.Close();
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}

今回も出来るだけ簡潔に書くように心がけましたので、結構な手抜きになっています。

長くなって来ましたので、今回書き残したメソッドの中で使われている、クラスやメソッドと使用方法は次回(明日か明後日)に分けて書くことにします。