2010年12月09日

"ASSOCIATORS OF" on System.Management

HDDフォーマット形式の取得方法 - Insider .NET会議室 より。

回答にて ちなみに、WMI でドライブレターからそのパーティションを探すには、Win32_LogicalDiskToPartition を使用できます。.NET(System.Management)だと使いづらいんですが。 などと書いてしまったわけですが、単に私の勉強不足による誤解でした。

ある WMI クラスインスタンスに関連するクラスインスタンスを取得するのに、WQL で ASSOCIATORS OF クエリを使うことができます。C ドライブの Win32_DiskPartition を取得するにはこんな感じのクエリになります。見れば大体分かると思うので解説は略。

ASSOCIATORS OF {Win32_LogicalDisk.DeviceID='C:'} WHERE
     ResultClass=Win32_DiskPartition AssocClass=Win32_LogicalDiskToPartition
     ResultRole=Antecedent Role=Dependent

上記はきわめて丁寧に書いた場合で、手を抜ききるとこんな感じになります。

ASSOCIATORS OF {Win32_LogicalDisk='C:'} WHERE ResultClass=Win32_DiskPartition

もちろん、System.Management でもこのクエリを使うことができます。ManagementObjectSearcher のコンストラクタに直接上記のクエリを渡すのが手っ取り早いでしょう。

クエリ構文が思いつかない、という場合、パラメータを渡すことで ASSOCIATORS OF クエリの構築を行ってくれる RelatedObjectQuery クラスも存在しています。このクラスを使った場合はこんな感じになります。

// 丁寧に書いた版
var query = new RelatedObjectQuery("Win32_LogicalDisk='C:'", "Win32_DiskPartition",
    "Win32_LogicalDiskToPartition", null, null, "Antecedent", "Dependent", false);
var searcher = new ManagementObjectSearcher(query);
// 省略版
var query = new RelatedObjectQuery("Win32_LogicalDisk='C:'", "Win32_DiskPartition");
posted by Hongliang at 21:25| Comment(10) | TrackBack(0) | .NET | このブログの読者になる | 更新情報をチェックする

2010年01月08日

WPF 上の pack URI

Generic.xamlの中のImageのSourceを、相対パス指定する方法について で私が自分自身で触れたにも関わらず実際には良く理解していなかった pack スキームについての調査。

資料はコレ、Windows Presentation Foundation におけるパッケージの URI ですね。そのもととなる Open Packaging Conventions の仕様をまず見ろと言う話かも知れませんが、知りたいのはプログラム上の話ですし。

なお、Open Packaging Conventions の仕様は ISO/IEC 29500-2 Open Packaging Conventions (OPC, 2008)(zip ファイル)に存在しているみたいです。

続きを読む
posted by Hongliang at 21:51| Comment(0) | TrackBack(0) | .NET | このブログの読者になる | 更新情報をチェックする

2008年04月06日

二次元配列をもっとビュー 4

四回目。前回は Sort プロパティを設定したときに DataGridView などに通知する機構を追加しました。今回は要素が変更されたときの通知です。なお、面倒なので以降の記事では TwoDimensionalArrayView を ArrayView と、TwoDimensionalArrayRowView を ArrayRowView と書くことにします。

話しに入る前に、前回の終わりでちらっと触れた AllowEdit を書き換えておきましょう。これで DataGridView で表示しているときに値を編集できるようになります。まあ後からコードで AllowEdit を操作することもできるんですが、一般的には編集可能がデフォルトでしょうし。

// デフォルト値を変更
private bool allowEdit = true;

ListChangedEventArgs で利用される ListChangedType 列挙体には、リスト全体が変更となったことを表す Reset の他に、ItemAdded や ItemDeleted、ItemMoved などが存在しています。固定長である二次元配列には一見縁がなさそうですが、ListChanged イベントの対象となるリストは飽くまで ArrayView、つまり ArrayRowView の並び方が問題なのです。値を変更した結果 ArrayRowView の順序が変更されれば ItemMoved の ListChanged イベントを起こすさせる必要があります。また今回取り扱う予定はありませんが Filter(RowFilter)が適用されているとき(Filter を適用したタイミングでは Reset です)、そのフィルタから外れるように値が変更された場合は ItemDeleted の ListChanged を起こすことになります。

続きを読む
posted by Hongliang at 02:31| Comment(0) | TrackBack(0) | .NET | このブログの読者になる | 更新情報をチェックする

2008年03月31日

二次元配列をもっとビュー 3

三回目。今回はソートしたときに DataGridView が無視してくれる問題についてです。といってもまあ自明の理なんですがね、

まず IBindingList の解説を少し引用しましょう。

ApplySort メソッドまたは RemoveSort メソッドを呼び出す場合は、Reset 列挙体を使用して ListChanged イベントを発生させてください。

ということでこれが原因です。このイベントを使わないと、DataGridView はデータソースにソートが適用されたタイミングを窺い知ることができません。

ではさくさく実装していきましょう。

続きを読む
posted by Hongliang at 07:20| Comment(0) | TrackBack(0) | .NET | このブログの読者になる | 更新情報をチェックする

2008年03月29日

二次元配列をもっとビュー 2

前回の続き。今回はソート機能の実装です。あ、その前に言っておくと、この TwoDimensionalArrayView<T> クラスはできる限り DataView に近づけたクラス構成にするつもりです。

さて、ソートの実装自体はそんなに難しいことではないでしょう。まず前回の雛形からソート関連の部分をピックアップします。

private List<TwoDimensionalArrayRowView<T>> arrangedViews;
bool IBindingList.SupportsSorting { get { return false; } }
bool IBindingList.IsSorted {
    get { throw new NotSupportedException(); }
}
ListSortDirection IBindingList.SortDirection {
    get { throw new NotSupportedException(); }
}
PropertyDescriptor IBindingList.SortProperty {
    get { throw new NotSupportedException(); }
}
void IBindingList.ApplySort(PropertyDescriptor property,
                            ListSortDirection direction) {
    throw new NotSupportedException();
}
void IBindingList.RemoveSort() {
    throw new NotSupportedException();
}

次に DataView のソート関連のメンバをピックアップ。

public bool ApplyDefaultSort { get; set; }
public string Sort { get; set; }

このうち ApplyDefaultSort は、「PrimaryKey を持っている DataTable の Sort が空のとき」に「PrimaryKey を使ってソートする」かどうか、というプロパティなので二次元配列には関係なし、除外。

続きを読む
posted by Hongliang at 12:31| Comment(0) | TrackBack(0) | .NET | このブログの読者になる | 更新情報をチェックする

2008年03月27日

二次元配列をもっとビュー 1

前回の 二次元配列をビュー では取り敢えず二次元配列をデータソースとして扱えるビューを作りました。今回はもうちょっと拡張します。長くなりそうなので連載形式で順次改造していくことにしようかと思っています。

データにはソートがつき物です。二次元配列自体はソートできませんが、そのビューならソートできてもおかしくありません。DataTable も行の並び替えはありませんが DataView にはソートが用意されていますし。

前回の TwoDimensionArrayView ではソートをサポートしていませんでした。というかそもそも前回のような実装ではソートの実現は困難です。構成から見直す必要があります。

その前にまず DataGridView などでカラムをクリックしたときなどにどのようにしてソートが実現されるのかを確認しましょう。前回にも書いた、データソースに使用できるインターフェイスを再掲します。

続きを読む
posted by Hongliang at 08:15| Comment(0) | TrackBack(0) | .NET | このブログの読者になる | 更新情報をチェックする

2007年03月31日

固定なフォーム

コードは嘘を付きません。世には四月馬鹿などと言う行事もあるようですが、コードだけなら何も問題はありません。ま、私は明日更新するつもり無いですけど。

ごく簡単なランチャを 1 時間ぐらいででっちあげたんですが、そのときにフォームのサイズの変更を制限したいなと思いまして。取りあえず Resize イベント辺りで元サイズに書き戻すように実装してみたらこれがまあちらついて堪りません。

じゃあどうするかという時に、イベントを探すんではなく Windows メッセージを探すのが私の捻くれたところ。WM_WINDOWPOSCAHNGING をハンドルすれば目的を達成できそうでした。

ちょっとした問題点として、このメッセージの LParam が構造体へのポインタであることが挙げられます。C++/CLI ならともかく、C# では Marshal クラスで構造体にコピーするか unsafe コンテキストでポインタとして扱うかってことになりますが、それ以前に構造体の宣言が面倒です。

そこで、ここは一つ Marshal.ReadInt32/WriteInt32 で直接いじることにしました。注意するのはオフセットで、構造体の先頭に HWND 型があるため固定値決め撃ちってわけにはいきません。Marshal.SizeOf もありますが、もうちょっと簡単に IntPtr.Size プロパティを使って計算しましょう。

以下に、簡単な実装コードを書いておきます。なお、WM_WINDOWPOSCHANGING に使われる WINDOWPOS 構造体には Z オーダー位置、各種フラグが用意されていますが、簡便のため今回の実装では位置とサイズしか処理しません。興味のある方は調べてみて下さい。

ちなみに、これで高さを固定して、フォームの上辺を掴んでリサイズさせようとしたりすると結構気持ち悪い動きになります。

以下コードと使用例
posted by Hongliang at 22:16| Comment(0) | TrackBack(1) | .NET | このブログの読者になる | 更新情報をチェックする

2007年03月21日

Thumbs.db と COM

今回は、どこが元ネタだったかはちょっと失念しましたが、掲示板で見かけた Thumbs.db のお話。

エクスプローラなどで「縮小」で表示した場合、Thumbs.db という隠しシステムファイルが作成され、二回目以降はここからサムネイルのキャッシュを抽出することで表示速度を上げています。これを我々も利用することはできないか。

実のところ、私自身はエクスプローラを(ファイラとしては)ほとんど使わないし、ましてや縮小表示など、という人なのであんまり意味は無いんですが。

そういう質問に対し、どなたかが IShellImageStore インターフェイスを使えばどうか、と提案なさっていたのが目に留まったので、早速調べてみました。なかなか情報が少なかったんですが。

MSDN には IShellImageStore の解説サンプルコード が挙げられています。と言うか参考になりそうな記述はほぼこれだけです。あとは最新版の Windows SDK のヘッダファイルでインターフェイスの構造や GUID を調べるぐらい。

そんなに複雑なものでもないしコーディング自体は割りとあっさり終わりました。画像も取得できます。まずそれを提示しましょう。

続きを読む
posted by Hongliang at 11:47| Comment(2) | TrackBack(0) | .NET | このブログの読者になる | 更新情報をチェックする

2007年03月15日

バイナリなコマンドライン引数

久々にしてちょっとお馬鹿っぽい一つの解決。

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 で難しい部分もありますけど。

続きを読む
posted by Hongliang at 23:49| Comment(0) | TrackBack(0) | .NET | このブログの読者になる | 更新情報をチェックする

2006年10月09日

IME 現在入力中

絶賛放置中の当サイトですが、流石にここまで放っておくのは些か気まずいので場繋ぎ的に更新。時間はどうとでもするんですが、どうにも心の琴線に触れるネタが無いんですよねぇ……。

さて、今回の更新は某掲示板にヒントを得て、IME を使用しての入力中かどうか取得するクラスです。入力中かどうかの状態が変わった時にはイベントを発生させます。とは言ってもごく簡単というか手抜きで、WM_IME_STARTCOMPOSITION と WM_IME_ENDCOMPOSITION を監視しているだけですので、インスタンス生成時に入力中だった場合は一旦入力が終了するまで正しい値を返しません。

続きを読む
posted by Hongliang at 02:41| Comment(0) | TrackBack(0) | .NET | このブログの読者になる | 更新情報をチェックする

2006年04月19日

いかに固定するか

日々拝読している akiramei さんの 匣の向こう側 - あまりに.NETな の記事で、Genericsとunsafe というのがあったのですが。

Marshal.UnsafeAddrOfPinnedArrayElement

これが勝利の鍵だ。

と言う結論ですが、これ間違いです。

MSDN の解説には次のように書かれています。

配列は、GCHandle を使用して pin を実行してあります。パフォーマンスを高めるため、このメソッドは渡された配列に対して一切の検証を行いません。この結果、予期しない動作につながることがあります。

分かりづらい文章ですね。原文だと極めて明快です。

The array must be pinned using a GCHandle before it is passed to this method.

このメソッドによって配列が自動的に固定されることはありません。配列を固定していない場合、このメソッドを呼び出した後に GC が起動して配列のアドレスが移動し、メソッドで取得したアドレスが無効になる可能性があります。

英文通り、事前に GCHandle.Alloc(object, GCHandleType.Pinned) で固定しなければいけません。で、GCHandle.Alloc したなら GCHandle.AddrOfPinnedObject メソッドを使うことで先頭アドレスが取得できます。

Alloc の第一引数はプリミティブなメンバしか含まない構造体でなければなりませんが、これの評価は実行時にされるので Generics でも問題なく使えます。

posted by Hongliang at 01:58| Comment(0) | TrackBack(0) | .NET | このブログの読者になる | 更新情報をチェックする

2006年04月14日

ListView とアイテムとフォーカスと

以前書いた C#とNTFSストリームの甘くない関係 ですが、今のところ五本の指に入るぐらいの人気(笑)にも関わらず内容はひどく寂しいものです。寂しいだけなら良いのですが、なにせ COM のことをほぼ全く理解していなかったときに書いた記事。思いっきり勘違いした上での愚痴ですので今は見るに堪えません。IDispatch と IUnknown をごっちゃにしてるんですよね。そのうち改めて記事にしようと思っています。正直実用は微妙であるという認識が強くなってるんですが。Microsoft が配布してる Dsofile.dll 使えば済む話っぽいんですよね……。

さて、今回は某掲示板から、ListView のフォーカスが移動したときのイベントって存在するのか、という問題です。フォーカスの移動ってのは、Control キー押しながらカーソルキーを押したときに動くアレです。選択状態とは無関係に移動できます。

さて、問題のイベントですが、率直に言って存在しません。

が、もちろん一切存在していないのでは深いレベルでは色々困るわけで、Win32API レベルでは存在します。それが LVN_ITEMCHANGED です。この通知メッセージは、リストビューのアイテムが変更されたときに送られてきます。アイテムの変更にはもちろんフォーカスが当たっているアイテムの変更も含まれます。

続きを読む
posted by Hongliang at 01:29| Comment(6) | TrackBack(0) | .NET | このブログの読者になる | 更新情報をチェックする

2006年04月02日

マルチメディアタイマ・改訂版

さて、前回アップしたマルチメディアタイマですが、速攻で問題点を見つけました。このままでは実行中に参照が無くなったとき、タイマが実行中でも止まってしまいます。

それはいけない。手本である System.Timers.Timer はタイマが有効な間は参照が無くなってもタイマを止めるまでは動き続けるようにデザインされています。

今回初めて知ったんですが、標準ライブラリの三つのタイマクラスのうち System.Threading.Timer クラスだけは実行中でも GC に回収されます(当然タイマは強制中断)。

続きを読む
posted by Hongliang at 21:35| Comment(2) | TrackBack(0) | .NET | このブログの読者になる | 更新情報をチェックする

マルチメディアタイマ

某掲示板に触発されて、ついマルチメディアタイマを使ったタイマクラスを書いてしまいました。

タイマが独自スレッドで動くことから、System.Timers.Timer とほぼ同じ構成にしています。私自身は VS を滅多に使わないから割と無駄っぽいですが、既定のプロパティやイベントを設定してみたり、コンポーネントを D&D した時点で SynchronizingObject が自動的に設定されるようにしてみたり、とちょっとしたコンポーネント作成のお勉強と言った雰囲気。

ドキュメントは WinXP 対象に書いてますが、9x 系ではマルチメディアタイマの挙動が微妙に違うらしいので要注意です。

今回は、コンポーネントをデザイナ画面に D&D したときに自動的にプロパティを設定するにはどう実装するかを考察してみましょう。

追記(06/04/02)この MultimediaTimer クラスは、速攻で改訂版が出ました。こっちのは残していますが使うべきではありません。

続きを読む
posted by Hongliang at 00:01| Comment(0) | TrackBack(1) | .NET | このブログの読者になる | 更新情報をチェックする

2006年03月27日

動的なDLLインポート

連載が終わった途端放置気味。意味もなく五七五で始めてみました。

コメント欄でちょっと話の出たホットキーの記事を書こうと思っていたのですが、調べれば調べるほど(本筋とは関係のないところで)難しい話になっていったので、後回し。いつになるかは未定義です。こだわりさえ捨てればいいんですが。

今回のネタはまさにネタですが、動的にアンマネージド DLL をインポートするってどうよ、と言う話です。

アンマネージド関数のインポートは通常 DllImport 属性(あるいは VB.NET なら Declare 構文)を使いますが、これを使用してインポートするには DLL 名とエントリポイントを静的に決定しておかなければなりません。これでは例えば統合アーカイバプロジェクトの DLL を使うにも、別の DLL に対しては別の関数を使わざるを得ず、あまり嬉しくない状況です。

続きを読む
posted by Hongliang at 16:00| Comment(8) | TrackBack(1) | .NET | このブログの読者になる | 更新情報をチェックする

2006年03月20日

COM クライアント実装の道程 for TaskScheduler その最終回

さて一連のシリーズもいよいよ最終回。最後は TaskScheduler クラスの使い方をつらつら書いていくことにしましょう。

続きを読む
posted by Hongliang at 22:11| Comment(3) | TrackBack(0) | .NET | このブログの読者になる | 更新情報をチェックする

2006年03月18日

COM クライアント実装の道程 for TaskScheduler その8

いよいよ連載も大詰め。TaskTrigger について解説していきましょう。

その前にまずは大元の TASK_TRIGGER 構造体を解説しなければなりません。TASK_TRIGGER 構造体はこれまで述べたとおりタスクの起動するタイミング(トリガ)を記述する構造体で、この構造体一つであらゆるトリガを表現します。そのため、TASK_TRIGGER は以下のメンバを持ちます。

  • 自身がどの種類の起動タイプなのかを表す TASK_TRIGGER_TYPE 列挙体の値
  • その起動タイプに固有の値を持つ TRIGGER_TYPE_UNION 共用体
続きを読む
posted by Hongliang at 21:03| Comment(2) | TrackBack(1) | .NET | このブログの読者になる | 更新情報をチェックする

2006年03月16日

COM クライアント実装の道程 for TaskScheduler その7

仕様を策定する人って絶対暇人ですよね。

前回の続きと言うことで、ITask に関するいくつかの実装を見ていきましょう。

まずは TaskScheduler クラスと同じく、Task クラスの基礎実装を。まあ ComInterfaceWrapper を継承して、内部で使用するインターフェイスを private プロパティにするだけですから同じですけど。ただ、コンストラクタは構成からして外部に公開する必要はないので、internal/Friend としておきます。ITask は単独で作成できますが、それは認めない方向で。

続きを読む
posted by Hongliang at 22:29| Comment(0) | TrackBack(0) | .NET | このブログの読者になる | 更新情報をチェックする

2006年03月12日

COM クライアント実装の道程 for TaskScheduler その6

死亡フラグって言いますよね。「この戦争が終わったら、俺、結婚するんだ」とか言うの。これ、死にフラグって表現もあると言うことを最近知りました。しかし死にフラグってのは、まるで上げ下げはしてるんだけどだれもそのフラグを参照してない孤独なフラグってイメージが。いやどうでも良いんですが。

今回から Task と TaskTrigger の解説に入るわけですが、いきなりクラスの解説をし出しても理解しにくいでしょうから、まずその下準備として ITask インターフェイスを中心にタスクアイテムの構造を述べていくことにします。

と切り出しておいて何ですが、実のところタスクアイテムの構成ってのはタスクのプロパティダイアログに表示されている奴ほぼそのままなんですよね。

続きを読む
posted by Hongliang at 17:38| Comment(0) | TrackBack(0) | .NET | このブログの読者になる | 更新情報をチェックする

2006年03月11日

COM クライアント実装の道程 for TaskScheduler その5

ID3タグってーのは調べれば調べるほど混沌としてきますね。あと v2.4 が出てもう5年以上立ってるけど結局 v2.3 の方が使われているような。WMP も v2.3 みたいだし。

さて、今回は前回の資産を生かして ITaskScheduler を .NET に相応しいクラスにラッピングします。まずは改めて ITaskScheduler のメンバを一覧しましょう。

メソッド 機能
SetTargetComputerこのインスタンスが操作の対象とするコンピュータの名前を設定する。
GetTargetComputerこのインスタンスが操作の対象とするコンピュータの名前を取得する。
Enum 現在のタスクフォルダに入っているタスクを列挙する。
Activate 操作するタスクを取得する。
Delete タスクを削除する。
NewWorkItem 新しいタスクアイテムをメモリに作成する。
AddWorkItem 新しいタスクアイテムのファイルを作成する。
IsOfType 指定したタスクアイテムが特定のインターフェイスをサポートしているかどうかを確認する。
続きを読む
posted by Hongliang at 18:08| Comment(0) | TrackBack(0) | .NET | このブログの読者になる | 更新情報をチェックする

ここ(hongliang.seesaa.net)で公開しているものについて、利用は自由に行って頂いて構いません。改変、再頒布もお好きになさって下さい。利用に対しこちらが何かを要求することはありません。

ただし、公開するものを使用、または参考したことによって何らかの損害等が生じた場合でも、私はいかなる責任も負いません。

あ、こんなのに使ったってコメントを頂ければ嬉しいです。

×

この広告は1年以上新しい記事の投稿がないブログに表示されております。