0

NM_CUSTOMDRAW通知コードがWM_NOTIFYメッセージによってコントロールの親に送信される場合、このWM_NOTIFYメッセージのlParamパラメーターは、ここに記述されているように、NMCUSTOMDRAW構造体のアドレスです。

http://msdn.microsoft.com/en-us/library/windows/desktop/ff919569(v=vs.85).aspx

一方、WM_NOTIFYメッセージのlParamは次のようになります。

A pointer to an NMHDR structure that contains the notification code and additional
information. For some notification messages, this parameter points to a larger
structure that has the NMHDR structure as its first member.

多くのコード例では、WM_NOTIFYメッセージのハンドラーについて、次のように表示されます。

LPNMLISTVIEW     pnm         =   (LPNMLISTVIEW)lParam;
    switch   (pnm->hdr.code){   .... 

しかし、問題は、このlParamがNMHDR構造またはNM_CUSTOMDRAW構造の前身であるかどうかわからないということです。どうすれば、lParamを正しくキャストできるでしょうか。lParamが単なるNMHDRである場合は、LPNMHDRとpnm->codeを使用する必要がありますね。

さらに悪いことに、異なるコントロールは異なるタイプの構造を使用します:NMLVCUSTOMDRAW、NMTVCUSTOMDRAW、NMLVCUTTOMDRAWおよびNMTBCUSTOMDRAW。したがって、WM_NOTIFYハンドラーの先頭で行う正しい方法は何ですか。それが、NM_CUSTOMDRAWであるかどうかを区別し、正しいNMCUSTOMDRAW構造体タイプを決定します。


記事を読んだとき

http://msdn.microsoft.com/en-us/library/windows/desktop/ff919569%28v=vs.85%29.aspx

MSDNでは、一部が理解できません。例えば、

CDRF_NOTIFYPOSTPAINTコントロール全体のペイントサイクルが完了すると、コントロールはNM_CUSTOMDRAW通知を送信します。これは、dwDrawStageがCDDS_PREPAINTと等しい場合に発生します。

コントロール全体のペイントサイクルが完了したときにコントロールがNM_CUSTOMDRAW通知を送信すると、このNM_CUSTOMDRAWのdwDrawStateはCDDS_PREPOSTPAINTと等しくなりますね。

そのMSDNの記事の戻り値の意味のリストで、誰かが「これはいつ発生するか....」と説明できますか。

4

2 に答える 2

2

Microsoft Windowsがその構造を構築する方法は、プレーンオールドデータ形式です。そのため、私が定義した場合:

struct A {
    int a;
};

struct B {
    A a;
    int b;
};

struct C {
    A a;
    int c;
};

メモリ内のBのレイアウトは、実際には2つの整数であり、Aの内容全体(整数)とBの内容全体(別の整数)です。したがって、値を取得できる限り、BをAのように扱うのが安全です。メンバーから、ポインターが本当にタイプBかタイプCかを判別します。この例では、NMHDRは一般的な値です( A)およびNMLISTVIEWは特定の値(BまたはC)です。(タイプNMHDRの)hdr値をテストして、lParamがどのタイプであるかを確認し、そこから正しいサブタイプにキャストします。これは、CおよびC++Windows開発に当てはまります。

于 2013-01-24T14:49:24.317 に答える
2

簡単です。lParamポインターは両方NMHDR*であり、NMLVCUSTOMDRAW*同時にです。がどのように定義されているかを見ると、 memberNMLVCUSTOMDRAWで始まることがわかります。NMHDR

LPARAMそうは言っても、あなたはあなたが選んだものにあなたを確実にキャストすることができます: NMHDR*, NMCUSTOMDRAW*, NMLVCUSTOMDRAW*. 通知が listview からのもので、メッセージ自体が でWM_NOTIFYあり、NMHDR::codeに等しい場合NM_CUSTOMDRAW、3 つのキャストのいずれかおよびすべてが正しくなります。

NMLVCUSTOMDRAW汎用の通知固有の拡張と考えてくださいNMHDR

于 2013-01-24T14:42:16.927 に答える