JDBな人生  専門的なことから日常的なことまで~ まぁ自由きままに書いていきます。
2017年07月 / 06月<< 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 >>08月

アクセスランキング

[ジャンルランキング]
コンピュータ
454位
アクセスランキングを見る>>

[サブジャンルランキング]
プログラミング
68位
アクセスランキングを見る>>

VB.NETからSkypeチャットを送受信してみる【続報】

久々にVB.NETでちょっとしたツールを作っています。
今回は、SKYPE4LCOMLibというAPIを通してSkypeを操作する方法について、簡単に記事を書こうと思います。


APIが廃止されたため、現在ではこの方法を使うことはできません。
Microsoftが何か対応してくれることを願いましょう…

導入)

Skype Developer - Desktop API (Accessories)
http://dev.skype.com/accessories

自作プログラムからSkypeを操ろう! - toriimiyukkiの日記
http://d.hatena.ne.jp/toriimiyukki/20100716/1279281599

色々と調べてみましたがチャット関連の情報が少ないようなので、この記事ではチャット中心に書きます。

Skypeのインスタンス化
Skype = New SKYPE4COMLib.Skype

'この時点でSkypeが起動していないと操作不可。7はSkypeのプロトコルのバージョン
Skype.Attach(7, False)

※Skypeの状態の確認
Skype.Client.IsRunning
ブール値です。まあこれは適宜チェックを行えばよいかと。


このAPIでは、取得したチャットオブジェクトをもとに操作を行います。
ということで、目的のチャットオブジェクトを探す関数をいくつか書いてみました。

IDからチャットオブジェクト(個人)の取得
Function GetChatUser(ByVal ID As String) As SKYPE4COMLib.Chat
    For Each e As SKYPE4COMLib.Chat In Skype.Chats
        If e.DialogPartner = ID Then
            Return e
        End If
    Next
    Return Nothing
End Function


表示名からチャットオブジェクト(個人)の取得
Function GetChatUserByName(ByVal Name As String) As SKYPE4COMLib.Chat
    For Each e As SKYPE4COMLib.Chat In Skype.Chats
        If e.Topic = "" Then
            For Each u As SKYPE4COMLib.User In e.ActiveMembers
                If u.FullName = Name Then
                    Return e
                ElseIf e.FriendlyName = Name And e.ActiveMembers.Count = 1 Then
                    Return e
                End If
            Next
        End If
    Next
    Return Nothing
End Function

グループチャットの名前から取得
Function GetChatRoom(ByVal Name As String) As SKYPE4COMLib.Chat
    For Each e As SKYPE4COMLib.Chat In Skype.Chats
        If e.Topic = Name Then
            Return e
        End If
    Next
    Return Nothing
End Function


※なお、すべてのチャットの取得はSkype.Chats、アクティブなもののみ対象であればSkype.ActiveChatsにて可能です。

≪チャットの送信≫
送信は取得したチャットオブジェクトからSendMessageメソッドを呼び出して行います。
Dim c As SKYPE4COMLib.Chat = GetChatUser("echo123")
c.SendMessage("メッセージ本文")


≪チャットの受信≫
こちらはMessageStatusイベントを利用します。なお、WithEventsキーワードの記述も行っておいてください。
'クラスの宣言直後に
Private WithEvents Skype As SKYPE4COMLib.Skype

Sub GotMessage(ByVal Msg As SKYPE4COMLib.ChatMessage, ByVal Status As SKYPE4COMLib.TChatStatus) Handles Skype.MessageStatus
    Console.WriteLine(Msg.Body)
End Sub


こんな感じです。
公式のリファレンスが少し読みにくいですが、APIの構造は比較的わかりやすいので勘で書いてもなんとかなるような気もします。

今作っているツールの公開はまだ考え中ですが
公開するときには、また記事を一つ書こうと思います。

#最近は記事への質問も受け付けています。何かあったらお気軽にー
   VB.NET    TB(0)    CM(0)    EDIT    ページ↑

TextBoxの文章を Ctrt + A で全選択できるようにする

TextBoxにフォーカスが当たっているとき、デフォルトではCtrl + Aを押しても全選択の操作はできません。

基本的にこのページの通りにコードを書けばこの操作は実装できます。

テキストボックスで CTRL+A を有効にする - BiBoLoG
http://d.hatena.ne.jp/Guernsey/20081016/1224135096

が、このままではこの操作を実行したときにエラー音が鳴ります。
そのためこの処理の記述のついでにイベントをキャンセルする処理も必要になります。

というわけで、Ctrl + Aでテキストを全選択する処理はこちらになります。

Private Sub TextBox1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles TextBox1.KeyDown
    If e.KeyCode = Keys.A And e.Control = True Then
        TextBox1.SelectAll()
        e.SuppressKeyPress = True
    End If
End Sub


もっとシンプルな方法があってもいいような気がしますが・・・
   VB.NET    TB(0)    CM(0)    EDIT    ページ↑

数字のみ入力できるテキストボックス

ずいぶんと間があいてしまいました。すみません。

最近、少しわけあってVB.NET(.NET 3.0)で開発をしています。

設定画面で「数字を数ケタ入力する」項目があり、どのような方法で入力させるか、ということに迷い、とりあえずテキストボックスを利用しました。そこで利用したコードを載せておきます。

Private Sub TextBox1_LostFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextBox1.LostFocus
    sender.Text = StrConv(sender.Text, VbStrConv.Narrow)
End Sub

Private Sub TextBox1_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged
    If (System.Text.RegularExpressions.Regex.Match(sender.Text, "\D|![0123456789]").Value <> "") Then
        Dim SS As Integer = TextBox1.SelectionStart
        sender.Text = System.Text.RegularExpressions.Regex.Replace(sender.Text, "!(\d|[0123456789])", "")
        If SS > 0 Then
            TextBox1.SelectionStart = SS - 1
        End If
    End If
End Sub

入力内容の変更が確定されたときに数字以外の文字が入っていないかチェック、入っていたらカーソルの位置を記録して余計な文字を排除、処理後にカーソルの位置を元に戻すというものです。
この方法の場合、コピー&ペーストへの対策もできます。

またフォーカスが外れたときに全角数字を半角数字に変換する処理も入れました。

そこそこ使いやすいものになったので、とりあえずこれを使っています。

#VB.NETはやっぱ色々厳しいですね・・・
   VB.NET    TB(0)    CM(0)    EDIT    ページ↑

久しぶりのVB.NET

今、訳あって、VB.NETでフォームアプリケーションを開発しています。

しばらくはPerlとJavaScriptの組み合わせばかりで、VB.NETは本当に久しぶりなんですが、コードを書いている途中にイラつくことが多々あります。

var ← Dim
ListBox1.Text + 1 ← Integer.Parse(ListBox1.Text) + 1
ListBox1.Text.Substring(1); ← ListBox1.Text.Substring(1)

この3つは、何回間違えたかわかりません。

Perlに慣れていると、Perlは文字列・数値気にしなくても、「.」と「+」の使い分けだけで済むのに、VB.NETは「ToString()」や「Integer.Parse()」を使わなければならない、という点が、かなり面倒に感じます。
#VB.NETでInteger以外の数値の型を使ったことがないような気が・・・

でも、入力補助は、便利ですね。うろ覚えのクラスやメソッドでも、ググらなくて良い、という点が特に。

因みに、今回作っているものは個人的に作っているものなのでここに公開はしませんが、これに関連して、VB.NET関連の記事をいくつか書こうと思います。
   VB.NET    TB(0)    CM(0)    EDIT    ページ↑

Cookieを添えてPOSTした後レスポンスのCookieを取得する

タイトルの表現がわかりにくいのはあまり気にしないでください。「POSTで値を送信」「Cookieを添える」「レスポンスのCookieを取得」の三つを一文にまとめたらこうなりました。

その方法ですが、ググってもこれというサンプルコードもなかったので、とりあえず書いてみました。もっと簡潔に書けると思うんですが・・・。
'Cookieを入れる変数「CookieData As System.Net.CookieContainer」が宣言されているものとします

'↓送信するデータを入れる(URLエンコードしておく)
Dim SendData As String = "mode=new&id=00000019&title=%e6%98%8e%e6%97%a5%e3%81%ae%e5%a4%a9%e6%b0%97"
Dim SendDataBytes() As Byte = System.Text.Encoding.ASCII.GetBytes(SendData)

Dim WebReq As System.Net.HttpWebRequest = System.Net.HttpWebRequest.Create(<URL>)

WebReq.CookieContainer = CookieData
'↑送信するCookieがある場合はここで指定
'↓無い場合はとりあえずnew
'WebReq.CookieContainer = New System.Net.CookieContainer

WebReq.Method = "POST"
WebReq.ContentType = "application/x-www-form-urlencoded"
WebReq.ContentLength = SendDataBytes.Length

Dim ReqStream As System.IO.Stream = WebReq.GetRequestStream
ReqStream.Write(SendDataBytes, 0, SendDataBytes.Length)
ReqStream.Close()

Dim WebRes As System.Net.HttpWebResponse = WebReq.GetResponse

'↓受信したCookieを入れる
CookieData = WebReq.CookieContainer

Dim ResStream As System.IO.Stream = WebRes.GetResponseStream
Dim StrReader As New System.IO.StreamReader(ResStream, System.Text.Encoding.GetEncoding("utf-8"))
Dim ResText = StrReader.ReadToEnd()
'↑本文は「ResText」に格納
StrReader.Close()

こんな感じです。

「Class System.Net.CookieContainer」は、「Class System.Net.Cookie」の配列になっています。
その「System.Net.Cookie」ですが、「Name」と「Value」というプロパティを持っていて、それぞれCookieの「a(Name)=b(Value)」を表します。


一応、これをコピペしたときどこを変えれば使いまわせるかわかるように、下線を付けておきました。

このサンプルソースをコピペする以前にそもそもCookie添えでPOSTして返ってきたCookieを取得するなんていう処理をすること自体あまりないかもしれませんが、まあ参考にできるのであればご自由に使ってください。


#久しぶりにVB.NETで書いてみました。どうも自分はフォームアプリケーションの開発には向いていないと思います。はい。だからと言ってコンソールアプリケーション作りたいとも思いませんが。慣れの問題ですかね・・・。
   VB.NET    TB(0)    CM(1)    EDIT    ページ↑

プロフィール

JDB Luigi

Author:JDB Luigi
どこにでもいるようなありふれた人間・・・という訳でもなく、かと言って怪しい宗教を信仰する変人という訳でも無い。

基本的に掲載しているコード等は煮ていただいても焼いていただいても結構ですが、利用は自己責任にてお願いいします。
また、バグ・アドバイス等もしあればよろしくお願いします。