2011年6月25日土曜日

タイトルバーを持たない&透明なウィンドウを作成する

先日の投稿でそろそろ文字やキーの送信処理について書いていこうと言ってたんだけど、表題の設定を前提にしていたため、まずはその説明を取り敢えずしとかないとまずいかなとも思ったので、それについて書きます。
ほーんのわずかだけど検索で飛んできてくれてる人もいるみたいだしね。
ちなみに、ここが足りないとかもう少し詳細にとかあれば、遠慮無くコメント付けてもらえると嬉しいです。

  • タイトルバーを持たないウィンドウ
これは単純にWindowクラスのWindowStyleプロパティをWindowStyle.Noneに設定するだけ。
ちなみにその他のWindowStyle列挙体はこちらを参照。
なお、後述するAllowsTransparencyプロパティをtrueにしている場合にはNone以外は設定できないので注意。

  • (背景が)透明なウィンドウ
WPFになってからとても簡単になったね、ここの項目は。
WindowクラスのAllowsTransparencyプロパティをtrueに設定して、Backgroundでアルファ値、もしくはOpacityを調整すれば、それだけでもう透明なウィンドウが作れちゃいます。

ちなみに先日の変形ウィンドウについての投稿で、タイトルバーを持ってかつ透明でないウィンドウだと以下のようになります。
クリップしたところが黒くなって、わざわざ手間をかけて変形させたことがマイナスにしか働かないねw


まったく関係ないですが、本投稿はShadowloo Showdown 2011を見ながら書いています。
格ゲーの腕はへっぽこぴーですが、盛り上がっていって欲しいですねー!
弱春風後の小Kを失敗しないようになりたい今日この頃…。

2011年6月21日火曜日

ウィンドウやコントロールの形状を変更する

 一般的な通常のウィンドウ(の形状)を持ったソフトウェアキーボードでも何も問題ないんだけど、少し形状に手を加えることで使う側として何だか楽しくなると個人的に感じています。
WPFではウィンドウを含むコントロールの変形が非常に簡単にできるんだけど、私がよく使う手法は以下の2つ。

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    // ウィンドウの形状を変更
    RectangleGeometry r = new RectangleGeometry(new Rect(0, 0, this.ActualWidth, this.ActualHeight), 30, 30);
    this.Clip = r;

    // ボタンの変形
    button1.RenderTransform = new RotateTransform(10, 45, 45);
}

Clipプロパティに望む形状のGeometryを設定して形を変更する方法と、RenderTransformプロパティに望む変形に対応するTransformクラスを設定する方法です。
用意されているTransformのサブクラスはこちらを参照
このような角が丸みを帯びたウィンドウや傾いたボタンを簡単に作成できます。

よく考えればソフトウェアキーボードの本筋とは少しずれた話ばかりしている気もしないでもないので、次はアプリケーションに文字やキー情報を送る方法でも書くつもり。
ただこのブログはほぼ備忘録orチラ裏なので、予定は未定が前提となっております故、ご了承下さい。

それ以前に、最近暇ができてもスパ4AE比翼恋理のだーりんばかりで、肝心のソフトウェアキーボードの作成があまり進んでいなかったりする…w



2011年6月6日月曜日

家庭用ジャングルジム&ブランコ

半年以上前に家庭用のジャングルジム&ブランコのアンパンマン NEW ブランコパークDXを買ったんだけど、当時1歳程度のうちの娘は殆ど見向きもしませんでした(-_-;
しかし、最近になって急に覚醒して登るは潜るわの大はしゃぎ(娘は1歳半)。
勉強代として半ば諦めていたんだけど、こういうおもちゃは急ぎすぎてはダメなんだな、と学んだ次第でございます。
ちなみにこのブランコパークDXは作りもしっかりしていてお値段もそこまで高くないのでオススメですよ。


2011年6月5日日曜日

プロパティ名の表示がトリミングされすぎる

以前からそうだったのか不明だが、プロパティウィンドウ内のプロパティ名が横幅に完全に余裕があるのに無意味にトリミングされる。
例えば"height"と表示する横幅が十分にあるにも関わらずが"hei..."と省略記号付きになるのね。
そろそろきちんとソフトウェアキーボードの作成を始めようと腰を上げた分、余計に気になったのかも知れない。

開発的には問題ないけども喉の奥に小骨が刺さったような歯がゆさがあったので、仕方なくVSを再インストールするも治らず(>_<
何回かアンインストール、インストールを繰り返してみたけど症状は何も変わらず。。。

試行錯誤の結果、ディスプレイ設定のテキストの大きさが原因でした。
この項目は大中小がデフォルトで選択できるんだけど、細かい値をカスタムできる。
ここで大中小以外の値でカスタムしていると、上記の症状が出るみたい。

再インストールする前には勿論ネットを検索してみたんだけど、クエリが上手く設定できなくて碌な情報が手に入らなかったこともあって、無駄に労力がかかってしまった…。

2011年6月4日土曜日

タイトルバーのドラッグ以外でウィンドウを移動する

ソフトウェアキーボードではタイトルバーを持たない形(WindowStyle.None)を取ることが多いです。
その場合にはタイトルバーをドラッグしてウィンドウを移動すると言う一般的な方法は使えません。

その代替として有効な手段が、領域内を左クリックドラッグでウィンドウを移動する方法です。
WPFではWindowクラスのDragMove()を使うことで非常に簡単に実装することができます。
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
    base.OnMouseLeftButtonDown(e);

    this.DragMove();
}

ただ、先日の投稿の方法でアクティブにならないウィンドウを作った場合には、ドラッグ中のフィードバックが行われません。
#マウスアップまでウィンドウが移動しない
これはタイトルバーを残していた場合にも同様です。

私は見かけ的に好きではないので、以下のようにしてマウスドラッグ時にウィンドウを移動しています。
bool dragFlag;
Point offset;

private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    dragFlag = true; // ドラッグ開始
    offset = e.GetPosition(this); // 開始位置の記録
}

private void Window_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
{
    if (dragFlag) // ドラッグ時のみ
    {
        Point p = e.GetPosition(this); // 現在のマウス座標
        // ウィンドウを移動
        this.Left += p.X -offset.X;
        this.Top += p.Y - offset.Y;
    }
}

private void Window_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
    dragFlag = false; // ドラッグ終了
}

この方法だとマウスムーブに合わせてきちんとウィンドウが移動されます。
今回だけに言えることじゃないですが、これがベストの方法とは限らないことを理解いただいた上で、参考にしていただけると幸いです。

2011年6月3日金曜日

Windows APIリスト

頑張って投稿を続けているけど確実に頻度は下がっていくだろうなw

窓の杜に『主要なWindows APIのドキュメントをリスト化した“Windows APIリスト”が公開』の記事が公開されています(リストの場所はこちら)。
今後私が紹介する予定のAPIも沢山載っているので参考にされては如何でしょうか。
MSDNを普通に検索するよりも、利用されるジャンルで分類されているため分かりやすいと思います。

育児系も書いてみる

ソフトウェア系もそうなんだけど、育児系は完全にチラシの裏です。
お暇でしたら、あぁこいつの近況はこんなんなんか、と流し読んで下さいw

と言うことで、1歳半になる娘がいるわけなんですが、最近トイレに勝手に入っては蓋をチョンチョンと叩く。
そして、子供ちゃれんじで送られてきたトイレのおもちゃ、と言っても20cm四方のぬいぐるみを置くものなのですが、それに座ってしーしー言って自己主張。
ただ、まだいらんだろうと「おまる」は買っていなかったんだけど、逆に娘のやりたい心に親がついて行けてないのではないかと凹んで、急遽おまるを探してみた。

それで一番上に出てきたのが「ポッティス イス型おまる」。
アマゾンだけど楽天で探してみてもランキング1位でした。
今っておまるでも足を横に出すのではなく、普通の洋式トイレでする時みたいに前に出すタイプになってるんだねぇ。
もちろん横タイプも多いですが、びっくりしたので取り敢えず育児一発目の記事にしてみましたー。
ちなみに今からちょうどこれを買いますので、感想も後日ここに載せたいと思います♪

でも初めから分かっていたことだけど、ソフトウェア系と育児系を同じブログに載せるのは、割と違和感があるなぁ(^^;



2011年6月2日木曜日

フォーカスを奪わないウィンドウ

まず、ソフトウェアキーボードのウィンドウは他ウィンドウからフォーカスを奪わないようにしなければなりません。
ソフトウェアキーボードのデザインは多種多様にあるけど、 私が想定している動作は、自作ソフトウェアキーボードからフォーカス(キャレット)を持つコントロールへ仮想キーコード、もしくは文字コードを送信するパターンになります。
これらを前提としてブログを書き進めていきますので、ご了承下さい。

私が調べたところ、上記を実装する手段は大まかに次の通り。
  1. ウィンドウがアクティブにならないようにする
  2. フォーカス遷移を記録しておいて、コード送信時にフォーカスを以前のウィンドウに戻す
  3. フォーカスメッセージをフックして、受け取らない(元フォーカスがあったウィンドウに再送)
 何通りか試してみたけど、やはり一番上手く想定通りの動作をするのは1.のやり方でした。
2.も「ソフトウェアキーボード上で操作して情報を元のウィンドウに送る」と言う動作自体は問題ありませんでした。
ただ、タスクバーやウィンドウの外観がアクティブウィンドウが変わる度に変化(フィードバック)するので見かけ上気持ち悪いんだよね。
3.は上手くやればできるのかもしれないけど、(私の力量では)安定性が低かったり、グローバルフックは将来的に公開するときに色々と面倒そう、と感じたので却下。

無駄な文を長々と書いてしまったけど、私は次のようにして1.を実装することにしました。

[DllImport("user32.dll")]
static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
[DllImport("user32.dll")]
static extern int GetWindowLong(IntPtr hWnd, int nIndex);

private const int GWL_EXSTYLE = -20;
private const int WS_EX_NOACTIVATE = 0x08000000;

protected override void OnSourceInitialized(EventArgs e)
{
    base.OnSourceInitialized(e);

    WindowInteropHelper helper = new WindowInteropHelper(this);
    SetWindowLong(helper.Handle, GWL_EXSTYLE, GetWindowLong(helper.Handle, GWL_EXSTYLE) | WS_EX_NOACTIVATE);
}

(ソフトウェアキーボードの)メインウィンドウにSetWindowLong()でWS_EX_NOACTIVATEを設定することで、アクティブにならないウィンドウの作成が可能。
なおWPFで実装しているため、ウィンドウハンドルを取得する部分がその前段となります。
ちなみにタスクバーやAlt-tabで選択した場合にはアクティブになるので、扱いには一工夫必要かな。

このようなブログを書くのは始めてなので、折角見ていただいてもよく分からない説明になっているかも知れません…。
もし詳しく説明してくれって人がいたらコメントでもして下さい。
#それ以前のページビューだけどねw

2011年6月1日水曜日

当面の開発テーマ

取り敢えず、ソフトウェアキーボードを作っていこうと思います。
今更感があるかもしれないけど、Windows7のマルチタッチ環境を想定します。
iPhone、Androidなど携帯端末向けに作成しようとも考えたんだけど、MAC持ってないし、Javaももう10年以上触ってない。
ただででもあまり時間がないので言語やクラスライブラの把握から始めるのは面白いけれども厳しいということで、Windows環境を対象に選んでみました。
将来的にはWindowsPhone7に向けて考えていきたいけど、WP7は生き残り以前に少しでも日本市場で流行るのかなぁ?w

と言うことで、基礎から調べながら実装していく予定なので、まずは普通のソフトウェアキーボードを作っていくつもりです。
タッチでもマウスでも操作はできるようにはするつもりだけど、タッチならではのインタラクションを検討したりするのは次の段階かな。
本命は新しい文字入力手法を開発すること。
たとえば、ShapeWriterなどに代表されるような、従来とは異なる、よりユーザに取って使いやすく効率的なシステムを開発していきたいな。

ある程度は調べ始めているので、次からはソフトウェアキーボードを作る上で私が必要だと判断したAPI(性格上Win32APIが多い)を紹介しつつ、完成したら公開する予定です。
このブログを見てくれる人がいるのか分からないけど、取り敢えず公開だけはしとこうw