SQLの窓

2013年10月29日


Framework4(C#) : Windows Phone OS 7.1 : WebClient で Post と Get する汎用 static クラス

Windows Phone では、Encoding に UTF-8 系しか無いので、アクセス先は UTF-8 限定となります。

  • utf-8 : UTF8Encoding
  • utf-16 : UnicodeEncoding (リトル エンディアン)
  • utf-16BE : UnicodeEncoding (ビッグ エンディアン)
  • utf-16LE :
  • using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Text;
    
    namespace winofsql {
    
    	class Tool {
    
    		// *********************************************
    		// UTF-8 POST
    		// *********************************************
    		public static string Post(string url,
                Dictionary<string, string> param,
                UploadStringCompletedEventHandler UploadStringCompleted=null) {
    
    			string result = "";
    
    			try {
    				WebClient webClient = new WebClient();
    
                    if ( UploadStringCompleted != null ) {
                        // 呼び出し側でラムダ式を使う事を想定した
                        // イベント登録
                        webClient.UploadStringCompleted += UploadStringCompleted;
                    }
    
                    webClient.Headers["Content-Type"] = "application/x-www-form-urlencoded";
    
                    string data_string = "";
    
                    foreach (KeyValuePair<string, string> kvp in param)
                    {
                        if (data_string != "")
                        {
                            data_string += "&";
                        }
                        data_string += kvp.Key + "=";
    
                		// *******************************************************
                        // System.Windows 内の System.Web にあります
                		// *******************************************************
                        data_string += HttpUtility.UrlEncode(kvp.Value);
                    }
                    
                    webClient.UploadStringAsync(new Uri(url), "POST", data_string);
    
    			}
    			catch (Exception Err) {
    				result = "ERROR: " + Err.Message;
    			}
    
                return result;
    
    		}
    
    		// *********************************************
    		// URL のみ呼び出し GET
    		// *********************************************
    		public static string Get(
                string url,
                DownloadStringCompletedEventHandler DownloadStringCompleted=null) {
    
    			string result = "";
    
    			try {
    				WebClient webClient = new WebClient();
    
                    if ( DownloadStringCompleted != null ) {
                        // 呼び出し側でラムダ式を使う事を想定した
                        // イベント登録
                        webClient.DownloadStringCompleted += DownloadStringCompleted;
                    }
    
                    webClient.DownloadStringAsync(new Uri(url));
    
    			}
    			catch (Exception Err) {
    				result = "ERROR: " + Err.Message;
    			}
    
                return result;
    
    		}
    
    		// *********************************************
    		// データ呼び出し( UTF-8 ) GET
    		// *********************************************
    		public static string Get(
                string url, 
                Dictionary<string, string> param,
                DownloadStringCompletedEventHandler DownloadStringCompleted=null) {
    
                string result = "";
    
                try
                {
                    WebClient webClient = new WebClient();
    
                    if (DownloadStringCompleted != null)
                    {
                        // 呼び出し側でラムダ式を使う事を想定した
                        // イベント登録
                        webClient.DownloadStringCompleted += DownloadStringCompleted;
                    }
    
                    string data_string = "";
    
                    foreach (KeyValuePair<string, string> kvp in param)
                    {
                        if (data_string != "")
                        {
                            data_string += "&";
                        }
                        data_string += kvp.Key + "=";
    
                        // *******************************************************
                        // System.Windows 内の System.Web にあります
                        // *******************************************************
                        data_string += HttpUtility.UrlEncode(kvp.Value);
                    }
    
                    webClient.DownloadStringAsync(new Uri(url + "?" + data_string));
    
                }
                catch (Exception Err)
                {
                    result = "ERROR: " + Err.Message;
                }
    
                return result;
    
    		}
    
    	}
    }
    
    
    関連する記事
    
    いろいろな言語におけるバーセントエンコーディング
    
    Framework4.5(C#)ストア : HttpClient で Post と Get する汎用 static クラス
    Framework4(C#) : WebClient で Post と Get する汎用 static クラス
    Android で Post と Get
    
    
    
    
    posted by lightbox at 2013-10-29 21:00 | Windows Phone | このブログの読者になる | 更新情報をチェックする

    2013年10月11日


    VS2010(C#)Phone : ListBox Twitter 検索テンプレート

    SkyDrive へ移動
    
    
    Windows Phone のコードの需要があるかどうかは疑問ですが、Microsoft が用意したバインドのテンプレートは、Windows Phone にしか無いようです。
    
    
    Twitter_Search.cs
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Net;
    using System.Diagnostics;
    using System.Security.Cryptography;
    
    namespace VS2010_Twitter
    {
        class Twitter_Search
        {
            private string _consumer_key;
            private string _consumer_secret;
            private string _token;
            private string _secret;
    
            private string _tweet_api = "https://api.twitter.com/1.1/search/tweets.json";
    
            public Twitter_Search(
                string consumer_key,
                string consumer_secret,
                string token,
                string secret
                )
            {
                _consumer_key = consumer_key;
                _consumer_secret = consumer_secret;
                _token = token;
                _secret = secret;
            }
    
            public void Tweet(string text, int count, DownloadStringCompletedEventHandler newEvent = null)
            {
    
                WebClient wc = new WebClient();
    
                if (newEvent != null)
                {
                    wc.DownloadStringCompleted += newEvent;
                }
    
                // ソートされるリスト
                Dictionary<string, string> sl = new Dictionary<string, string>();
                sl.Add("count", count.ToString());
                sl.Add("oauth_consumer_key", _consumer_key);
                sl.Add("oauth_nonce", Nonce());
                sl.Add("oauth_signature_method", "HMAC-SHA1");
                sl.Add("oauth_timestamp", TimeStamp());
                sl.Add("oauth_token", _token);
                sl.Add("oauth_version", "1.0");
                sl.Add("q", rfc3986(Uri.EscapeDataString(text)));
    
                // http ヘッダ用シグネチャ作成
                string work = "";
                foreach (KeyValuePair<string, string> kvp in sl)
                {
                    if (work != "")
                    {
                        work += "&";
                    }
                    work += kvp.Key + "=" + kvp.Value;
                }
    
                string work2 = "";
                // メソッド
                work2 += "GET" + "&";
                // API URL
                work2 += rfc3986(Uri.EscapeDataString(_tweet_api)) + "&";
                // Oauth + データ
                work2 += rfc3986(Uri.EscapeDataString(work));
    
                // OAuth tool チェック用
                Debug.WriteLine(work2);
    
                string oauth_signature = Signature(work2);
    
                // ヘッダ情報を作成
                work = "";
                foreach (KeyValuePair<string, string> kvp in sl)
                {
                    // oauth_* のみを使用する
                    if (work != "")
                    {
                        if ((kvp.Key + "      ").Substring(0, 6) == "oauth_")
                        {
                            work += ", ";
                        }
                    }
                    if ((kvp.Key + "      ").Substring(0, 6) == "oauth_")
                    {
                        work += kvp.Key + "=" + Dd(kvp.Value);
                    }
                }
                // シグネチャを追加( ヘッダーはソートの必要は無い )
                work += ", oauth_signature=" + Dd(rfc3986(Uri.EscapeDataString(oauth_signature)));
    
                // OAuth tool チェック用
                Debug.WriteLine(work);
    
                // フォーマットは、 OAuth tool で確認。
                wc.Headers["Authorization"] = "OAuth " + work;
    
                // 投稿
                wc.DownloadStringAsync(new Uri(
                    _tweet_api +
                    "?" +
                    "q=" + sl["q"] +
                    "&count=" + sl["count"]
                ));
    
            }
    
            private string rfc3986(string base_string)
            {
                string result = base_string.Replace("!", "%21");
                result = result.Replace("'", "%27");
                result = result.Replace("(", "%28");
                result = result.Replace(")", "%29");
                result = result.Replace("*", "%2A");
                return result;
            }
    
            // ダブルクォートで挟む
            private string Dd(string base_string)
            {
                return "\"" + base_string + "\"";
            }
    
            private string Nonce()
            {
                Random rand = new Random();
                int nonce = rand.Next(1000000000);
                return nonce.ToString();
            }
    
            // タイムスタンプ
            private string TimeStamp()
            {
                TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
                return Convert.ToInt64(ts.TotalSeconds).ToString();
            }
    
            // シグネチャ
            private string Signature(string target)
            {
                string work = _consumer_secret + "&" + _secret;
                byte[] bin = Encoding.UTF8.GetBytes(target);
    
                HMACSHA1 hmacsha1 = new HMACSHA1();
                hmacsha1.Key = Encoding.UTF8.GetBytes(work);
                byte[] hash = hmacsha1.ComputeHash(bin);
    
                return Convert.ToBase64String(hash);
            }
        }
    }
    
    
    関連する記事
    
    VS2012(C#)ストア : ListView Twitter 検索テンプレート
    
    
    
    
    posted by lightbox at 2013-10-11 20:38 | Windows Phone | このブログの読者になる | 更新情報をチェックする

    2013年07月12日


    Live SDK v5.4 : VS2010 + Windows Phone / 画像アップロード

    VS2010 で動いたのは、Windows Phone だけでした。Form アプリで動作させるには、VS2012 が必要なようです。( VS2010 で、一部、情報の参照は動いたのですが、アップロードやダウンロードという一番必要なものが落ちました。dll が足らないとか言われます。しかし、VS2012 では同じものが動作しています )
    
    Microsoft のドキュメントは、どれもこれも微妙にウソでした。
    
    my:SignInButton の追加は、コントロールの Toolbox の『Windows Phone コントロール』で右クリックして『アイテムの選択』で、Program Files 内の "Microsoft SDKs\Live\v5.4\Windows Phone 7.1\References\Microsoft.Live.Controls.dll" を読み込んで使います。
    
    というか、そもそも、Windows8 ストアで動かすとログイン完了で落ちます
    ( Win8 ストアでは、Login する為の単独メソッドがあり、パスワードを間違うとちゃんと反応しますが、ログインがうまく行くと落ちます )
    
    Windows8 ストアアプリは、年額4900円を払って登録しないと専用の API は使用できません。
    
    コード内で使うクラスは、Microsoft.Live.dll を参照します。 Micrsoft のドキュメントでは、同様のものが Windows ストアにもあるような記述がされているのですが、Live SDK v5.4 ではみあたりません。 MainPage.xaml
    <phone:PhoneApplicationPage 
        x:Class="PhoneApp2.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
        xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
        FontFamily="{StaticResource PhoneFontFamilyNormal}"
        FontSize="{StaticResource PhoneFontSizeNormal}"
        Foreground="{StaticResource PhoneForegroundBrush}"
        SupportedOrientations="Portrait" Orientation="Portrait"
        shell:SystemTray.IsVisible="True"
        xmlns:my="clr-namespace:Microsoft.Live.Controls;assembly=Microsoft.Live.Controls">
    
        <!--LayoutRoot は、すべてのページ コンテンツが配置されるルート グリッドです-->
        <Grid x:Name="LayoutRoot" Background="Transparent">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
    
            <!--TitlePanel は、アプリケーション名とページ タイトルを格納します-->
            <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
                <TextBlock
                    x:Name="ApplicationTitle"
                    Text="Live SDK v5.4"
                    Style="{StaticResource PhoneTextNormalStyle}" />
                <TextBlock
                    x:Name="PageTitle"
                    Text="画像アップロード"
                    Margin="9,-7,0,0"
                    Style="{StaticResource PhoneTextTitle1Style}"
                    FontSize="40"
                    TextWrapping="Wrap" />
            </StackPanel>
    
            <!--ContentPanel - 追加コンテンツをここに入力します-->
            <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
                <my:SignInButton
                    Content="Button"
                    Height="101"
                    HorizontalAlignment="Left"
                    Margin="16,20,0,0"
                    Name="signInButton1"
                    VerticalAlignment="Top"
                    Width="420"
                    ClientId="自分のアプリのクライアントID"
                    SessionChanged="signInButton1_SessionChanged"
                    Scopes="wl.signin wl.basic wl.skydrive_update" />
                <TextBlock
                    Height="301"
                    HorizontalAlignment="Left"
                    Margin="19,127,0,0"
                    Name="infoTextBlock"
                    VerticalAlignment="Top"
                    Width="417"
                    FontSize="22"
                    TextWrapping="Wrap" />
                <Button
                    Content="画像アップロード"
                    Height="96"
                    HorizontalAlignment="Left"
                    Margin="19,434,0,0"
                    Name="button1"
                    VerticalAlignment="Top"
                    Width="417"
                    Click="button1_Click"
                    IsEnabled="False" />
            </Grid>
        </Grid>
     
        <!--ApplicationBar の使用法を示すサンプル コード-->
        <!--<phone:PhoneApplicationPage.ApplicationBar>
            <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">
                <shell:ApplicationBarIconButton IconUri="/Images/appbar_button1.png" Text="Button 1"/>
                <shell:ApplicationBarIconButton IconUri="/Images/appbar_button2.png" Text="Button 2"/>
                <shell:ApplicationBar.MenuItems>
                    <shell:ApplicationBarMenuItem Text="MenuItem 1"/>
                    <shell:ApplicationBarMenuItem Text="MenuItem 2"/>
                </shell:ApplicationBar.MenuItems>
            </shell:ApplicationBar>
        </phone:PhoneApplicationPage.ApplicationBar>-->
    
    </phone:PhoneApplicationPage>
    
    
    MainPage.xaml.cs
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using Microsoft.Phone.Controls;
    using Microsoft.Live;
    using Microsoft.Phone.Tasks;
    using System.Diagnostics;
    
    namespace PhoneApp2
    {
        public partial class MainPage : PhoneApplicationPage
        {
    
            private LiveConnectClient client;
            private LiveConnectSession session;
    
            // コンストラクター
            public MainPage()
            {
                InitializeComponent();
            }
    
            // ****************************************************
            // サインイン・ボタン
            // ****************************************************
            private void signInButton1_SessionChanged(object sender, 
                Microsoft.Live.Controls.LiveConnectSessionChangedEventArgs e)
            {
                if (e.Status == LiveConnectSessionStatus.Connected)
                {
                    session = e.Session;
                    client = new LiveConnectClient(session);
                    infoTextBlock.Text = "サインイン";
                    this.button1.IsEnabled = true;
                }
                else
                {
                    infoTextBlock.Text = "未接続";
                    client = null;
                }
            }
    
            // ****************************************************
            // 画像アップロードボタン
            // ****************************************************
            private void button1_Click(object sender, RoutedEventArgs e)
            {
                // 画像参照オブジェクト
                var picker = new PhotoChooserTask();
                // 画像参照オブジェクトに選択完了のイベントを登録
                picker.Completed +=
                    new EventHandler<PhotoResult>(Image_Selected);
                // 参照開始
                picker.Show();
            }
    
            // ****************************************************
            // 選択完了のイベント
            // ****************************************************
            private void Image_Selected(object sender, PhotoResult e)
            {
                if (e.Error != null)
                {
                    this.infoTextBlock.Text = "画像選択エラー: " + e.Error.ToString();
                }
                else
                {
                    // Windows Phone 内部のパスよりファイル名を取得
                    //string[] filePathSegments = e.OriginalFileName.Split('\\');
                    //string fileName = filePathSegments[filePathSegments.Length - 1];
                    // SkyDrive を処理するオブジェクトにイベントを登録
                    client.UploadCompleted
                        += new EventHandler<LiveOperationCompletedEventArgs>(Live_UploadCompleted);
                    // ****************************************************
                    // アップロード開始
                    // ****************************************************
                    client.UploadAsync("me/skydrive", 
                        "PhotoChooserTask.jpg", 
                        e.ChosenPhoto, 
                        OverwriteOption.Overwrite);
                }
            }
    
            // ****************************************************
            // アップロード完了
            // ****************************************************
            private void Live_UploadCompleted(object sender, LiveOperationCompletedEventArgs e)
            {
                if (e.Error == null)
                {
                    IDictionary<string, object> file = (IDictionary<string, object>)e.Result;
                    this.infoTextBlock.Text = "File uploaded. Link: " + file["source"];
    
                    foreach (var key in file.Keys)
                    {
                        Debug.WriteLine(string.Format("KEY : {0} => VALUE : {1}", key, file[key]));
                    }
                    
                }
                else
                {
                    this.infoTextBlock.Text =
                        "Error uploading file: " + e.Error.ToString();
                }
            }
    
        }
    }
    
    
    
    Windows Phone エミュレータでは、『Pause』キーで、キーボードから英数字が入力可能になります。しかし、US キーボード配置なので、@ は、SHIFT+(2 " ふ) で、_ は、SHIFT+(- = ほ) です。
    ( CTRL+ でも動作するようです )
    
    
    
    
    
    
    
    
    
    アプリは、SkyDrive のページの一番下にある『開発者向け情報(英語)』より登録して、『モバイル クライアント アプリ』を『はい』に設定しておきます。VS2012 で、Form アプリからアクセスする場合もこの設定が必要です。
    
    
    
    ※ Android でテストした時のアプリをそのまま使っています
    
    
    
    
    
    posted by lightbox at 2013-07-12 19:00 | Windows Phone | このブログの読者になる | 更新情報をチェックする

    2013年06月10日


    Windows Phone から Post 投稿 と Get 読み出し

    Win8 ストアから Post 投稿 とできるだけ同じ使い方にできるようにしました。ただ、こちらは非同期処理はイベントを記述する必要があるので、ラムダ式で使用する事を想定しています
    
    using System;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Ink;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using System.Collections.Generic;
    using System.Text;
    
    namespace LBOX_Http
    {
        public class Lbox
        {
            public static string errorString = "";
    
    		public static bool Post(string url, Dictionary<string, string> param, UploadStringCompletedEventHandler UploadStringCompleted )
    		{
                bool result = true;
    
                try
    			{
                    WebClient HttpClient = new WebClient();
    
                    HttpClient.UploadStringCompleted += UploadStringCompleted;
    
                    HttpClient.Headers["Content-Type"] = "application/x-www-form-urlencoded";
    
                    string data_string = "";
    
                    foreach (KeyValuePair<string, string> kvp in param)
                    {
                        if (data_string != "")
                        {
                            data_string += "&";
                        }
                        data_string += kvp.Key + "=";
                        data_string += Uri.EscapeDataString(kvp.Value);
                    }
                    
                    HttpClient.UploadStringAsync(new Uri(url), "POST", data_string);
    
    			}
    			catch (Exception Err)
    			{
                    errorString = Err.Message; 
                    result = false;
    			}
    
                return result;
    		}
        }
    }
    
    
    
    ▼ 呼び出し方法
    
    String url = "投稿先の URL";
    var param = new Dictionary<string, string>();
    param.Add("u", "入力文字列");
    Lbox.Post(url, param, (object r_sender, UploadStringCompletedEventArgs r_e) =>
    {
    	if (r_e.Error == null)
    	{
    		MessageBox.Show(r_e.Result);
    	}
    	else
    	{
    		MessageBox.Show(r_e.Error.Message);
    	}
    });
    
    
    
    Get 読み出し
    
    using System;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Ink;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    
    namespace LBOX_Http
    {
        public class Lbox
        {
            public static string errorString = "";
    
            public static bool Get(string url, DownloadStringCompletedEventHandler DownloadStringCompleted)
            {
                bool result = true;
    
                try
                {
                    WebClient HttpClient = new WebClient();
    
                    HttpClient.DownloadStringCompleted += DownloadStringCompleted;
                    if (url.IndexOf("?") == -1)
                    {
                        HttpClient.DownloadStringAsync(new Uri(url + "?" + DateTime.Now.Ticks));
                    }
                    else
                    {
                        HttpClient.DownloadStringAsync(new Uri(url + "&" + DateTime.Now.Ticks));
                    }
    
                }
                catch (Exception Err)
                {
                    errorString = Err.Message;
                    result = false;
                }
    
                return result;
            }
    
        }
    }
    
    
    まだ キャッシュのバグがあるようなので、URL に文字列を付加しています
    
    呼び出し
    
    Lbox.Get("呼び出すURL",
    	(object r_sender, DownloadStringCompletedEventArgs r_e) =>
    {
    	if (r_e.Error == null)
    	{
    		// XML 文字列を dom に変換( System.Xml.Linq を参照追加 )
    		XDocument dom = XDocument.Parse(r_e.Result);
    		XNamespace xn = "http://search.yahoo.com/mrss/";
    
    		var items = dom.Descendants("item");
    		foreach (var item in items)
    		{
    			Debug.WriteLine(item.Element("title").Value);
    			Debug.WriteLine(item.Element("description").Value);
    			Debug.WriteLine(item.Element(xn + "thumbnail").Attribute("url").Value);
    			App.listMain.Items.Add(
    				new ListItem()
    				{
    					id = item.Element("title").Value,
    					name = item.Element("description").Value,
    					link = item.Element("link").Value,
    					img = item.Element(xn + "thumbnail").Attribute("url").Value
    				}
    			);
    		}
    	}
    	else
    	{
    		MessageBox.Show(r_e.Error.Message);
    	}
    });
    
    
    
    
    
    
    
    posted by lightbox at 2013-06-10 21:34 | Windows Phone | このブログの読者になる | 更新情報をチェックする

    2013年05月17日


    Windows Phone の MessageBox

    Windows Phone API リファレンス
    
    ※ WindowsPhone では、MessageBoxButton 列挙体 は、OK と OKCancel しかありません
    
    メッセージ ボックスはモーダルであるため、ユーザーはボタンをタップして、メッセージ ボックスを閉じる必要があります。
    
    Microsoft ドキュメント
    
    MessageBox.Show メソッド (String, String, MessageBoxButton) (System.Windows)
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using Microsoft.Phone.Controls;
    using System.Diagnostics;
    using Microsoft.Phone.Shell;
    
    namespace BlankApp1
    {
        public partial class MainPage : PhoneApplicationPage
        {
            // コンストラクター
            public MainPage()
            {
                InitializeComponent();
            }
    
            private void ApplicationBarIconButton_Click(object sender, EventArgs e)
            {
                var result = MessageBox.Show(
                    (sender as ApplicationBarIconButton).Text,
                    "タイトル",
                    System.Windows.MessageBoxButton.OKCancel
                    );
    
                if (result == MessageBoxResult.OK)
                {
                    Debug.WriteLine("OK");
                }
                if (result == MessageBoxResult.Cancel)
                {
                    Debug.WriteLine("Cancel");
                }
            }
        }
    }
    
    
    このサンプルではメッセージとして、呼び出し元の『ApplicationBarIconButton』のテキストを表示しています
    
    
    
    
    タグ:Windows Phone
    posted by lightbox at 2013-05-17 09:56 | Windows Phone | このブログの読者になる | 更新情報をチェックする

    2013年04月20日


    Windows Phone のアプリケーションバーはテンプレートのコメントを外して使う

    デザイナではどうにもなりません。Microsoft の解説ページでは常に『コメントを外すかここのコードを使え』です。
    
    Microsoft のドキュメントWindows Phone のアプリ バー
    
    ※ 全体概要です
    
    ❷ Windows Phoneのアプリケーション バー アイコン ボタン
    
    アイコン画像の場所と、追加方法です
    
    32ビット
    C:\Program Files\Microsoft SDKs\Windows Phone\v8.0\Icons
    64ビット
    C:\Program Files (x86)\Microsoft SDKs\Windows Phone\v8.0\Icons
    
    XAML で Windows Phone のアプリ バーを作成する方法 コメントを外して作るお話 ❹ Windows Phone のコードでアプリ バーを作成する方法 コードで動的に作るお話 ❺ Windows Phone のアプリ バーのアイコン ボタンとメニュー項目を動的に変更する方法 アプリケーションバーのプロパティを変更するお話 ❻ Windows Phone の複数のページでアプリ バーを再利用する方法 Windows Phone では、ページ毎にデータが独立してしまうので、App.xaml でアプリケーションバーを共有しましょう・・・というお話 ❼ Windows Phone の単一 Pivot コントロールで異なるアプリ バーを使用する方法 Pivot の複数ページは、実際は一つのコントロールなので、元々共有されてしまうので、イベントで違うものを表示しましょう・・・というお話 ❽ チュートリアル: Windows Phone のアプリ バー テスト アプリの作成 いろんなテクニックを使って実装してみましょう・・・というお話ですが、特に試す必要は無いと思います。 それより、サンプルコードが完成しているので、そちらを実行してみるのがいいと思います。 ❾ MainPage.xaml - Application Bar Sample 以下は以前書いた記事です ❿ 【解説】アプリケーションバーのメニュー項目のクリック / Windows Phone(C#)
    posted by lightbox at 2013-04-20 15:32 | Windows Phone | このブログの読者になる | 更新情報をチェックする

    2012年11月11日


    Windows Phone から Facebook に画像アップロード

    SkyDrive に移動
    
    
    アクセストークンは取得したという前提での処理です。アクセストークンは URL に含ませる仕様になっており、メッセージと画像データは一般的なものです。プライバシーの設定についてはまだ良く解りませんが、テスト後は友人のみ公開となっていました。
    
    ※ SkyDrive にはプロジェクト全体を書庫としてダウンロードできるようにしています。
    
    using System;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Ink;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using System.Windows.Media.Imaging;
    using System.IO;
    using System.Text;
    
    namespace WebPost
    {
    	public class ControlImageUpload
    	{
    		private WriteableBitmap _wb;
    
    		// イベント引き渡し用クラス
    		private class MyParam
    		{
    			public WebRequest wr;
    			public MemoryStream ms;
    			public string strBoundary;
    			public string file_name;
    
    			public MyParam()
    			{
    				wr = null;
    				ms = null;
    				strBoundary = null;
    				file_name = null;
    			}
    		}
    
    		// コンストラクター
    		public ControlImageUpload( WriteableBitmap wb)
    		{
    			_wb = wb;
    		}
    
    		public void UploadJpg( string url, string file_name, int quality=85 )
    		{
    
    			string strBoundary = DateTime.Now.Ticks.ToString("x");
    
    			MemoryStream stream = new MemoryStream();
    			_wb.SaveJpeg(stream, _wb.PixelWidth, _wb.PixelHeight, 0, quality);
    
    			WebRequest wr = HttpWebRequest.Create(url);
    
    			wr.Method = "POST";
    			wr.ContentType = "multipart/form-data; boundary=---" + strBoundary;
    
    			AsyncCallback writeCallBack = new AsyncCallback(WriteCallBack);
    			MyParam myParam = new MyParam() {
    				wr = wr,
    				ms = stream,
    				strBoundary = strBoundary,
    				file_name = file_name
    			};
    
    			// 要求開始
    			IAsyncResult iar1 = wr.BeginGetRequestStream(writeCallBack, myParam);
    		}
    
    		// 書き込み
    		private void WriteCallBack(IAsyncResult ar)
    		{
    			HttpWebRequest req = (HttpWebRequest)((MyParam)ar.AsyncState).wr;
    			MemoryStream stream = ((MyParam)ar.AsyncState).ms;
    			string strBoundary = ((MyParam)ar.AsyncState).strBoundary;
    			string file_name = ((MyParam)ar.AsyncState).file_name;
    
    			Stream rs = req.EndGetRequestStream(ar);
    
    			BinaryWriter sw = new BinaryWriter(rs);
    
    			Encoding encoding = Encoding.GetEncoding("iso-8859-1");
    			Byte[] content = encoding.GetBytes("-----" + strBoundary + "\r\n");
    			sw.Write(content, 0, content.Length);
    
    			content = encoding.GetBytes("Content-Disposition: post-data; name=\"message\"\r\n\r\n");
    			sw.Write(content, 0, content.Length);
    
    			Encoding encoding_utf8 = Encoding.GetEncoding("utf-8");
    			content = encoding_utf8.GetBytes("Windows Phone からアップロード\r\n");
    			sw.Write(content, 0, content.Length);
    
    			content = encoding.GetBytes("-----" + strBoundary + "\r\n");
    			sw.Write(content, 0, content.Length);
    
    			content = encoding.GetBytes("Content-Disposition: form-data; name=\"source\"; filename=\"" + file_name + "\"\r\n");
    			sw.Write(content, 0, content.Length);
    
    			content = encoding.GetBytes("Content-Type: image/jpeg\n");
    			sw.Write(content, 0, content.Length);
    
    			content = encoding.GetBytes("\r\n");
    			sw.Write(content, 0, content.Length);
    
    			sw.Write(stream.GetBuffer(), 0, stream.GetBuffer().Length);
    
    			content = encoding.GetBytes("\r\n-----" + strBoundary + "--\r\n");
    			sw.Write(content, 0, content.Length);
    
    			sw.Close();
    
    			AsyncCallback readCallBack = new AsyncCallback(this.ReadCallBack);
    			IAsyncResult iar2 = req.BeginGetResponse(readCallBack, req);
    
    		}
    
    		// 読み込み
    		private void ReadCallBack(IAsyncResult ar)
    		{
    
    			HttpWebRequest req = (HttpWebRequest)ar.AsyncState;
    			HttpWebResponse response = (HttpWebResponse)req.EndGetResponse(ar);
    
    			Encoding enc = System.Text.Encoding.GetEncoding("UTF-8");
    			StreamReader sr = new StreamReader(response.GetResponseStream(), enc);
    
    			string str = sr.ReadToEnd();
    			sr.Close();
    
    			// 完了後の UI スレッドへのアクセス
    			Deployment.Current.Dispatcher.BeginInvoke(() =>
    			{
    				// 内部のイベントの呼び出し
    				OnImageUploadResult(new ImageUploadArgs(str));
    			});
    		}
    
    		// カスタムイベント用引数
    		public class ImageUploadArgs : EventArgs
    		{
    			public ImageUploadArgs(string s)
    			{
    				message = s;
    			}
    			private string message;
    
    			public string Message
    			{
    				get { return message; }
    				set { message = value; }
    			}
    		}
    
    		// カスタムイベントハンドラの定義 ( EventHandler<T> )
    		public event EventHandler<ImageUploadArgs> ImageUploadResult;
    
    		// 外部へイベントを発行する為の内部メソッドの定義
    		protected virtual void OnImageUploadResult(ImageUploadArgs e)
    		{
    			EventHandler<ImageUploadArgs> handler = ImageUploadResult;
    
    			// イベントが外部で実装されている場合、そのイベントを呼び出す
    			if (handler != null)
    			{
    				handler(this, e);
    			}
    		}
    	}
    }
    
    
    関連する記事
    
    手動で Facebook API の 60日間の アクセストークンを取得する
    Windows Phone からカメラで撮影した画像を http でアップロードする
    Window Phone 内の画像ファイルを選択して別の画像ファイルとしてメディアライブラリーに保存
    
    
    
    タグ:C# Windows Phone
    posted by lightbox at 2012-11-11 04:06 | Windows Phone | このブログの読者になる | 更新情報をチェックする

    WebClient で2時間用アクセストークンを取得して60日間用に交換してFacebook に投稿する Windows Phone 用のコード

    SkyDrive に移動
    手動で Facebook API の 60日間の アクセストークンを取得する』を WebClient で記述したものです。実際は最後にユーザ情報を取得して、画面にユーザのプロファイル画像を表示しています。
    
    最後のユーザ情報は JSON で帰って来るので、Json.NET のライブラリを使用しています。
    
    ※ アクセストークンが取得できてしまえば、投稿はただの単純な POST です。
    
    アプリケーションとして実装していませんが、アクセストークンの期限が切れると投稿エラーになるので、その場合はログイン画面に移動して ApplicationSettings をクリアする必要があります。
    
    using System;
    using System.Collections.Generic;
    using System.Windows.Navigation;
    using Microsoft.Phone.Controls;
    
    using System.Diagnostics;
    
    using System.Windows;
    using System.Net;
    using Newtonsoft.Json.Linq;
    
    namespace WP_C_Sharp_Facebook1
    {
    	public partial class Login : PhoneApplicationPage
    	{
    	private WebClient webClient = new WebClient();
    		private WebClient webClient_me = new WebClient();
    
    		public Login()
    		{
    			InitializeComponent();
    
    			string url_target = String.Format(
    				"https://www.facebook.com/dialog/oauth/?redirect_uri=http://www.facebook.com/connect/login_success.html&response_type=token&client_id={0}&scope=user_about_me,user_photos,read_stream,publish_stream",
    				App.mainPage.ApplicationID);
    
    			// 認証ページへ遷移
    			webBrowser.Navigate(new Uri(url_target));
    		}
    
    		private void webBrowser_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
    		{
    			Debug.WriteLine("webBrowser_Navigated: {0}", e.Uri);
    
    			string url = e.Uri.ToString();
    			if (url.IndexOf("access_token") != -1)
    			{
    				Debug.WriteLine(url);
    				string target_line = url.Substring(url.IndexOf("access_token"));
    				string [] separators = new string[1];
    				separators[0] = "&";
    				string[] part_string = target_line.Split(separators, System.StringSplitOptions.RemoveEmptyEntries);
    
    				Dictionary<string,string> dic = new Dictionary<string,string>();
    				separators[0] = "=";
    				string[] part_values = null;
    				part_values = part_string[0].Split(separators, System.StringSplitOptions.RemoveEmptyEntries);
    				dic.Add(part_values[0], part_values[1]);
    				part_values = part_string[1].Split(separators, System.StringSplitOptions.RemoveEmptyEntries);
    				dic.Add(part_values[0], part_values[1]);
    
    
    		    webClient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(webClient_DownloadStringCompleted);
    				url = String.Format("https://graph.facebook.com/oauth/access_token?client_id={0}&client_secret={1}&grant_type=fb_exchange_token&fb_exchange_token={2}",
    					App.mainPage.ApplicationID,
    					App.mainPage.ApplicationSecret,
    					dic["access_token"]);
    
    				webClient.DownloadStringAsync(new Uri(url));
           		}
    
    		}
    
    	private void webClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
    	{
    	    if (e.Error != null)
    	    {
    		Deployment.Current.Dispatcher.BeginInvoke(() =>
    		{
    		    Debug.WriteLine(e.Error.Message);
    		});
    	    }
    	    else
    	    {
    		// プロパティにセット
    		string new_token_line = e.Result;
    				Debug.WriteLine(new_token_line);
    
    				string[] separators = new string[1];
    				separators[0] = "&";
    				string[] part_string = new_token_line.Split(separators, System.StringSplitOptions.RemoveEmptyEntries);
    
    				Dictionary<string, string> dic = new Dictionary<string, string>();
    				separators[0] = "=";
    				string[] part_values = null;
    				part_values = part_string[0].Split(separators, System.StringSplitOptions.RemoveEmptyEntries);
    				dic.Add(part_values[0], part_values[1]);
    				part_values = part_string[1].Split(separators, System.StringSplitOptions.RemoveEmptyEntries);
    				dic.Add(part_values[0], part_values[1]);
    
    				Debug.WriteLine(dic["access_token"]);
    
    				App.isolatedStore.Add("access_token", dic["access_token"]);
    
    				webClient_me.DownloadStringCompleted += new DownloadStringCompletedEventHandler(webClient_me_DownloadStringCompleted);
    				string url = String.Format("https://graph.facebook.com/me?access_token={0}",
    					dic["access_token"]);
    
    				webClient_me.DownloadStringAsync(new Uri(url));
    			}
    	}
    
    		private void webClient_me_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
    		{
    			if (e.Error != null)
    			{
    				Deployment.Current.Dispatcher.BeginInvoke(() =>
    				{
    					Debug.WriteLine(e.Error.Message);
    				});
    			}
    			else
    			{
    				Debug.WriteLine(e.Result);
    
    				JObject me = JObject.Parse(e.Result);
    
    				App.isolatedStore.Add("fb_name", me["name"].ToString());
    				App.isolatedStore.Add("fb_id", me["id"].ToString());
    				App.isolatedStore.Add(
    						"fb_image_url",
    						string.Format("https://graph.facebook.com/{0}/picture", me["id"].ToString())
    						);
    
    				Dispatcher.BeginInvoke(() =>
    				{
    					// 全ての処理が終わったのでメインページへ戻る
    					this.NavigationService.GoBack();
    
    				});
    			}
    		}
    
    	}
    }
    
    最初、Facebook SDK を使ってたんですが、ただログインして投稿するだけならコードは少し長くなりますが、する事は全く同じなので、全て自前のコードで記述しました。
    
    
    
    
    タグ:C# Windows Phone
    posted by lightbox at 2012-11-11 01:31 | Windows Phone | このブログの読者になる | 更新情報をチェックする

    2012年11月10日


    Windows Phone からカメラで撮影した画像を http でアップロードする

    SkyDrive へ移動
    
    
    カメラで撮影した画像を WEB 上へアップロードするアプリケーションですが、アップロード部分はクラス化しているのですぐ利用可能だと思います。
    
    エミュレータでは、カメラで撮影はダミー画像になりますが、実機の場合 Zune で接続していると、写真や音楽系のデバッグができないので以下のようにします。
    
    1) Zune でデバイスとPCを接続して同期接続にする
    2) Zune を終了させる
    
    C:\Program Files (x86)\Microsoft SDKs\Windows Phone\v7.1\Tools\WPConnect\x64\WPConnect.exe または C:\Program Files\Microsoft SDKs\Windows Phone\v7.1\Tools\WPConnect\x86\WPConnect.exe を実行する
    
    ControlImageUpload クラス
    
    画像をアップロードする為のクラスです。コンストラクタを二つ用意していますが、一つは JPEG フォーマットのストリームを渡して、Windows Phone 内での通常の画像を扱うのに使用します。もう一つは、WriteableBitmap を渡しますが、これは画面上のコントロールを WriteableBitmap(コントール名, null) でそのまま取得したものを内部で JPEG 化してアップロードしています。
    
    
    using System;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Ink;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using System.Windows.Media.Imaging;
    using System.IO;
    using System.Text;
    
    namespace WebPost
    {
    	public class ControlImageUpload
    	{
    		private WriteableBitmap _wb;
    		MemoryStream stream = new MemoryStream();
    
    		// イベント引き渡し用クラス
    		private class MyParam
    		{
    			public WebRequest wr;
    			public MemoryStream ms;
    			public string strBoundary;
    			public string file_name;
    
    			public MyParam()
    			{
    				wr = null;
    				ms = null;
    				strBoundary = null;
    				file_name = null;
    			}
    		}
    
    		// コンストラクター
    		public ControlImageUpload(WriteableBitmap wb, int quality = 85 )
    		{
    			_wb = wb;
    			_wb.SaveJpeg(stream, _wb.PixelWidth, _wb.PixelHeight, 0, quality);
    		}
    		public ControlImageUpload(Stream img_stream)
    		{
    			img_stream.CopyTo(stream);
    		}
    
    		public void UploadJpg( string url, string file_name )
    		{
    
    			string strBoundary = DateTime.Now.Ticks.ToString("x");
    
    			WebRequest wr = HttpWebRequest.Create(url);
    
    			wr.Method = "POST";
    			wr.ContentType = "multipart/form-data; boundary=---" + strBoundary;
    
    			AsyncCallback writeCallBack = new AsyncCallback(WriteCallBack);
    			MyParam myParam = new MyParam() {
    				wr = wr,
    				ms = stream,
    				strBoundary = strBoundary,
    				file_name = file_name
    			};
    
    			// 要求開始
    			IAsyncResult iar1 = wr.BeginGetRequestStream(writeCallBack, myParam);
    		}
    
    		// 書き込み
    		private void WriteCallBack(IAsyncResult ar)
    		{
    			HttpWebRequest req = (HttpWebRequest)((MyParam)ar.AsyncState).wr;
    			MemoryStream stream = ((MyParam)ar.AsyncState).ms;
    			string strBoundary = ((MyParam)ar.AsyncState).strBoundary;
    			string file_name = ((MyParam)ar.AsyncState).file_name;
    
    			Stream rs = req.EndGetRequestStream(ar);
    
    			BinaryWriter sw = new BinaryWriter(rs);
    
    			Encoding encoding = Encoding.GetEncoding("iso-8859-1");
    			Byte[] content = encoding.GetBytes("-----" + strBoundary + "\n");
    			sw.Write(content, 0, content.Length);
    
    			content = encoding.GetBytes("Content-Disposition: form-data; name=\"target\"; filename=\""+file_name+"\"\n");
    			sw.Write(content, 0, content.Length);
    
    			content = encoding.GetBytes("Content-Type: image/jpeg\n");
    			sw.Write(content, 0, content.Length);
    
    			content = encoding.GetBytes("\n");
    			sw.Write(content, 0, content.Length);
    
    			sw.Write(stream.GetBuffer(), 0, stream.GetBuffer().Length);
    
    			sw.Write("\n-----" + strBoundary + "--\n");
    
    			sw.Close();
    
    			AsyncCallback readCallBack = new AsyncCallback(this.ReadCallBack);
    			IAsyncResult iar2 = req.BeginGetResponse(readCallBack, req);
    
    		}
    
    		// 読み込み
    		private void ReadCallBack(IAsyncResult ar)
    		{
    
    			HttpWebRequest req = (HttpWebRequest)ar.AsyncState;
    			HttpWebResponse response = (HttpWebResponse)req.EndGetResponse(ar);
    
    			Encoding enc = System.Text.Encoding.GetEncoding("UTF-8");
    			StreamReader sr = new StreamReader(response.GetResponseStream(), enc);
    
    			string str = sr.ReadToEnd();
    			sr.Close();
    
    			// 完了後の UI スレッドへのアクセス
    			Deployment.Current.Dispatcher.BeginInvoke(() =>
    			{
    				// 内部のイベントの呼び出し
    				OnImageUploadResult(new ImageUploadArgs(str));
    			});
    		}
    
    		// カスタムイベント用引数
    		public class ImageUploadArgs : EventArgs
    		{
    			public ImageUploadArgs(string s)
    			{
    				message = s;
    			}
    			private string message;
    
    			public string Message
    			{
    				get { return message; }
    				set { message = value; }
    			}
    		}
    
    		// カスタムイベントハンドラの定義 ( EventHandler<T> )
    		public event EventHandler<ImageUploadArgs> ImageUploadResult;
    
    		// 外部へイベントを発行する為の内部メソッドの定義
    		protected virtual void OnImageUploadResult(ImageUploadArgs e)
    		{
    			EventHandler<ImageUploadArgs> handler = ImageUploadResult;
    
    			// イベントが外部で実装されている場合、そのイベントを呼び出す
    			if (handler != null)
    			{
    				handler(this, e);
    			}
    		}
    	}
    }
    
    
    関連する記事
    
    Windows Phone の実行画面(自分のアプリのみ)をJPG化してWEBにPOSTするサンプル
    
    
    
    タグ:Windows Phone C#
    posted by lightbox at 2012-11-10 22:05 | Windows Phone | このブログの読者になる | 更新情報をチェックする

    Window Phone 内の画像ファイルを選択して別の画像ファイルとしてメディアライブラリーに保存

    
    
    カメラで撮影した画像も含めて、PhotoChooserTask で読みだす事ができますが、他の操作に使う場合は Memory Stream にコピーする必要も出て来るので、その方法を介した保存方法と二段構えのサンプルです。
    ( 一応、画像は JPEG 形式であるという前提です )
    
    単に選択した画像を XAML の画面に表示したいだけならば、e.ChosenPhoto を BitmapImage にして Source プロパティにセットします。
    
    SavePicture メソッドは、Picture オブジェクトなので、GetImage メソッドで再びストリームを取得できます。( GetThumbnail メソッドもあります )
    
    SavePicture に渡されるストリームは、JPEG 形式である必要があるので、BitmapImage の SetSource メソッドで渡すストリームも JPEG 形式で問題無いようです。
    
    ※ CameraCaptureTask で撮影した画像のストリームも JPEG 形式です
    
    public partial class MainPage : PhoneApplicationPage
    {
    	PhotoChooserTask pct = new PhotoChooserTask();
    
    	public MainPage()
    	{
    		InitializeComponent();
    
    		pct.Completed += new EventHandler<PhotoResult>(task_Completed);
    		pct.ShowCamera = true;
    	}
    
    	private void btnLoad_Click(object sender, EventArgs e)
    	{
    		// 画像選択
    		pct.Show();
    	}
    
    	void task_Completed(object sender, PhotoResult e)
    	{
    		if (e.TaskResult != TaskResult.OK)
    		{
    			return;
    		}
    
    		// Microsoft.Xna.Framework.Media
    		// ※ メディアライブラリーにストリームから直接保存
    		using (MediaLibrary ml = new MediaLibrary())
    		{
    			Picture pic = ml.SavePicture("DirectPictureSave1_" + DateTime.Now.ToString("yyyyMMddhhmmss"), (Stream)e.ChosenPhoto);
    		}
    
    		// メモリストリームにコピーしてから保存
    		MemoryStream ms = new MemoryStream();
    		((Stream)e.ChosenPhoto).Seek(0, SeekOrigin.Begin);	// Stream を最初に
    		((Stream)e.ChosenPhoto).CopyTo(ms);	// Memory Stream にコピー
    
    		// Microsoft.Xna.Framework.Media
    		// ※ メディアライブラリーに保存
    		using (MediaLibrary ml = new MediaLibrary())
    		{
    			Picture pic = ml.SavePicture("DirectPictureSave2_" + DateTime.Now.ToString("yyyyMMddhhmmss"), ms.GetBuffer());
    			// 選択した画像を表示する
    			BitmapImage bmp = new BitmapImage();
    //				bmp.SetSource(pic.GetThumbnail());
    			// Picture オブジェクトより、ストリームを取得
    			bmp.SetSource(pic.GetImage());
    			imgPhoto.Source = bmp;
    
    			MessageBox.Show("保存しました");
    		}
    
    	}
    
    }
    
    
    JPEG のストリームを デコードする必要がある場合は
    WriteableBitmap wb = PictureDecoder.DecodeJpeg(ストリーム);
    として WriteableBitmap を取得する事ができます
    
    
    
    タグ:C# Windows Phone
    posted by lightbox at 2012-11-10 19:37 | Windows Phone | このブログの読者になる | 更新情報をチェックする

    2012年11月01日


    Windows Phone の実行画面(自分のアプリのみ)をJPG化してWEBにPOSTするサンプル

    この画面をアップロードします。
    
    
    
    POST された画像はこちらです。
    
    
    
    ごく普通の Boundary を使ったバイナリアップロードです。
    最後に、UI スレッドへ結果を通知する為に Deployment.Current.Dispatcher.BeginInvoke を使用しています。
    
    Windows Phone まとめリンク
    
    Windows Phone
    
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using Microsoft.Phone.Controls;
    
    using System.Diagnostics;
    using System.IO;
    using System.Windows.Media.Imaging;
    using System.Text;
    using System.Threading;
    using System.Windows.Threading;
    
    namespace WebPost
    {
    	public partial class MainPage : PhoneApplicationPage
    	{
    
    		// コンストラクター
    		public MainPage()
    		{
    			InitializeComponent();
    		}
    
    		// イベント引き渡し用クラス
    		private class MyParam
    		{
    			public WebRequest wr;
    			public MemoryStream ms;
    			public string strBoundary;
    
    			public MyParam()
    			{
    				wr = null;
    				ms = null;
    				strBoundary = null;
    			}
    		}
    
    		IAsyncResult iar2 = null;
    
    		// 書き込み
    		public void WriteCallBack(IAsyncResult ar)
    		{
    			Debug.WriteLine("WriteCallBack");
    
    			HttpWebRequest req = (HttpWebRequest)((MyParam)ar.AsyncState).wr;
    			MemoryStream stream = ((MyParam)ar.AsyncState).ms;
    			string strBoundary = ((MyParam)ar.AsyncState).strBoundary;
    
    			Stream rs = req.EndGetRequestStream(ar);
    
    			BinaryWriter sw = new BinaryWriter(rs);
    
    			Encoding encoding = Encoding.GetEncoding("iso-8859-1");
    			Byte[] content = encoding.GetBytes("-----"+strBoundary+"\n");
    			sw.Write( content,0 , content.Length );
    
    			content = encoding.GetBytes("Content-Disposition: form-data; name=\"target\"; filename=\"LayoutRoot.jpg\"\n");
    			sw.Write( content,0 , content.Length );
    
    			content = encoding.GetBytes("Content-Type: image/jpeg\n");
    			sw.Write( content,0 , content.Length );
    
    			content = encoding.GetBytes("\n");
    			sw.Write( content,0 , content.Length );
    
    			sw.Write(stream.GetBuffer(), 0, stream.GetBuffer().Length);
    
    			sw.Write("\n-----" + strBoundary + "--\n");
    
    			sw.Close();
    
    			AsyncCallback readCallBack = new AsyncCallback(this.ReadCallBack);
    			IAsyncResult iar2 = req.BeginGetResponse(readCallBack, req);
    
    		}
    
    
    		// 読み込み
    		public void ReadCallBack(IAsyncResult ar)
    		{
    
    			HttpWebRequest req = (HttpWebRequest)ar.AsyncState;
    			HttpWebResponse response = (HttpWebResponse)req.EndGetResponse(ar);
    
    			Encoding enc = System.Text.Encoding.GetEncoding("UTF-8");
    			StreamReader sr = new StreamReader(response.GetResponseStream(), enc);
    
    			string str = sr.ReadToEnd();
    			Debug.WriteLine(str);
    			sr.Close();
    
    			// 完了後の UI スレッドへのアクセス
    			Deployment.Current.Dispatcher.BeginInvoke(() =>
    			{
    				MessageBox.Show("送信しました");
    			});
    
    		}
    
    		// 送信
    		private void button1_Click_1(object sender, RoutedEventArgs e)
    		{
    			string strBoundary = DateTime.Now.Ticks.ToString("x");
    
    			WriteableBitmap wb = new WriteableBitmap(LayoutRoot, null);
    			MemoryStream stream = new MemoryStream();
    			wb.SaveJpeg(stream, wb.PixelWidth, wb.PixelHeight, 0, 85);
    
    			WebRequest wr = HttpWebRequest.Create("http://localhost/php_json/up.php");
    
    			wr.Method = "POST";
    			wr.ContentType = "multipart/form-data; boundary=---" + strBoundary;
    
    			AsyncCallback writeCallBack = new AsyncCallback(WriteCallBack);
    			MyParam myParam = new MyParam() { wr = wr, ms = stream, strBoundary = strBoundary };
    
    			IAsyncResult iar1 = wr.BeginGetRequestStream(writeCallBack, myParam);
    
    		}
    
    
    	}
    }
    
    関連する記事
    
    VBScript を使って HTTPプロトコルで PHP へファイルをアップロードする方法
    
    ファイルのアップロード時のデータのダンプ
    
    
    ▼ 受け取り側の PHP です
    
    <HTML>
    <HEAD>
    <META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=utf-8">
    </HEAD>
    <BODY>
    <FORM 
    	enctype="multipart/form-data"
    	method="POST"
    >
     
    	アップロードするファイル : 
    	<INPUT name="target" type="file" style='width:400'>
    	<INPUT type="submit" value="アップロード">
     
    </FORM>
    <PRE>
    <?
    if ( $_SERVER['REQUEST_METHOD'] == "POST" ) {
     
    	$upload = realpath("./");
    	$upload .= ( DIRECTORY_SEPARATOR . $_FILES['target']['name'] );
    
    	print $upload;
    
    	if ( move_uploaded_file(
    		$_FILES['target']['tmp_name'], $upload ) ) {
    		print "アップロードに成功しました<br>\n";
    	}
    
    	print_r( $_FILES );
    }
    
    ?>
    </PRE>
    </BODY></HTML>
    
    
    
    
    
    posted by lightbox at 2012-11-01 23:45 | Windows Phone | このブログの読者になる | 更新情報をチェックする

    2012年10月27日


    Windows Phone(C#) のデータバインドを Json.NET を使って一行で実装する( しかも XML を JSON 変換して使う )

    以下の画像はこのブログの index20.rdf を表示しています
    
    
    
    SkyDrive に移動
    
    
    サンプルは、2ページ仕様で表示していますが、1ページ目の内容を再度表示しているだけです。重要なのは、Json.NET の使い方と、その為のバインド用のクラスの作成方法です。
    
    ※ データは NAVER まとめのデータを利用してテストしています
    ※ 結果をアプリからの投稿用の『超簡易掲示板』を使用して JSON 文字列を書き込んでいます
    
    Windows Phone まとめリンク
    
    Windows Phone
    
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using Microsoft.Phone.Controls;
    
    using System.Diagnostics;
    using Newtonsoft.Json;
    using Newtonsoft.Json.Linq;
    using System.Xml.Linq;
    using Microsoft.Phone.Tasks;
    
    namespace DataBound_ListBox_JSON
    {
    	public partial class MainPage : PhoneApplicationPage
    	{
    		// コンストラクター
    		public MainPage()
    		{
    			InitializeComponent();
    
    			// ListBox コントロールのデータ コンテキストをサンプル データに設定します
    			DataContext = App.ViewModel;
    			this.Loaded += new RoutedEventHandler(MainPage_Loaded);
    
    			App.mainPage = this;
    
    		}
    
    		private void webClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
    		{
    			if (e.Error != null)
    			{
    				Deployment.Current.Dispatcher.BeginInvoke(() =>
    				{
    					Debug.WriteLine(e.Error.Message);
    				});
    			}
    			else
    			{
    				JObject RSS = null;
    				JArray jsonItems = null;
    				string json_string = null;
    				int rowMax = 0;
    
    				// XML 文字列を dom に変換
    				XDocument dom = XDocument.Parse(e.Result);
    
    				// dom を JSON 文字列に変換
    				json_string = JsonConvert.SerializeXNode(dom.FirstNode);
    
    				// JSON 文字列を JSON 表現可能な JObject に変換
    				RSS = JObject.Parse(json_string);
    
    				// 対象となる item の数を得る
    				jsonItems = (JArray)RSS["rss"]["channel"]["item"];
    
    				// **********************************
    				// ここからテスト確認用はじまり
    				// **********************************
    				rowMax = jsonItems.Count;
    				// トップから一覧表示
    				for (int i = 0; i < rowMax; i++)
    				{
    					Debug.WriteLine(RSS["rss"]["channel"]["item"][i]["title"]);
    					Debug.WriteLine(RSS["rss"]["channel"]["item"][i]["description"]);
    					Debug.WriteLine(RSS["rss"]["channel"]["item"][i]["link"]);
    				}
    
    				Debug.WriteLine("----------------------------------");
    
    				// 必要部分のみ(item)を JSON 文字列に戻す
    				json_string = JsonConvert.SerializeObject(jsonItems);  // 必要なのはここだけ
    				json_string = "{ item: " + json_string + "}";
    
    				RSS = JObject.Parse(json_string);
    
    				// 対象のみ
    				for (int i = 0; i < rowMax; i++)
    				{
    					Debug.WriteLine(RSS["item"][i]["title"]);
    					Debug.WriteLine(RSS["item"][i]["description"]);
    					Debug.WriteLine(RSS["item"][i]["link"]);
    				}
    
    				WebClientPost.LogPost("http://localhost/php_json/log.php", json_string);
    				// **********************************
    				// ここまでテスト確認用の終わり
    				// **********************************
    
    
    				// **********************************
    				// バインドは以下の一行で完了
    				// **********************************
    				App.ViewModel = JsonConvert.DeserializeObject<MainViewModel>(json_string);
    				// データコンテキスト設定
    				DataContext = App.ViewModel;
    
    
    				// ロード済のフラグをセット
    				App.ViewModel.IsDataLoaded = true;
    			}
    		}
    
    		// ListBox で変更された選択項目を処理します
    		private void MainListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    		{
    			// 選択されたインデックスが -1 の場合 (選択されていない場合) は何も行いません
    			if (MainListBox.SelectedIndex == -1)
    				return;
    
    			// 新しいページに移動します
    			NavigationService.Navigate(
    				new Uri("/DetailsPage.xaml?selectedItem=" + MainListBox.SelectedIndex, UriKind.Relative)
    				);
    
    			// 選択されたインデックスを -1 (選択されていない) にリセットします
    			MainListBox.SelectedIndex = -1;
    		}
    
    		// ViewModel Items のデータを読み込みます
    		private void MainPage_Loaded(object sender, RoutedEventArgs e)
    		{
    			if (!App.ViewModel.IsDataLoaded)
    			{
    				LoadData();
    			}
    		}
    
    		public void LoadData()
    		{
    
    			if (App.ViewModel.IsDataLoaded)
    			{
    				App.ViewModel.item.Clear();
    			}
    
    			WebClient webClient = new WebClient();
    			webClient.DownloadStringCompleted +=
    				new DownloadStringCompletedEventHandler(webClient_DownloadStringCompleted);
    			// 外部サービスから文字列を取得
    			webClient.DownloadStringAsync(new System.Uri("http://matome.naver.jp/feed/hot"));
    		}
    
    	}
    }
    
    関連する記事
    
    PHP による『超簡易掲示板』 / アブリケーションからの POST 検証用
    
    
    
    タグ:JSON
    posted by lightbox at 2012-10-27 23:29 | Windows Phone | このブログの読者になる | 更新情報をチェックする

    2012年10月21日


    WindowsPhone からの単純なインターネット投稿

    SkyDrive へ移動
    
    WebClientPost.cs
    
    WebClientPost.LogPost("http://localhost/lightbox/test/log.php", json_string);
    
    PHP による『超簡易掲示板』 / アブリケーションからの POST 検証用 を使用して外部ログとして利用できます。( Debug.WriteLine だととても長い文字列を簡単に取得できません )
    
    
    using System;
    using System.Net;
    using System.Windows;
    
    public class WebClientPost
    {
    	public static void LogPost(string url,string value){
    
    		WebClient HttpClient = new WebClient();
    
    		// ダウンロード完了後に呼び出されるイベントハンドラを設定
    		HttpClient.UploadStringCompleted += new UploadStringCompletedEventHandler(HttpPostCompleted);
    
    		// POST 用 Http ヘッダの設定
    		HttpClient.Headers["Content-Type"] = "application/x-www-form-urlencoded";
    
    		string data_string = "send=send&text=" + Uri.EscapeDataString(value);
    		HttpClient.UploadStringAsync(new Uri(url), "POST", data_string);
    
    	}
    
    	static void HttpPostCompleted(object sender, UploadStringCompletedEventArgs e)
    	{
    		if (e.Error == null)
    		{
    			MessageBox.Show("送信しました");
    		}
    		else
    		{
    			MessageBox.Show("通信エラーが発生しました。\r\n" + e.Error.Message);
    		}
    	}
    
    }
    
    
    関連する記事
    
    PHP による『超簡易掲示板』 / アブリケーションからの POST 検証用
    
    
    
    posted by lightbox at 2012-10-21 19:45 | Windows Phone | このブログの読者になる | 更新情報をチェックする

    Json.NET を使って、XML データを JSON に変換して利用する / Windows Phone(C#)

    using System.Xml.Linq が必要です。このサンプルでは、JObject を作成してループ処理していますが、実際は item 以下の JSON 文字列を作成して、JsonConvert.DeserializeObject を使って C# のクラスのインスタンスを作成します。
    
    その クラスのインスタンスを DataContext に設定してバインドする事によって自動的に ListBox の表示が可能になります。
    
    JObject RSS = null;
    JArray jsonItems = null;
    string json_string = null;
    int rowMax = 0;
    
    // XML 文字列を dom に変換
    XDocument dom = XDocument.Parse(e.Result);
    
    // dom を JSON 文字列に変換
    json_string = JsonConvert.SerializeXNode(dom.FirstNode);
    
    // JSON 文字列を JSON 表現可能な JObject に変換
    RSS = JObject.Parse(json_string);
    
    // 対象となる item の数を得る
    jsonItems = (JArray)RSS["rss"]["channel"]["item"];
    rowMax = jsonItems.Count;
    // トップから一覧表示
    for (int i = 0; i < rowMax; i++)
    {
    	Debug.WriteLine(RSS["rss"]["channel"]["item"][i]["title"]);
    	Debug.WriteLine(RSS["rss"]["channel"]["item"][i]["description"]);
    	Debug.WriteLine(RSS["rss"]["channel"]["item"][i]["link"]);
    }
    
    Debug.WriteLine("----------------------------------");
    
    // 必要部分のみ(item)を JSON 文字列に戻す
    json_string = JsonConvert.SerializeObject(jsonItems);
    json_string = "{ item: " + json_string + "}";
    
    RSS = JObject.Parse(json_string);
    
    // 対象のみ
    for (int i = 0; i < rowMax; i++)
    {
    	Debug.WriteLine(RSS["item"][i]["title"]);
    	Debug.WriteLine(RSS["item"][i]["description"]);
    	Debug.WriteLine(RSS["item"][i]["link"]);
    }
    
    
    
    
    
    タグ:JSON
    posted by lightbox at 2012-10-21 01:36 | Windows Phone | このブログの読者になる | 更新情報をチェックする

    2012年09月29日


    WebClient で取得したデータを元に、コントロールの表示状態を変更する / Windows Phone(C#)

    
    
    内容は、『WebClient でページのタイトルを WEB から取得して表示する / Windows Phone(C#)』と同じですが、チェックボックスは変更可能なコントロールなので、TwoWay に設定して、画面から変更した場合に Class1 のプロパティにデータがセットされる事を確かめるようにしています。
    
    もし、このセットする部分に Web 経由でデータを POST すれば、受け取った PHP 等がサーバにデータを保存する事が可能になります。
    
    MainPage.xaml 全体のソースコード
    
    ▼ 主要部分
    
    <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
    	<CheckBox
    		Content="CheckBox Setting"
    		Height="Auto"
    		HorizontalAlignment="Left"
    		Margin="60,20,0,0"
    		Name="checkBoxSetting"
    		VerticalAlignment="Top"
    		IsChecked="{
    			Binding
    			Source={StaticResource class1},
    			Path=CheckBoxSetting,
    			Mode=TwoWay
    		}"/>
    
    </Grid>
    
    
    
    Class1.cs 全体のソースコード
    
    ▼ 主要部分
    
    // チェックボックス用プロパティ
    // ※ TwoWay でセットされる様子をチェックする為にコードを記述しています
    private bool _CheckBoxSetting;
    public bool CheckBoxSetting {
    	get {
    		return _CheckBoxSetting;
    	}
    	set {
    		_CheckBoxSetting = value;
    		Debug.WriteLine("CheckBoxSetting にデータがセットされました" + value);
    	} 
    }
    
    public Class1()
    {
    
    	WebClient webClient = new WebClient();
    
    	webClient.DownloadStringCompleted += 
    		new DownloadStringCompletedEventHandler(webClient_DownloadStringCompleted);
    	// 外部サービスから文字列を取得
    	webClient.DownloadStringAsync(new System.Uri("http://textt.net/sworc/20120925064853.txt"));
    }
    
    private void webClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
    {
    	if (e.Error != null)
    	{
    		Deployment.Current.Dispatcher.BeginInvoke(() =>
    		{
    			Debug.WriteLine(e.Error.Message);
    		});
    	}
    	else
    	{
    		// プロパティにセット
    		this.CheckBoxSetting = bool.Parse(e.Result);
    		NotifyPropertyChanged("CheckBoxSetting");
    	}
    }
    
    
    ▼ True という文字列を返します
    http://textt.net/sworc/20120925064853.txt
    
    
    
    posted by lightbox at 2012-09-29 15:10 | Windows Phone | このブログの読者になる | 更新情報をチェックする
    Seesaa の各ページの表示について
    Seesaa の 記事がたまに全く表示されない場合があります。その場合は、設定> 詳細設定> ブログ設定 で 最新の情報に更新の『実行ボタン』で記事やアーカイブが最新にビルドされます。
    
    Seesaa のページで、アーカイブとタグページは要注意です。タグページはコンテンツが全く無い状態になりますし、アーカイブページも歯抜けページはコンテンツが存在しないのにページが表示されてしまいます。
    
    また、カテゴリページもそういう意味では完全ではありません。『カテゴリID-番号』というフォーマットで表示されるページですが、実際存在するより大きな番号でも表示されてしまいます。
    
    ※ インデックスページのみ、実際の記事数を超えたページを指定しても最後のページが表示されるようです
    
    対処としては、このようなヘルプ的な情報を固定でページの最後に表示するようにするといいでしょう。具体的には、メインの記事コンテンツの下に『自由形式』を追加し、アーカイブとカテゴリページでのみ表示するように設定し、コンテンツを用意するといいと思います。
    
    
    ※ エキスパートモードで表示しています
    
    アーカイブとカテゴリページはこのように簡単に設定できますが、タグページは HTML 設定を直接変更して、以下の『タグページでのみ表示される内容』の記述方法で設定する必要があります
    
    
    <% if:page_name eq 'archive' -%>
    アーカイブページでのみ表示される内容
    <% /if %>
    
    <% if:page_name eq 'category' -%>
    カテゴリページでのみ表示される内容
    <% /if %>
    
    <% if:page_name eq 'tag' -%>
    タグページでのみ表示される内容
    <% /if %>
    
    この記述は、以下の場所で使用します


    Windows
    container 終わり

    フリーフォントで簡単ロゴ作成
    フリーフォントでボタン素材作成
    フリーフォントで吹き出し画像作成
    フリーフォントではんこ画像作成
    ほぼ自由に利用できるフリーフォント
    フリーフォントの書体見本とサンプル
    画像を大きく見る為のウインドウを開くボタンの作成

    Android SDK ポケットリファレンス
    改訂版 Webデザイナーのための jQuery入門
    今すぐ使えるかんたん ホームページ HTML&CSS入門
    CSS ドロップシャドウの参考デモ
    PHP正規表現チェッカー
    Google Hosted Libraries
    cdnjs
    BUTTONS (CSS でボタン)
    イラストAC
    ぱくたそ
    写真素材 足成
    フリーフォント一覧
    utf8 文字ツール
    右サイド 終わり
    base 終わり