Bakulog

獏の夢日記的な何か。

【WPF】社畜ちゃんをデスクトップマスコットにする【XAML】

最近社畜業界で人気急上昇中の社畜ちゃんをデスクトップマスコットにしました。

 作ったもの紹介

まず完成品を紹介。こちらの「社畜ちゃんタイピング」が作成したソフトになります。紹介前に一応注意ですが社畜ちゃんの著作権ビタワン様(twitter: @vitaone_)が持っており本ソフトは二次創作的な何かです。

デスクトップマスコットの機能は見ての通りなので紹介文とかは敢えて無しで…。

ダウンロードはGoogle Driveから2015/7/7追記: ソースコードGitHubに移しました。いちおうGoogle Driveにもソフト本体だけ残してますソースコード丸ごと版と実行ファイルのみの2バージョンがあります。繰り返しになりますが社畜ちゃんは完全フリーな素材ではないので再頒布とかはご遠慮下さい。というか、何かしたければ私じゃなくてビタワン様にお問い合わせ下さい。

 

 

こんなの普通に作れんの?

こっからは作り方紹介です。Google Driveソースコード同梱版にはソリューションファイル(ShachikuChanTyping.sln)を含めたファイル全体が入っている2015/7/7追記: ソースはGitHubに移行しましたので、コチラをVisual Studioで開いて見つつ読み進めてもらえるといいかなーと思います。

この「社畜ちゃんタイピング」はMicrosoftが擁する最強の?デスクトップGUIフレームワークであるWPF(Windows Presentation Foundation)で実装しています。以前にSlideShareに上げた「C#/WPFで作るデスクトップマスコット入門」にも書いてますがWPFWindows用デスクトップマスコットとの相性が抜群に良いです(もちろん真っ当なGUIにも強いです)。

そこで今回は「社畜ちゃんタイピング」が出来るまでの流れをかるーく確認してみましょう。ちなみに初期版完成までの所要時間はだいたい4時間くらいです。画像関係で手抜きすると2時間くらいで作れるという説もあります。

 

なお一旦記事に書いてみたら予備知識がけっこう必要な感じになってしまいました。WPFの達人が初心者向け記事を書いておられるそうなので、本記事見てもチンプンカンプン…という場合は参考にしてみてください。

 

Visual Studio 2013でWPFプリプロジェクトを作成

本ソフトはVisual Studio 2013を使って作成しています。昔はVisual Studioというと無償で使えるのは評価版(Express)だけでしたが最近はCommunity版という無償だけど有償と同等の性能があるものが使えたりするので、個人デベロッパの方はぜひ導入しましょう。というかWPFアプリケーションをVisual Studio抜きで開発とかあり得ないので必ず使って下さい。

 

社畜ちゃんの画像をベクターデータ化する

まずGUIコントロールの一つとして社畜ちゃんを作ります。ソースの中で"ShachikuChan.xaml"とあるのがそうですね。

このファイルですが、コードエディタ的に使うのが主であるVisual Studioを使う…のではなく同梱ソフトであるBlend for Visual Studioを使います。このソフトはXAMLを使ったGUIを編集するためのイラストレーター的ソフトで、Visual Studioと同様にソリューションファイル(ShachikuChanTyping.sln)を開いての作業が可能です。Blendはベクター画像、つまりドット絵ではなく「太さが2で青色の曲線」みたいに無限精度で表現されるイメージの作成に大変便利です。今回は諸事情あってビタワン様の絵をトレスしたものが使いたかったので、実際に画像をベースにトレスしてベクタイメージを作りました。絵的にはこんな雰囲気。

blend_shachikuchan

Blendでお絵かきする方法についてはぐらばく先生がXAMLでクラウディアさんを描いた記事とかが大変参考になるのでコチラで勉強して下さい。

 

腕が動くアニメーションを作成

絵を書いた後も引き続きBlendで作業を続けて、腕を動かすアニメーションを作るんですが…これについては解説書くのが少し大変なので、別記事で用意させて頂きますm( )m

ただ記事はなくとも確実に理解して欲しい事が一つだけあります。それは「社畜ちゃんの腕の動きはコーディングではなくGUIデザイナーで全部作ってる」という事です。要するにコード書かないで済むからラクですよって話ですね。

 

非矩形ウィンドウ上に社畜ちゃんを配置

ともかく社畜ちゃんが完成したら実際にウィンドウ上に配置します。Blendでの作業はおしまいにしてVisual Studioに移りましょう(※BlendとVisual Studioを同時に起動して同じソリューションファイルを開いても大丈夫です。その場合、片方のソフトでファイル変更が起こるともう片方にも反映されます)。

メインウィンドウである"ShachikuChanWindow.xaml"上に社畜ちゃんを配置するには、自前の名前空間XAML上で認識できるように名前空間設定を追加し、ソレを使ってさっき作った社畜ちゃんを置きます。

<Window ...
    ↓追加
    xmlns:local="clr-namespace:ShachikuChanTyping"
    ...
    >
    <Window.ContextMenu>
        ...(右クリックメニューを設定)
    </Window.ContextMenu>
    <Grid>
        ↓追加
        <local:ShachikuChan x:Name="ShachikuChan"/>
    </Grid>
</Window>

しかし、これだけだとウィンドウの中に社畜ちゃんが居るような状態になります。

vs_shachikuchan

デスクトップマスコットらしくするため背景を透明にしないといけませんが、実は前作ったスライドで示しているように背景の透明化はとても簡単です。Windowの属性値を3つ追加指定するだけでうまくいきます。

<Window x:Class="ShachikuChanTyping.MainWindow"
        ...
        ↓3つ追加
        AllowsTransparency="True"
        WindowStyle="None"
        Background="Transparent"
        >
        ...
</Window>

 

各属性値の意味はこんな感じ。

  • AllowTransparency: ウィンドウが透ける場合がある事を宣言する
  • WindowStyle: 「最大化」とか「閉じる」ボタンが表示される外枠を消す
  • Background: ウィンドウ全体の背景を透明色にする

ちなみにこうした非矩形ウィンドウを表示する為の内部機構としてはレイヤードウィンドウというのが使われてるようですが、WPFではレイヤードウィンドウの事を意識する必要はありません。単に上の3つをおまじないだと思ってれば十分使えます。

 

キーボードが叩かれたことを検知する

ここからようやくC#コードの出番です。

まず「社畜ちゃんタイピング」の重要な特徴として「キーボードを叩くと反応する」というのをやってますが、これは実は他の方が作って下さったものの流用です。やりたいことで調べてみるとキーボード操作へイベントをグローバルフックする方法というドンピシャな記事が出てくるので、コチラをそのままコピペして使えばOKです。ソースの中では"KeyboardHook.cs"というファイルがコピペしたものになってますが、変更として名前空間だけ"ShachikuChanTyping"に書き直しています。

 

ウィンドウを画面左下へ持っていく

ウィンドウのコードビハインド(ShachikuChanWindow.xaml.cs)を見てもらえば分かるんですが、Screenクラスを使ってスクリーンサイズを取得することで左下への移動を可能にしています。

ただし昨今のディスプレイではインチ当たりドット数(DPI)が高いモノもあるのでDPI対応をしっかりしないといけません。例えば私が持ってるVAIO Zの場合DPIが通常のディスプレイの2倍あるため、適当に座標計算をすると社畜ちゃんが画面外に表示されるというようなバグが起きてしまいます。DPIを考慮した位置計算プログラムはこんな感じです。

//"System.Windows.Forms.dll"をプロジェクトの参照に追加すること

...

/// <summary>スクリーンの左下にウィンドウを移動させます。</summary>
private void RelocateToLeftBottom()
{
    var area = System.Windows.Forms.Screen.GetWorkingArea(System.Drawing.Point.Empty);

    var dpiFactor = GetDpiFactors();
    this.Left = (area.Left) / dpiFactor.X;
    this.Top = area.Bottom / dpiFactor.Y - this.Height;
}

/// <summary>
/// DPIの補正値を取得します。
/// </summary>
/// <returns>DPI補正値(例: 192dpiなら192 / 96 = 2, 144dpiなら1.5)</returns>
private System.Drawing.Point GetDpiFactors()
{
    var g = System.Drawing.Graphics.FromHwnd(IntPtr.Zero);
    return new System.Drawing.Point(g.DpiX / 96.0, g.DpiY / 96.0);
}

意外にサクッと書ける事が分かります。

 

設定のロードセーブ機能を追加

ソースコード内の"ShachikuChanSetting.cs"では外部ファイルからロードしたり保存したりできる設定内容を扱っています。地味ですが「最前面表示」とか「表示サイズ」といったパラメータを保存した方が使い勝手がいいですからね。

と言っても".ini"みたいなファイルを書くのはダサいのでココではXmlSerializerを使ってます。

using System.IO;
using System.Xml.Serialization;

...

const string SettingFileName = "hoge.xml";

/// <summary>設定を保存します。</summary>
public void Save()
{
    using (var sw = new StreamWriter(SettingFileName))
    {
        var serializer = new XmlSerializer(typeof(ShachikuChanSetting));
        serializer.Serialize(sw, this);
    }
}

/// <summary>保存済みの設定または既定の設定を取得します。</summary>
public static ShachikuChanSetting Load()
{
    using (var sr = new StreamReader(SettingFileName))
    {
        var serializer = new XmlSerializer(typeof(ShachikuChanSetting));
        return serializer.Deserialize(sr) as ShachikuChanSetting;
    }
}

なお実物のロード関数にはtry catch文がついてますが、見やすさの観点からコチラでは省略しています。

こうするとShachikuChanSettingクラス内で定義されたpublicプロパティが全てロード/セーブの対象になります。ちなみにXmlSerializerより保存内容を細かく設定したい場合はDataContractSerializerを使う方法もあります。

 

その他GUIの小技

細かいですが重要な事として、キャラを掴んで動かせるようにするためにDragMove関数を使ったりしてます。具体的なコードで言うと"MainWindow.xaml.cs"内のコレですね。

/// <summary>社畜ちゃんが左クリックで掴まれた時の処理です。</summary>
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
    base.OnMouseLeftButtonDown(e);
    this.DragMove();
}

コレ以外にも小技はいくつか仕掛けてますが全部紹介すると結構長くなっちゃうので、続きはソースコード見て下さい。

 

 

まとめ

結論だけ言うなら「WPF/C#の組合せでアジャイルなデスクトップマスコット開発が可能です」というお話でした。いちおう本記事の参考図書というか私がC#/XAMLの勉強で読んだ本を紹介しておきます。

オライリーの「プログラミングC#」は第7版より第6版の方が初心者向きでオススメ出来ます。また「プログラミングWindows 第6版」はWindowsストアアプリをメインターゲットに据えて書かれてますが、XAMLの解説が重視されているおかげでWPF用の教科書としても相当優秀です。

 

アニメーションの作成については別件で記事化する予定ですので続報をお待ち下さい。