コードは嘘を付きません。世には四月馬鹿などと言う行事もあるようですが、コードだけなら何も問題はありません。ま、私は明日更新するつもり無いですけど。
ごく簡単なランチャを 1 時間ぐらいででっちあげたんですが、そのときにフォームのサイズの変更を制限したいなと思いまして。取りあえず Resize イベント辺りで元サイズに書き戻すように実装してみたらこれがまあちらついて堪りません。
じゃあどうするかという時に、イベントを探すんではなく Windows メッセージを探すのが私の捻くれたところ。WM_WINDOWPOSCAHNGING をハンドルすれば目的を達成できそうでした。
ちょっとした問題点として、このメッセージの LParam が構造体へのポインタであることが挙げられます。C++/CLI ならともかく、C# では Marshal クラスで構造体にコピーするか unsafe コンテキストでポインタとして扱うかってことになりますが、それ以前に構造体の宣言が面倒です。
そこで、ここは一つ Marshal.ReadInt32/WriteInt32 で直接いじることにしました。注意するのはオフセットで、構造体の先頭に HWND 型があるため固定値決め撃ちってわけにはいきません。Marshal.SizeOf もありますが、もうちょっと簡単に IntPtr.Size プロパティを使って計算しましょう。
以下に、簡単な実装コードを書いておきます。なお、WM_WINDOWPOSCHANGING に使われる WINDOWPOS 構造体には Z オーダー位置、各種フラグが用意されていますが、簡便のため今回の実装では位置とサイズしか処理しません。興味のある方は調べてみて下さい。
ちなみに、これで高さを固定して、フォームの上辺を掴んでリサイズさせようとしたりすると結構気持ち悪い動きになります。
以下コードと使用例今回は、どこが元ネタだったかはちょっと失念しましたが、掲示板で見かけた Thumbs.db のお話。
エクスプローラなどで「縮小」で表示した場合、Thumbs.db という隠しシステムファイルが作成され、二回目以降はここからサムネイルのキャッシュを抽出することで表示速度を上げています。これを我々も利用することはできないか。
実のところ、私自身はエクスプローラを(ファイラとしては)ほとんど使わないし、ましてや縮小表示など、という人なのであんまり意味は無いんですが。
そういう質問に対し、どなたかが IShellImageStore インターフェイスを使えばどうか、と提案なさっていたのが目に留まったので、早速調べてみました。なかなか情報が少なかったんですが。
MSDN にはIShellImageStore の解説 とサンプルコード が挙げられています。と言うか参考になりそうな記述はほぼこれだけです。あとは最新版の Windows SDK のヘッダファイルでインターフェイスの構造や GUID を調べるぐらい。
そんなに複雑なものでもないしコーディング自体は割りとあっさり終わりました。画像も取得できます。まずそれを提示しましょう。
続きを読む久々にしてちょっとお馬鹿っぽい一つの解決。
VBレスキュー(花ちゃん)のVB.NET・VB2005用掲示板 の、コマンドラインの引数について というスレッドを見て思いついたのですが。
コマンドライン引数には文字列しか使えないので、オブジェクトは渡せません。
さて、IFormatter や XmlSerializer などを使えばオブジェクトを永続化でき、他のアプリケーションともやり取りできます。でも SoapFormatter や XmlSerializer は長ったらしくなるのでコマンドライン引数の文字数制限に引っかかりそうな気がするし、BinaryFormatter はそれ以前にバイナリなんで問題外です。
ここでふと思い出したのが、Base64 です。これならバイナリを文字列に変換できます。使用される文字はMSDN の Convert.ToBase64String メソッドの解説 に以下のように書かれています。
Base64 形式の文字を 0 から昇順で並べた場合、大文字の "A" 〜 "Z"、小文字の "a" 〜 "z"、数字の "0" 〜 "9"、および "+" と "/" の記号の順になります。値として解釈されない文字 "=" は、文字列末尾の埋め込み用に使用されます。
半角空白やダブルクォーテーションが含まれておらず、全く普通にコマンドライン引数として利用可能な文字のみが使われています。おお、これならいける。
つまり、BinaryFormatter でシリアライズし、それを Base64 でエンコーディングして引数に渡す。渡された側はデコードしてデシリアライズする。という手順を踏めば問題なく受け渡し可能と言うことになります。
早速コードを書いてみましょう。エラー処理なんかやってないのでデシリアライズ時は注意。使い方は、まあ言うまでもないですよね。当然の事ながら、引数として渡すアプリケーションと受け取るアプリケーションは双方がこの Hoge クラスを定義しているアセンブリを参照しておく必要があります。
XmlSerializer なら、型と名前さえ同じなら同じクラス(同じクラスであるというのはつまり端的に言うとでなくてもデシリアライズできるので、自由度が高いかも知れません。XmlSerializer は XmlSerializer で難しい部分もありますけど。
続きを読むここ(hongliang.seesaa.net)で公開しているものについて、利用は自由に行って頂いて構いません。改変、再頒布もお好きになさって下さい。利用に対しこちらが何かを要求することはありません。
ただし、公開するものを使用、または参考したことによって何らかの損害等が生じた場合でも、私はいかなる責任も負いません。
あ、こんなのに使ったってコメントを頂ければ嬉しいです。
この広告は90日以上新しい記事の投稿がないブログに表示されております。