2012年2月27日月曜日

[akinosign] akinosignを公開しました

akinosignはIMEの日本語入力オン/オフの状態を示すサインを表示するアプリケーションです。
(ダウンロードはこちら(Vector)からどうぞ)
日本語を入力するつもりでキーボードを打ったは良いけどもアルファベットが表示されてしまって仕方なく打ちなおす、と言うような事態を防止することが狙いです。
#IMEオンの状態でのひらがな/アルファベットモードの区別は表示しません。対応しているのはIMEのオン/オフ状態のみです。

akinosignは以下の特徴を持ちます。
  1. テキストエリアにフォーカスがある場合にのみIMEのオン/オフ状態を示すサインを表示します。テキストエリア以外ではサインを表示しないため、本来の作業の邪魔になりません。
  2. テキストエリアの大きさによってサインの表示方法を切り替えることができます。1~2行の検索ボックス等ではサインをテキストエリア下辺に表示して、テキストエディタ等の大きなテキストエリアではマウス横にサインを表示する(orサイン自体を表示しない)ことができます。
  3. サインはフォーカス移動時、及びオン/オフ状態の切り替え時に表示されます。サインは指定時間経過後に自動で非表示にすることができます。
図1.テキストエリア下辺にサインを表示
図2.IMEオン/オフでサインの色が変わります(IMEオン:橙、オフ:黒(既定))
図3.テキストエリアの高さが大きい場合はマウスの横に表示

Webページを閲覧しては検索ボックスにキーワードを入力して再度ブラウジングに戻る、ようなテキストエリアとそれ以外を行き来する場合にIMEの状態がよく分からなくなります(少なくとも私は)。
逆に同じテキストエリアで作業を続けている間はIMEの状態が分からなくなることは比較的少ないと感じています。
akinosignは特に前者に焦点を当てています。
前者の場合はテキストエリアが1,2行である場合が多いため、視認性を考慮してテキストエリア下辺にサインを表示します。
しかし、後者の場合はテキストエディタなど、複数行に渡る(高さが大きい)テキストエリアの場合が多いと考えられます。
その場合には下辺のサインは見にくい恐れがあるため、テキストエリアの高さによる表示サインの切り替え(3.)を用意しています。

類似ソフトは既に色々と存在していますが、私の好みに合うものが見つからなかったことが開発の動機です。
特にテキストと関係のない場所でIME状態の表示が出る点がどうしても受け入れられませんでした。。。
ですので、基本的に私の好みに合わせた機能、調整になっております(演出過多な部分も多いです)が、 お気に召した方は是非ご利用してみて下さい。

【注意点その1】
  • akinoboardと同様に、管理者権限で実行されているアプリケーション上ではakinosignは正常に動作しません。ただし、akinosignも管理者権限で実行している場合にはその限りではありません。
  • アクセシビリティ用の設定画面が自動で開くアプリケーションがあります。Adobe Readerでは「文書読み上げオプション」が表示される場合があります。特に問題がないようでしたら、デフォルトの設定のままで「読み上げ環境設定の設定を常に使用する」をチェックして下さい。
  • XP環境では動作確認していません。

【注意点その2】
akinosignが正常に動作しないアプリケーションもあります。
これはアプリケーション側の仕様による場合が多く、基本的に対応は難しいです。
対応希望のアプリケーションがあれば、ご連絡いただけましたら対応できる場合には対応させていただきますが、あまり期待はしないで下さいね(^^;
参考までに、現在私の方で確認している非対応アプリケーションを記しておきます。 
  • アクセシビリティ機能に対応していないアプリケーション
  • Google Chromeのページ内テキストエリア
  • LibreOffice
  • Java上で動いているアプリケーション
  • ゲーム系
  • Visual Studio(エディタ部分の座標が適切でない)

2012年2月19日日曜日

リソースファイルへの参照URI

かなり嵌ってしまったので備忘録として残しておく。

WPFでリソースファイルを参照するには、そのリソースを指すURIを指定する。
なお、前段となるリソースの登録は以下の通り(絶対コレと言うものではない)
  • プロジェクト→既存項目の追加(サブフォルダに入れるのも可)
  • リソースのプロパティ→ ビルドアクション:Resource(埋め込まれたリソースではない)
今回はプロジェクトルート直下のImagesフォルダに画像を登録したとする。
".\Images\picture.png"

リソースがローカルアセンブリに格納している場合には、このリソースを指し示す絶対パス(パッケージ)のURIは次のようになる。
"pack://application:,,,/Images/picture.png"

パッケージのURIについては詳しくはここを見てもらうとして、今回嵌ったのは相対URIになる。
上記絶対URIの相対URIは"/Images/picture.png"となるはずだが、今回BitmapImage.StreamSourceにこの相対URIを指定すると、全く意図した動作をしなかった。
具体的には、先頭に"/"を付けるとアセンブリが置かれているドライブのルートを起点としたURIとして、"/"を付けないとアセンブリを起点としたURIとして扱われた。
なお、XAMLでは問題なく相対URIを指定して想定通りの動作になる。
加えて、これはWPFの話でSilverlightでは相対URIでパッケージを指し示すことができるようだが、う~んよく分からん状態。。。

クラスによって相対URIの扱いが変わるのは分かっているが、それは通常のファイルパスだけだと思っていたんだけど、パッケージについても同様のようだ。
#ファイルパスもURIだから当たり前と言っては当たり前なのかもしれないが…

あまり時間が取れないのできちんと調べることができず、明確な仕様は分からなかった。
現時点では解決策としては絶対URIで指定することくらいかな。
もし同じ問題で嵌った人がいれば、解決策だけでも少しはヒントになれば幸いですね。

2012年2月13日月曜日

WPFでウィンドウメッセージを処理する

久々にプログラミングの話をば。
前からそうだけどプログラミングTipsのようなものを備忘録的に記していっているので、"備忘録"タグを今度からつけようと思います。

で、今回はWPFでウィンドウメッセージを処理する方法。
WindowsFormではForm.WndProcメソッドをオーバーライドするだけで良かったけど、WPFではその方法は使えない。
WPFではHwndSourceクラスのAddHookメソッドを使うことで、所謂ウィンドウプロシージャとほぼ同様の役目を果たすことができる。

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

    WindowInteropHelper helper = new WindowInteropHelper(this);
    HwndSource source = HwndSource.FromHwnd(helper.Handle);
    // もしくは
    // HwndSource source = PresentationSource.FromVisual(this) as HwndSource
    source.AddHook(new HwndSourceHook(WndProc));
}

static IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
    switch (msg)
    {
        case Win32.WM_MOUSEACTIVATE: // 処理するメッセージ
            handled = true; // ここでメッセージを止める場合はtrue
            return new IntPtr(Win32.MA_NOACTIVATE); // メッセージや処理によって適切な値を返す
    }
    return IntPtr.Zero;
}

ちなみに上記はマウスクリックでウィンドウをアクティブにしないように変更するコードです。
昔のエントリーでは、ウィンドウメッセージを処理する以外の方法を紹介していますので、興味があったらそちらもどうぞ。

WPFでは基本的にはウィンドウメッセージを直接扱う機会は少ないんだけど、他ソフト(プロセス)と関わりあう類のソフトウェアキーボード等のソフトを作る際には触らなければならない場合も少なくないので正直面倒ですね。。。

2012年2月5日日曜日

IMEチェッカー再始動

年末から拘っていた毛筆演出がどうにかなったのでIMEチェッカーの開発を再始動しました。
単にPhotoshopの毛筆ブラシで画像を作ることにしただけだけどw
それに伴ってソースを見なおしたんだけど、変数名やアルゴリズムを改めて見ると分かりにくかったため、一から作り直す予定。
と言っても、基本部分は変わらないためそんなに時間はかからないはず。
IME状態とフォーカスオブジェクトの取得部分はできているので、今後の課題は毛筆オブジェクトの表示部分になります。
テキストエリアが狭い(数行程度)場合はテキストエリア自体に毛筆オブジェクト(横線)を被せて、広い場合はマウスの横に毛筆オブジェクト(チェックマーク)を表示する予定。
ただ予定は未定なので、上記表示方法切り替えはバージョンアップ後に回すかも知れない、かな…。