ラベル 備忘録 の投稿を表示しています。 すべての投稿を表示
ラベル 備忘録 の投稿を表示しています。 すべての投稿を表示

2012年5月21日月曜日

"GenerateResource" タスクが予期せずに失敗しました!?

と言うことで、久々にVSをいじったところ、ソースは同じなのにビルドエラーが出る!?
色々と調べてみたところ、環境変数のTEMP,TMPにドライブルートを設定していたことが問題だと発覚(こちらのページを参照)。
ルートではなくその下にフォルダを作ってそちらを設定することで事なきを得ました。
最近RAMディスクを使うようになったんだけど、まさかこんなところで弊害が出るとは…。
ちなみに私は次のバッチファイルをスタートアップに入れてtmpフォルダを起動時に自動作成しています。

@echo off
mkdir t:\tmp

問題が解決したところで、Diablo3も程々に更新に手を付けなくちゃなぁ。。。

以下、ガチ備忘録
アプリケーションタブに表示しないようにするには
  • 非表示でないWindowをOwnerに設定
  • 拡張スタイルにWS_EX_TOOLWINDOW(0x0080)を設定
  • Windowを非表示にする(本件ではこれは使えない)

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