Windows 8.1 Update の内容をざっと

Microsoft Build Developer Conference | April 2 – 4, 2014
http://www.buildwindows.com/ 
Channel 9: Videos about the people building Microsoft Products & Services
http://channel9.msdn.com/#videoHolder

のネタ的に記念に。Windows 8.1 Update は 4/8 にダウンロードできるそうなので、特別な理由がない限りわざわざ MSDN からダウンロードする必要はないのですが。一応、VMWare の Windows 8.1 に入れて試してみました。MSDN からスタンドアローンのアップデートをするときは、解凍した後で ReadMe.txt にインストールの順番が書いてあるのでそれで。私の環境では、 KB2919442 が適用済みだったので大丈夫ですが、エクスプローラーで一番上から(KB番号が若い順)インストールすると嵌るかもしれません。先頭の2つのKBだけが順序が逆なので。

以下は、デスクトップPC に Windows 8.1 Update を入れたときの話。

ちなみに目玉(?)の機能っぽい、スタートメニューのタイル化と、ストアアプリのウィンドウ化は、今回の Windows 8.1 Update には入っていません。ストアアプリのウィンドウ化は、サードパティが商品化していたのでそれの寿命が尽きるのか…とも思われますが、どうなんでしょう?

http://buchizo.files.wordpress.com/2014/04/image28.png

普通に Windows 8.1 を使っている限りはあまり、いらんかなーという感じなのですが、マウスを上に持ってくると Windows デスクトップアプリのようにタイトルと、閉じるボタンが出ます。「_」が最小化ボタンで、「×」が閉じるボタンですね。ツールチップはでませんが。

image

左上のコントロールボックス(という名前だったはず)をクリックするとおなじみのメニューが出ます。ここで「最小化」と「閉じる」が選べますね。実は、「最小化」がアプリを閉じる(中断)で、「閉じる」がアプリが終了なんですが…まあ、英語版の場合は「Minimize」「Close」だから、こっちのほうがいいかも。「最大化」は、画面分割をしている状態だと、全画面に最大化されます。意味合いはあってますね。コントロールボックスをダブルクリックすると、ストアプリが終了できるのは、デスクトップアプリと同じです。分割した状態では「最大化」と「最小化」、「閉じる」しかないので、右に動かしたり左に動かしたりするのはマウスでやることになります。残念…と思ったけど、以下の Alt+Space で動かせます。

image

image

ちなみに、このコントロールボックスは、Alt+Space で出せます。デスクトップからの継承なので統一感はばっちりですね(誉めてます)。あと、Alt+F4 でストアアプリを終了できます。これは、Windows 8.1 でもある機能です(というのをさっき初めて確認しました)

さて、ヘルプを見ると Windows 8.1 の操作があるのですが、残念、アプリの終了方法はドラッグする方法しか書いてありません。これはヘルプのアップデート待ちかと…って、これをアップデートしてたらすごいぞッ!!! 品質的に。4/8 以降のストアアプリのアップデートで、更新されるのかな?

image

おなじみのデスクトップに戻ると、おなじみのスタートボタンの横に「ストア」ボタンが表示されます。ええ、ストアアプリもタスクバーに置かれるようになったので、ここからもストアを起動できます。そういえば、Microsoft の記事に「Window 8 では、ほとんどのユーザーが24時間以内にストアを見つけることができましたッ!!!」とあったので、結構気にしていたんですね。24時間じゃ遅いよッ!!! チャームとかだと全然見つかりません。なわけで、iPad みたく、AppleStore のアイコンを置くわけですよ。いや、正直言って邪魔なので「タスクバーからピン留めを外す」で消え去ってもらう訳ですが、ユーザー的にはデスクトップにアイコンを置く「ゴミ箱の横あたりに置く」ぐらいのずうずうしさは必要かも。慎ましやかですね。

image

さて、ストアアプリがタスクバーに置かれると何が便利かというと、こんな感じでプレビューが出ます。Update 前は、ストアアプリの場合は左のタスクバー(だっけ?)で確認、デスクトップアプリの場合はタスクバーで確認と分かれていたのですが、Update 以後はタスクバーで一括してプレビューが確認できます。便利ですね。

image

でもって、このタスクバー。不便なところもあって、いままでゲームのストアアプリを立ち上げて、おいてボスが来たら Win+D キー一発でデスクトップに戻れたのですが(昔懐かしのボス機能です)、Update 以後はタスクバーにゲームのアイコンが残ってしまうのでばれてしまいますね。注意したいところです。今後はどうするのがいいでしょうか?これはサポートセンターに問い合わせ…ても答えてくれないと思いまふ。

と思ったら、「Windows ストアアプリをタスクバーに表示する」のチェックを外せばよいとのこと。なるほど。Surface RT のようなタブレットの場合は、逆にこのチェックが OFF になっているので、ON にすれば表示されるようになります。

image

ちなみに、今気づいたのですが、Win+T でタスクのタスクの切り替えもストアアプリ込みになります。いままで、Alt+Tab を使うか、Win+Tab でストアアプリだけ、という感じだったので意外と便利かもしれません。いや、マウスでぽちぽちやるために機能追加なのでしょうが、副産物として。

正直、トリプルディスプレイで使っている身としては、ストアアプリのウィンドウ化はあまり必要ないのですが、シングルのノートブックでやっているときは便利なのかなぁ。Alt+Tab で全画面切り替えを普通にやるので、いまひとつ私にはメリットがありません。Windows 8 のデザイン的に、ストアアプリは全画面(あるいは縦長のスナップ)が標準になっているので、デスクトップにウィンドウが出るとしても補助的なものかと。本格的に画面にマッチさせるには、WPFで作るかWindowsフォームになりますよね。そのあたり手軽なウィジットが無くなったので、この穴を埋めるのは誰/何だろう、って気もしてます。まだ、Adobe Air なのかなとか。ああ、Silverlight on Desktop があったはずですがアレは何処行ったんでしょう。ちなみ、Silverlight 自体は、Silverlight 8.1 となって戻ってくるそうなので 藍澤光 http://www.microsoft.com/taiwan/silverlight/ が戻ってくるかも?というか、8人姉妹?それとも8.1人姉妹?

カテゴリー: windows 8.1 | Windows 8.1 Update の内容をざっと はコメントを受け付けていません

Xamarinでコントロールのドラッグに対応する

いわゆる画像をドラッグします。本来はこれがやりたかったのですが、プラットフォームごとに微妙に違うので断念。どうせ C# で言語をそろえるので拡張メソッドが適当なヘルパークラスを作れば統一できそうです。

■Windows ストアアプリの場合

ManipulationDelta を使う。

<Canvas 
    x:Name="canvas"
    ManipulationDelta="canvas_ManipulationDelta"
    HorizontalAlignment="Left" Height="564" Margin="80,10,0,0" Grid.Row="1" VerticalAlignment="Top" Width="1200">
    <Ellipse 
        x:Name="circle"
        ManipulationMode="All"
        Fill="#FF4CE035" Height="100" Canvas.Left="133" Stroke="Black" Canvas.Top="63" Width="100" 
        />
</Canvas>

Canvas で ManipulationDeltaイベントを設定してして、ドラッグ対象のコントロールに ManipulationMode=”All” を指定します。

private void canvas_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
    var el = e.OriginalSource as UIElement;
    var cir = el as Ellipse;
    double x = Canvas.GetLeft(el) + e.Delta.Translation.X;
    double y = Canvas.GetTop(el) + e.Delta.Translation.Y;
    // 画面からはみ出ないようにする
    if (-cir.ActualWidth / 2 <= x &&
        x <= canvas.ActualWidth - cir.ActualWidth / 2 &&
        -cir.ActualHeight / 2 <= y &&
        y <= canvas.ActualHeight - cir.ActualHeight / 2)
    {
        Canvas.SetLeft(el, x);
        Canvas.SetTop(el, y);
    }
}

ManipulationDelta イベントでは、対象のオブジェクトと移動距離が取れるのでこれを使って位置を移動します。Canvas上に乗せているので、位置指定は Canvas.SetLeft と Canvas.SetTop を使います。

■Androidの場合

Touch イベントを使います。Touch イベントで、DOWN/MOVE/UP が取れるので、これで対象のコントロール(ウィジット)を移動させます。

protected override void OnCreate(Bundle bundle)
{
    base.OnCreate(bundle);

    // Set our view from the "main" layout resource
    SetContentView(Resource.Layout.Main);

    // Get our button from the layout resource,
    // and attach an event to it
    this.iv1 = FindViewById(Resource.Id.imageView1);
    this.iv2 = FindViewById(Resource.Id.imageView2);
    this.iv1.SetImageResource(Resource.Drawable.MarkBlue);
    this.iv2.SetImageResource(Resource.Drawable.MarkBlue);
    this.text1 = FindViewById(Resource.Id.textView1);
    iv1.Touch += iv1_Touch;
    iv2.Touch += iv1_Touch;
}

bool moveFlag = false;
float _sx, _sy;
void iv1_Touch(object sender, View.TouchEventArgs e)
{
    var el = sender as ImageView;
    if (el == null) return;

    float x = e.Event.RawX;
    float y = e.Event.RawY;

    switch (e.Event.Action)
    {
    case MotionEventActions.Down:
        _sx = x - el.Left;
        _sy = y - el.Top;
        moveFlag = true;
        break;
    case MotionEventActions.Move:
        if (moveFlag)
        {
            int left = (int)(x - _sx);
            int top = (int)(y - _sy);
            el.Layout(left, top,
                left + el.Width,
                top + el.Height);
        }
        break;  
    case MotionEventActions.Up:
        moveFlag = false;
        break;
    }
}

framelayout にコントロールを乗せておけば、Layout メソッドで位置指定ができます。

■iOSの場合

ドラッグするコントロールを継承する方法もあるのですが、ViewControllerでまとめて操作してみます。TouchesBegan、TouchesMoved、TouchesEnded をオーバーライドします。

    
UIImageView dragItem = null;
/// タッチ開始
public override void TouchesBegan(NSSet touches, UIEvent evt)
{
    base.TouchesBegan(touches, evt);
     UITouch touch = touches.AnyObject as UITouch;
     foreach (var el in this.drags) {
        if (el.Frame.Contains (touch.LocationInView (View))) {
            this.dragItem = el;
            break;
        }
    }
}
/// タッチ移動
public override void TouchesMoved(NSSet touches, UIEvent evt)
{
    base.TouchesMoved(touches, evt);
    UITouch touch = touches.AnyObject as UITouch;
    PointF newPoint = touch.LocationInView(View);
    PointF previousPoint = touch.PreviousLocationInView(View);
    if (dragItem != null ) {
        float offsetX = previousPoint.X - newPoint.X;
        float offsetY = previousPoint.Y - newPoint.Y;
        dragItem.Frame = new RectangleF (
            new PointF (dragItem.Frame.X - offsetX, dragItem.Frame.Y - offsetY),
            dragItem.Frame.Size);
    }
}
/// タッチ終了
public override void TouchesEnded (NSSet touches, UIEvent evt)
{
    base.TouchesEnded (touches, evt);
    dragItem = null;
}

TouchesMoved メソッドで、コントロールの移動前と移動後が取れるので、これを使ってコントロールを移動させます。移動したコントロールの判別を Frame.Contains で使っているのがいいまいちなのですが。

それぞれドラッグイベントの取得の仕方が微妙に違うので、ややこしいです。

  • Windows ストアアプリの場合は、ドラッグ対象にフラグを設定して、コンテナでイベント取得
  • Androidの場合は、ドラッグ対象にイベントを設定して、コンテナに委譲
  • iOSの場合は、コンテナでイベントを取得して、ドラッグ対象を計算で特定

このあたりは、どうせ C# で作るのだから統一しておきたいところです。個人的には Android 方式のほうがわかりやすいのですが(Java ではリスナークラスが必要になるので逆にわかりにくい)、差分を取れるほうが楽なので、ManipulationDelta のようにできると良いかなと。

サンプルは こちら https://github.com/moonmile/SampleTouch

カテゴリー: Android, WinRT, Xamarin, iOS | Xamarinでコントロールのドラッグに対応する はコメントを受け付けていません

XamarinでAndroid/iOS/Windowsストアの回転に対応する

実機を回転したときに縦置きと横置きの対応する方法は、基本はフローレイアウトを使うほうがいいのですが、コントロールがたくさん並んでいる場合にはなかなか大変ですね。…という理由を付けて、まとまったものが見つからなかったので、3つのプラットフォームでXamarinでどう対応するのかを残しておきます。

それぞれ方法があると思いますが、Potable Class Library で DataModel を共有化することと、3つのプラットフォームで似た方法で作れる、ことを目的とします。

■Windowsストアプリ の場合

  1. 横置き(Landscape)と縦置き(Portrait)の2つのViewStateを作る。
  2. PageクラスのLayoutUpdatedイベントで DisplayInformation.GetForCurrentView() でデバイスの向きを判断して、VisualStateManager.GoToState メソッドを呼び出す。

Blend を使って、VisualStateGroup を作って、その中に2つの ViewState を作る。”Landscape” と “Portrait” を作っておく。

image


 
  
   
   
    

コントロールを Portrait を設定してデザインを作る。

画面自体は1画面なので、XAMLに対して、this.DataContext = _model; のようにバインドができる。

回転時はイベントを取得して、ViewState を切り替える。

private void pageRoot_LayoutUpdated(object sender, object e)
{
    DisplayInformation displayInfo = DisplayInformation.GetForCurrentView();
    switch (displayInfo.CurrentOrientation)
    {
        // 横置き
        case DisplayOrientations.Landscape:
        case DisplayOrientations.LandscapeFlipped:
            VisualStateManager.GoToState(this, "Landscape", true);
            break;
        // 縦置き
        case DisplayOrientations.Portrait:
        case DisplayOrientations.PortraitFlipped:
            VisualStateManager.GoToState(this, "Portrait", true);
            break;
    }
}

横置きと縦置きで、コントロールの位置はこんな風に自由に配置できる。方法としてはスナップも同じ。というかスナップと同じ方法。

image

image

■Android の場合

  1. Alternative Layouts で、landscape 用のレイアウトを作る。
  2. layout-land/Main.axml を横置き用に編集する。
  3. ウィジット(コントロール)の ID は元の Portrait と同じにしておく。

image

image

回転したときには内部で自動的に判断して、layout-land/Main.axml が呼び出される。*.axml ファイルが2つになるので、IDをそろえておく。揃えておくと、FindViewById メソッドで統一して扱える。

private void UpdateData()
{
    FindViewById(Resource.Id.textViewID).Text = _model.ID;
    FindViewById(Resource.Id.textViewUserName).Text = _model.UserName;
    FindViewById(Resource.Id.textViewScore).Text = _model.Score.ToString();
    FindViewById(Resource.Id.textViewRank).Text = _model.Rank.ToString();
}

 

Android エミュレータは Ctrl+F11 で回転できる。

image

image

■iOS の場合

  1. Storyboard で、横置き用の ViewController を作成する。
  2. Storyboard Segue に名前を付けおく。
  3. 元の ViewController の View のタグを付けておく(初期化判断用)
  4. 同じ ViewController クラスに設定しておく。
  5. UIDeviceOrientationDidChangeNotification イベントで、PerformSegue メソッドを使って View を切り替える。

最初の画面が縦置き(Portrait)で、横置き(Landscape)に画面遷移する、という想定で作る。

image

切り替えを「Model」にしておく。

image

最初の View に Tag を付けておく。これは最初の画面のみ UIDeviceOrientationDidChangeNotification を設定するため。

image

AwakeFromNib をオーバーライドして UIDeviceOrientationDidChangeNotification イベントを登録。回転イベントが発生したら、UIDevice.CurrentDevice.Orientation で View を切り替える。

bool isShowingLandscaeView ;
public override void AwakeFromNib ()
{
    base.AwakeFromNib ();
    // main view only 
    if (this.View.Tag == 100) {
        // main view only,
        // set to main view's tag 100.
        this.isShowingLandscaeView = false;
        UIDevice.CurrentDevice.BeginGeneratingDeviceOrientationNotifications ();
        NSNotificationCenter.DefaultCenter.AddObserver (
            "UIDeviceOrientationDidChangeNotification",
            orientationChanged);
    }
}
void orientationChanged( NSNotification obj ) 
{
    var deviceOrientation = UIDevice.CurrentDevice.Orientation;
    if (deviceOrientation == UIDeviceOrientation.LandscapeLeft ||
        deviceOrientation == UIDeviceOrientation.LandscapeRight) {
        if (isShowingLandscaeView == false) {
            this.PerformSegue ("LandView", this);
            isShowingLandscaeView = true;
        }
    } else if (deviceOrientation == UIDeviceOrientation.Portrait ||
        deviceOrientation == UIDeviceOrientation.PortraitUpsideDown) {
        if (isShowingLandscaeView == true) {
            this.DismissViewController (false, null);
            isShowingLandscaeView = false;
        }
    }
}

 

元画面(portrait)から lanscape に遷移するときは、this.PerformSegue (“LandView”, this); を使い、landscape から元画面(portrait)に戻るときは this.DismissViewController (false, null); を使う。これは、storybord の画面遷移と同じ。遷移のアニメーションと回転時のアニメーションが競合するよな気もするんだが…このほうは Apple のマニュアルにもあるので、大丈夫だと思う。

image

image

2つの画面に分かれるが、同じ ViewController を示すようにして、IBOutlet させたプロパティにDataModel から設定する。

■ DataModel を PCL で作る

データ自体は、DataModel 内にひとつにしたいので、複数の View に対応する必要がある。基本は画面遷移をしたときと同じなのだが、画面のコントロール/ウィジットが多い場合には意外と大変かも。ただし、縦横で別々に作ったほうが使いやすいデザインにはなる。

  Winストア Android iOS
デザイン 1つのXAML 2つの
AXMLファイル
2つのViewController
回転
切り替え
コード 自動 コード
データ
設定
データバインド FindViewById で取得。IDを揃える。 IBOutletで取得

上記のサンプルは git で公開しています。https://github.com/moonmile/SampleRotate

機会を作って MvvmCross でも。

カテゴリー: Android, C#, WinRT, Xamarin, iOS | XamarinでAndroid/iOS/Windowsストアの回転に対応する はコメントを受け付けていません

HAXM で Android 仮想デバイスを高速化

ほとんど、Android仮想デバイス(AVD)の高速化 – Yahoo!知恵袋 に書いてある通りなので、自分用にメモとして残しておきます。

私の環境が、

  • Windows 8.1 Pro
  • VMWare Worksitation 10

なので、Hyper-V の機能が使えません。VMWare の仮想の仕組みが Hyper-V と競合するので、あれこれで HAXM Android* – Intel® Hardware Accelerated Execution Manager | Intel® Developer Zone と競合するのかと思っていたのですが、勘違いしていました。Intel CPU の場合は利用できる。AMD CPU の場合は利用できない。という違いですね。Intel VT という仮想化技術で実現しているので、さっくりと VirtualChecker 3.0.1 でチェックしておきます。

image

左上の「Intel VT-X」が Enabled になっていれば OK です…と思ったけど、AMD-V 対応でも Enabled になる?まあ、自分のPCが IntelかAMDぐらいかぐらいは分かるか。

Android エミュレータの「Intel Atom x86」を動かすために、Android* – Intel® Hardware Accelerated Execution Manager | Intel® Developer Zone から、Hotfix for Windows 8.1 only (1.0.7) のほうをダウンロード(Windows 8.1なので)。Android SDK Manager の HAXM は、Windows 8.1 だとクラッシュするそうです(試してません)。

image

「Intel Atom x86」のイメージは、各API に入っています。4.0.3 以降(API 15)以降ですね。

image

Android Virtual Device Manager で、CPU/ABI を ARM から Intel Atom (x86) に変更します。

image

Android Virtual Device Manager で起動する Android を選択して「Start」ボタンを押してエミュレーターを起動。

image

エミュレータ自体は結構なスピードで立ち上がります。

image

で、実際のところ Xamarin.Android からデプロイをしてみると、最初のデプロイに結構な時間がかかるのは同じ模様で。

image

…と、ここまで書いてやっぱりデプロイできず。変だな。で、試しに 4.0.3 (API 15)で Intel Atom で動かすと正常に動きます。私の 4.4.2 のエミュレータの作り方がおかしいのか、後で調べなおそう。

image

API 19 だと ARM でも動かないので、エミュレータの設定がおかしいのかも。試しに 4.3 (API 18)を入れると動くので、現状では API 19 は対応していないのかも。

カテゴリー: Android, Xamarin | HAXM で Android 仮想デバイスを高速化 はコメントを受け付けていません

Code Snippet With Syntaxhighlighter を使ってみる

【WindowsLiveWriter】で「Code Snippet With Syntaxhighlighter」を使ってソースコードを入力する | Q-miz blog(きゆみずぶろぐ) の記事を参考にして、Windows Live Writer でコードを書いてみるテスト。このブログ自体、SyntaxHighlighter は入っているのだけど、いつもは QX エディタで編集、自前 Perl スクリプトで整形、自前アップロードプログラムで WordPress へ投稿、ってなことをやっている。コードの編集とか画像の縮小とかを自動化しているんだけど、単なる文章の場合は Windows Liver Writer で書くことが多い。

Xamarin.iOS 拡張を見ると、Visual Studio拡張がどうやっているのか調べる必要があって GUID を頼りにレジストリエディタをのぞいてみると、

[HKEY_CURRENT_USERSoftwareMicrosoftVisualStudio12.0_ConfigProjects{6bc8ed88-2882-458c-8e55-dfd12b67127b}]
@="MonoTouchProjectFactory"
"DisplayName"="Xamarin.iOS"
"DisplayProjectFileExtensions"="Xamarin.iOS Projects (*.csproj);*.csproj"
"Package"="{77875fa9-01e7-4fea-8e77-dfe942355ca1}"
"ProjectTemplatesDir"="\..\NullPath"
"Language(VsTemplate)"="CSharp"
"ShowOnlySpecifiedTemplates(VsTemplate)"=dword:00000001
"TemplateGroupIDs(VsTemplate)"="MonoTouch"
"TemplateIDs(VsTemplate)"="Microsoft.CSharp.XmlFile,Microsoft.CSharp.TextFile,Microsoft.CSharp.CodeFile,Microsoft.CSharp.Class,Microsoft.CSharp.Resource,Microsoft.CSharp.AssemblyInfo.Internal"

 

こんなところのプロジェクトテンプレートがある。 このパッケージ 77875fa9-01e7-4fea-8e77-dfe942355ca1 をもう一度検索すると、

[HKEY_CURRENT_USERSoftwareMicrosoftVisualStudio12.0_ConfigPackages{77875fa9-01e7-4fea-8e77-dfe942355ca1}]
@="MonoTouchPackage"
"InprocServer32"="C:\Windows\SYSTEM32\MSCOREE.DLL"
"Class"="Mono.IOS.VisualStudio.MonoTouchPackage"
"CodeBase"="C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\Extensions\Xamarin\Xamarin.iOS\1.10.47.0\Mono.IOS.VisualStudio.dll"

 

なところで、DLLを定義していることがわかる。

この部分で CSharp プロジェクトテンプレートを VisualBasic テンプレートに切り替えるのか?と思っているのだけど、いやいや、FSharp の場合は別だろうから、Visual Basic拡張は別途作らないといけないかも、後で調べよう。

カテゴリー: Wordpress, Xamarin | Code Snippet With Syntaxhighlighter を使ってみる はコメントを受け付けていません

Visual Basic で iOS アプリを書くプロジェクトを作成…できた

Visual Basic で iOS アプリを書くプロジェクトを作成…している途中 | Moonmile Solutions Blog
http://www.moonmile.net/blog/archives/5604

昨日の続きで、Xamarin.iOSを使ってVBでコードを書いてiOSアプリを書く、というニッチな話を。
結論から言うと、一応できました。結構、回避策を使っているので、もうちょっとアプローチを考えないといけないのですがブレイクスルーはできた感じ。

■Xamarin.MonoTouch.VisualBasic.targets を作成する

以下の3つのファイルを作成します。

C:\Program Files (x86)\MSBuild\Xamarin\iOS\Xamarin.MonoTouch.VisualBasic.targets

<Project DefaultTargets=&quot;Build&quot; xmlns=&quot;http://schemas.microsoft.com/developer/msbuild/2003&quot;>
	<PropertyGroup>
		<TargetFrameworkIdentifier>MonoTouch</TargetFrameworkIdentifier>
		<TargetFrameworkVersion Condition=&quot;'$(TargetFrameworkVersion)' == ''&quot;>v1.0</TargetFrameworkVersion>
	</PropertyGroup>
	<Import Project=&quot;$(MSBuildBinPath)\Microsoft.VisualBasic.Targets&quot; />
	<Import Project=&quot;Xamarin.MonoTouch.Common.targets&quot; />
</Project>

C:\Program Files (x86)\MSBuild\Xamarin\Xamarin.ObjcBinding.VisualBasic.targets

<Project DefaultTargets=&quot;Build&quot; xmlns=&quot;http://schemas.microsoft.com/developer/msbuild/2003&quot;>
        <Import Project=&quot;$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.ObjcBinding.VisualBasic.targets&quot; />
</Project>

C:\Program Files (x86)\MSBuild\Xamarin\iOS\Xamarin.ObjcBinding.VisualBasic.targets

<Project DefaultTargets=&quot;Build&quot; xmlns=&quot;http://schemas.microsoft.com/developer/msbuild/2003&quot;>

  <UsingTask TaskName=&quot;Xamarin.ObjcBinding.Tasks.BTouch&quot; AssemblyFile=&quot;Xamarin.ObjcBinding.Tasks.dll&quot; />

  <PropertyGroup>
    <TargetFrameworkIdentifier>MonoTouch</TargetFrameworkIdentifier>
    <TargetFrameworkVersion Condition=&quot;'$(OS)' == 'Unix'&quot;>v1.0</TargetFrameworkVersion>
    <TargetFrameworkVersion Condition=&quot;'$(OS)' != 'Unix'&quot;>v4.0</TargetFrameworkVersion>
  </PropertyGroup>

  <Import Project=&quot;$(MSBuildBinPath)\Microsoft.VisualBasic.Targets&quot; />
  <Import Project=&quot;Xamarin.ObjcBinding.Common.targets&quot; />

  <PropertyGroup>
    <!-- work around a bug in the Mono Microsoft.CSharp.Targets that defaults the compiler to gmcs -->
    <CscToolExe Condition = &quot;'$(OS)' == 'Unix'&quot;>vbnc</CscToolExe>

    <!-- Btouch needs CscPath, but when building from within Visual Studio, it and the CscTool{Exe,Path}
         properties will be empty since VS uses the in-process compiler, so fix them. -->
    <CscPath Condition=&quot;'$(CscPath)' == '' And '$(OS)' != 'Unix'&quot;>$(CscToolPath)$(CscToolExe)</CscPath>
    <CscPath Condition=&quot;'$(CscPath)' == '' And '$(OS)' != 'Unix'&quot;>$(MSBuildToolsPath)\vbc.exe</CscPath>

    <BaseLibDllPath Condition=&quot;'$(OS)' == 'Unix'&quot;>/Developer/MonoTouch/usr/lib/mono/2.1/monotouch.dll</BaseLibDllPath>
    <BaseLibDllPath Condition=&quot;'$(OS)' != 'Unix'&quot;>$(MSBuildExtensionsPath)\Xamarin\iOS\monotouch.dll</BaseLibDllPath>
    <BTouchToolExe Condition=&quot;'$(BTouchToolExe)' == '' And '$(OS)' == 'Unix'&quot;>/Developer/MonoTouch/usr/bin/btouch</BTouchToolExe>
    <BTouchToolExe Condition=&quot;'$(BTouchToolExe)' == '' And '$(OS)' != 'Unix'&quot;>$(MSBuildExtensionsPath)\Xamarin\iOS\btouch.exe</BTouchToolExe>
    <GeneratedSourcesFileList Condition=&quot;'$(GeneratedSourcesFileListing)' == ''&quot;>$(GeneratedSourcesDirectory)\sources.list</GeneratedSourcesFileList>
  </PropertyGroup>

  <!-- Add our own pre-build steps -->
  <PropertyGroup>
    <CompileDependsOn>
      GenerateBindings;
      $(CompileDependsOn)
    </CompileDependsOn>
  </PropertyGroup>

  <!-- Override the CoreCompile Target to use btouch -->
  <Target Name=&quot;GenerateBindings&quot;
  	  Inputs=&quot;$(MSBuildAllProjects);@(ObjcBindingApiDefinition);@(ObjcBindingCoreSource);@(ReferencePath);@(ObjcBindingNativeLibrary)&quot;
	  Outputs=&quot;$(GeneratedSourcesFileList)&quot;>

    <BTouch AdditionalLibPaths=&quot;$(AdditionalLibPaths)&quot;
    	    AllowUnsafeBlocks=&quot;$(AllowUnsafeBlocks)&quot;
	    ApiDefinitions=&quot;@(ObjcBindingApiDefinition)&quot;
	    CoreSources=&quot;@(ObjcBindingCoreSource)&quot;
	    DefineConstants=&quot;$(DefineConstants)&quot;
	    GeneratedSourcesDirectory=&quot;$(GeneratedSourcesDirectory)&quot;
	    GeneratedSourcesFileList=&quot;$(GeneratedSourcesFileList)&quot;
	    Namespace=&quot;$(Namespace)&quot;
	    BTouchToolPath=&quot;$(BTouchToolExe)&quot;
	    CompilerPath=&quot;$(CscPath)&quot;
	    BaseLibDll=&quot;$(BaseLibDllPath)&quot;
	    NoStdLib=&quot;$(NoStdLib)&quot;>
      <Output TaskParameter=&quot;GeneratedSourcesFileList&quot; ItemName=&quot;GeneratedSourcesFileList&quot; />
    </BTouch>

    <ReadLinesFromFile File=&quot;$(GeneratedSourcesFileList)&quot; >
      <Output TaskParameter=&quot;Lines&quot; ItemName=&quot;GeneratedSources&quot; />
    </ReadLinesFromFile>

    <CreateItem Include=&quot;@(ObjcBindingCoreSource)&quot;>
      <Output TaskParameter=&quot;Include&quot; ItemName=&quot;Compile&quot; />
    </CreateItem>

    <CreateItem Include=&quot;@(GeneratedSources)&quot;>
      <Output TaskParameter=&quot;Include&quot; ItemName=&quot;Compile&quot; />
    </CreateItem>

    <CreateItem Include=&quot;@(ObjcBindingNativeLibrary)&quot;>
      <Output TaskParameter=&quot;Include&quot; ItemName=&quot;ManifestResourceWithNoCulture&quot; />
    </CreateItem>
  </Target>

</Project>

■*.sln と *.vbproj を書き換える

どうやら、mac にデプロイしていなさそうの勘はあたりで、デプロイ(配置)するようにしたら通りました。
*.sln に以下になるように追加。「Deploy.0」が配置の実行にあたります。91DDFB1F-30BD-472E-9022-0D0E29A8A301 は VB プロジェクトの GUID です。

{91DDFB1F-30BD-472E-9022-0D0E29A8A301}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
{91DDFB1F-30BD-472E-9022-0D0E29A8A301}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
{91DDFB1F-30BD-472E-9022-0D0E29A8A301}.Debug|iPhoneSimulator.Deploy.0 = Debug|iPhoneSimulator

*.proj のほうは、以下になるように書き換えます。ProjectTypeGuids はプロジェクトの種類を設定するもので、6BC8ED88-2882-458C-8E55-DFD12B67127B は、Xamarin.iOS の C# の GUID です。このままだと C# のコンパイラが走ってしまうのでコメントアウトしています。が、このコメントを消してしまう(ProjectTypeGuids自体を削除する)とデプロイできません。変ですね(苦笑)。まあ、*.vbproj の読み込み部分が変らしいので、これはこれで使わせてもらいます。

<ProjectGuid>{91DDFB1F-30BD-472E-9022-0D0E29A8A301}</ProjectGuid>
<!--
<ProjectTypeGuids>{6BC8ED88-2882-458C-8E55-DFD12B67127B};{F184B08F-C81C-45F6-A57F-5ABD9991F28F}</ProjectTypeGuids>
-->

ここに出てくる GUID は、*.sln の上のほうにある Project 部分に対応します。

Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "HelloVB", "HelloVBHelloVB.vbproj", "{91DDFB1F-30BD-472E-9022-0D0E29A8A301}"
EndProject

ProjectGuid 関連はこちらへ。おそらく、Visual Basic 用のGUIDを自作すればOKかと思います。

VSの「プロジェクトの種類がこのインストールでサポートされていません」(ProjectTypeGuids) – あおきのTechメモ
http://d.hatena.ne.jp/aoki1210/20090912/p1
INFO: List of known project type Guids
http://www.mztools.com/Articles/2008/MZ2008017.aspx

■Microsoft.VisualBasic.dll を外す

先の方法で、無事 mac へのデプロイはできたのですが、こんどは VisualBasic.dll がロードできなくて iOS シミュレータを立ち上げる前にこけます。具体的には Visual Studio に出てくる出力をみると、以下な感じで、何かが load できていません。

Loaded assembly: /Users/masuda/Library/Caches/Xamarin/mtbs/builds/HelloVB/91ddfb1f-30bd-472e-9022-0d0e29a8a301/assemblies/HelloVB.exe
2014-03-25 03:06:09.981 HelloVB[9011:70b] Could not load 'HelloVB' for registration: System.Reflection.ReflectionTypeLoadException: The classes in the module cannot be loaded.
  at (wrapper managed-to-native) System.Reflection.Assembly:GetTypes (System.Reflection.Assembly,bool)
  at System.Reflection.Assembly.GetTypes () [0x00000] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Reflection/Assembly.cs:351
  at MonoTouch.Registrar.OldDynamicRegistrar.RegisterAssembly (System.Reflection.Assembly a) [0x00000] in /Developer/MonoTouch/Source/monotouch/src/ObjCRuntime/OldDynamicRegistrar.cs:67
Loaded assembly: /Developer/MonoTouch/usr/lib/mono/2.1/System.Xml.dll [External]
2014-03-25 03:06:09.983 HelloVB[9011:70b] This could be due to an outdated assembly kept by the simulator, location: /Users/masuda/Library/Caches/Xamarin/mtbs/builds/HelloVB/91ddfb1f-30bd-472e-9022-0d0e29a8a301/assemblies/HelloVB.exe
Missing method SetProjectError in assembly /Users/masuda/Library/Caches/Xamarin/mtbs/builds/HelloVB/91ddfb1f-30bd-472e-9022-0d0e29a8a301/assemblies/HelloVB.exe, type Microsoft.VisualBasic.CompilerServices.ProjectData
An unhandled exception occured.

多分、C# にない VisualBasic.dll を参照していると思われるので、*.vbproj から以下の設定で VisualBasic.dll を参照しないようにします。

  <PropertyGroup>
    <Configuration Condition=&quot; '$(Configuration)' == '' &quot;>Debug</Configuration>
    <Platform Condition=&quot; '$(Platform)' == '' &quot;>iPhoneSimulator</Platform>
...
	<NoVBRuntimeReference>true</NoVBRuntimeReference>
  </PropertyGroup>

VBなのに VisualBasic.dll を参照しないので、いくつか VB 特有の機能が失われますが、ひとまず。
VisualBasic.dll を参照していないので、My Project 回りの *.vb でコンパイルエラーが出るので、コメントアウトしていまいます。

■デバッグ実行する

うまくできると、こんな風にデバッグ実行ができます。

■サンプルはこちら

Xamarin の Hello World を VB に直したサンプルです。先の *.targets ファイルも入っています。

http://1drv.ms/1jnqkR7

VisualBasic.dll を外してしまったために、VB 特有の関数が使えなくなっています。ですが、mono にも vbnc という VB コンパイラがあるので、VisualBasic.dll はあるハズなんですよね。そのあたりをうまく整合性をあわせてやれば、もうちょっと汎用性がある形でできると思うのですが。このあたりは、Android版を作りながら考える予定。

追記 2014/03/26
プロジェクトテンプレートにしてみました。

http://1drv.ms/1l0Ssqs

カテゴリー: VB, Xamarin | Visual Basic で iOS アプリを書くプロジェクトを作成…できた はコメントを受け付けていません

Visual Basic で iOS アプリを書くプロジェクトを作成…している途中

Xamarin では C# で iOSアプリを作れるのですが、Visual Basic では作れません…が本当のか?と思って試している途中。

こんな風に、C# のプロジェクトを真似て Visual Basic でプロジェクトを作ります。

image

  1. 参照設定で、monotouch, System, System.Core, System.Xml を入れる。
  2. <Import Project=”$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.MonoTouch.VisualBasic.targets” /> を *.vbproj に追加する。
  3. C:\Program Files (x86)\MSBuild\Xamarin\iOS\Xamarin.MonoTouch.VisualBasic.targets を新しく作成する。

中身はこんな感じ。

<Project DefaultTargets=”Build” xmlns=”http://schemas.microsoft.com/developer/msbuild/2003″>
    <PropertyGroup>
        <TargetFrameworkIdentifier>MonoTouch</TargetFrameworkIdentifier>
        <TargetFrameworkVersion Condition=”‘$(TargetFrameworkVersion)’ == ””>v1.0</TargetFrameworkVersion>
    </PropertyGroup>
   
    <Import Project=”$(MSBuildBinPath)\Microsoft.VisualBasic.Targets” />
    <Import Project=”Xamarin.MonoTouch.Common.targets” />
</Project>

  1. Settings.Designer.vb の中身はビルドができないのでコメントアウト

なところまで作ると、Xamarin.iOS を入れた状態で、Visual Basic の iOS プロジェクトがビルドできます。

…が、ビルドはできるものの、デバッグ/デプロイができない。

image

monotouch.dll が見当たらないのか、依存が見つからないのかわからないけど、必要なアセンブリがみつからない。C# のプロジェクトのでは正常にデバッグ実行できるので、Visual Basic で作ったときだけ何かが足りない。残念。

調べてみたい方は、リンクからどうぞ。

http://1drv.ms/1jhTWiG

カテゴリー: VB, Xamarin | 2件のコメント

MVP Community Camp 2014 で発表しました。

Xamarinで作るiPhoneとwindowsストアアプリの共通コンポーネント

Xamarin.iOS, Xamarin.Android を使ったデモをさらっと。サンプル用に作ったプログラム(実は、書籍用に作っているプログラム)は、あえてコードの説明を避けたのですが…まあ、コードも公開してしまいます。まだ途中なので。完成したあかつきには購入をご検討ください。たぶん、サンプルコードはフリーでダウンロードできるようになると思います。

http://1drv.ms/1g1WE9M

こんな感じのプロジェクト構成になっています。

image

カテゴリー: C#, Xamarin | MVP Community Camp 2014 で発表しました。 はコメントを受け付けていません

PCL のターゲットフレームワークに Xamarin をインストールせずに Xamarin.Android を追加する

からの一連のところの話と、明後日発表をするので、ちょっと気になったので PCL の作りを再チェックしてました。

image

Xamarin拡張を入れると、ポータブルクラスライブラリを作るときに、Xamarin.Android と Xamarin.iOS のチェックを入れられるようになるんですが、これって何処で設定しているんでしょうね?という疑問です。

そもそも、ポータブルクラスライブラリ自体は「ポータブル」なんだから、他の特殊なアセンブリを参照する必要はないんですよね。最低限のアセンブリを使うわけだから。だから、Xamarin.Androidなどのインストールをしなくても、何等かの設定で読み込めるわけで、この設定自体は何処かにあったのか…それとも Xamarin.Androidをインストールしたときか?という推測が成り立ちます。

PCLのプロジェクトをエディタで開くと、

<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkProfile>Profile78</TargetFrameworkProfile>

となって TargetFrameworkProfile が「Profile78」になっています。これが何処にあるかというと、C:/Program Files (x86)/Reference Assemblies/Microsoft/Framework/.NETPortable/v4.5/Profile/ フォルダの中にあるんですね。更に、SupportedFrameworks フォルダを調べると、Xamarin.Android などがあります。

image

フォルダ名は、

  • Profile7
  • Profile49
  • Profile78

と3つある訳ですが、これが何を意味するのかは他の SupportedFrameworks フォルダを覗くと分かります。

Profile7 Profile49 Profile78
.NET Framework 4.5
Windows Store apps (Windows 8).
Windows Phone 8
Xamarin.Android
Xamarin.iOS

どうやら先のチェックボックスと対応しているようです。RedistList フォルダの中には、対応するアセンブリのリストがあるので、その差分を取ってみると。

Profile7 Profile49 Profile78
Microsoft.VisualBasic
System.Threading.Tasks.Parallel
System.Reflection.Emit.ILGeneration

だいたい、こんな感じになってます。で、このProfileフォルダは Xamarin を入れたときに出来るのではなくて、最初に Visual Studio を入れたときに作られます。つまり、あらかじめ PCL となるアセンブリの組み合わせは決まっているということですね。となると、動的コード生成で使われる System.Reflection.Emit.ILGeneration は Windows ストアアプリにときに入らない、ってことになります。

このあたり、Xamarin.iOS では動的コード生成ができないという制限があるのですが、そもそもが WinRT の場合は動的コード生成ができないので、PCL にするとそもそも動的コード生成はできないってことですよ。これはMSDNにもあります。

と、今気が付いたんですが、そうなると Profile49 の Xamarin.iOS の設定って間違っているんじゃないか?と思ったり。

■Xamarin.Android を入れずに、PCL の設定で Xamarin.Android を表示するには

ってことで、ややこしいですが、

Xamarin.Android.xml

<?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?>
<Framework DisplayName=&quot;Xamarin.Android&quot; Identifier=&quot;MonoAndroid&quot; Profile=&quot;*&quot; MinimumVersion=&quot;1.0&quot; MaximumVersion=&quot;*&quot; />

Xamarin.iOS.xml

<?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?>
<Framework DisplayName=&quot;Xamarin.iOS&quot; Identifier=&quot;MonoTouch&quot; Profile=&quot;*&quot; MinimumVersion=&quot;1.0&quot; MaximumVersion=&quot;*&quot; />

を、対応する Profile フォルダに保存すれば OK です。Xamarin Studio をインストールしなくてもxml ファイルを作るだけです。Visual Studioを再起動すると設定が反映されます。

こんな風に OreOre.Framework を PCL に追加することもできますね。意味ないけど。

image

カテゴリー: Xamarin | PCL のターゲットフレームワークに Xamarin をインストールせずに Xamarin.Android を追加する はコメントを受け付けていません

アリスはカンマとコンマを区別する

久々のアリプラシリーズです。

元のコードはc++なんですかね?と思って自分でコードを書いてみます。ええと、カンマ(コンマ)「,」演算子は、マクロでは使うけど演算子のオーバーロードをすると関数の引数とややこしくなるわけですが、「爽やかなコード」になるかどうかは分かりません。
確か、,演算子は優先度が一番低いから、そのあたりも含めて使うといいかも。

int x , y ;
int z = (x=10,y=20);

最後の式の値を返すので、zの値は20になりますね。そのあたりを利用したマクロが量産される訳ですが。バッドテクニックと言えなくもないし広域に使うとまずそうだけど、局所的にたまに使います。データ加工したいときとか。

さて、アリスとロリータをカンマで繋ぎます。繋ぐ方法はいろいろあるので、いくつか試してみたのがこれ。どこでどうやってつながっているのかを理解するには、c++ の構文解析を「想像」する必要がありますよね。関数の引数で使うカンマと、オーバーライドできるカンマ演算子がまぜこぜになっているので、こんな感じになります。
“Alice”と”Lolita”をカンマでつなげるカンマ演算子の定義です。

#include &quot;stdafx.h&quot;
#include <string>
#include <iostream>

using namespace std;
std::string operator , (std::string &l, std::string &r)
{
	cout << &quot;in operator , &quot; << endl;
	std::string s;
	s.append(l);
	s.append(&quot;,&quot;);
	s.append(r);
	return s;
}
std::string comma(std::string &l, std::string &r)
{
	cout << &quot;in comma function 2 arguments &quot; << endl;
	std::string s;
	s.append(l);
	s.append(&quot;,&quot;);
	s.append(r);
	return s;
}

std::string comma(std::string &l)
{
	cout << &quot;in comma function 1 argument &quot; << endl;
	return l;
}

int _tmain(int argc, _TCHAR* argv[])
{
	string s1 = &quot;Alice&quot;;
	string s2 = &quot;Lolita&quot;;
	std::cout << &quot;ans: &quot; << (s1, s2) << std::endl;
	std::cout << &quot;ans: &quot; << comma(s1, s2) << std::endl;
	std::cout << &quot;ans: &quot; << comma((s1, s2)) << std::endl;
}

■実行結果

in operator ,
ans: Alice,Lolita
in comma function 2 arguments
ans: Alice,Lolita
in operator ,
in comma function 1 argument
ans: Alice,Lolita

ちなみに、「カンマ演算子」なのか「コンマ演算子」なのかは諸説あるところで、わたくし的には「テクスト」と「テキスト」の違いを意識して(「コンテクスト」と「コンテキスト」とかも)、用語定義の哲学っぽく「カンマ演算子」という呼び名が好みです。そうそう、小数点の扱いも「ポイント」は「.」だったり「,」だったりする訳で、呼び名(発声)と現物(意味)とは違うよねという話。シニフィアンとシニフィエを久し振りに。

カテゴリー: C++ | アリスはカンマとコンマを区別する はコメントを受け付けていません