最近在看 .netframework 的源代码.
当看到winform 的 ListBox 控件时,知道它是用 DrawItem 事件来绘制子项目的
但我在它的代码中看到它是这样调用的.
private void WmReflectDrawItem(ref Message m)
{
...具体函数实现略过
//此处调用 OnDrawIten
this.OnDrawItem(new DrawItemEventArgs(graphics, this.Font, rect, lParam.itemID, (DrawItemState) lParam.itemState, this.ForeColor, this.BackColor));
}那么 WmReflectDrawItem 又是在哪调用的呢,我再查,发现是在 WndProc, 也就是控件的主消息循环中
protected override void WndProc(ref Message m)
{
int msg = m.Msg;
switch (msg)
{
case 0x202b:
this.WmReflectDrawItem(ref m);
return; case 0x202c:
this.WmReflectMeasureItem(ref m);
return; case 0x317:
this.WmPrint(ref m);
return; default:
if (msg != 0x2111)
{
goto Label_029F;
}
this.WmReflectCommand(ref m);
return;
}
}
函数调用是明白了,问题也就来了,以上这几个消息ID(0x202B,0x2111等)我从没见过,在 winuser.h 中也查不到,且值都大于 WM_USER (0x0400), 而且我发现很多控件中都有 WmReflectCommand, WmReflectDrawItem 等函数,其对应的消息ID都一样, 难道是 windows的隐藏消息.
望高人解答.
当看到winform 的 ListBox 控件时,知道它是用 DrawItem 事件来绘制子项目的
但我在它的代码中看到它是这样调用的.
private void WmReflectDrawItem(ref Message m)
{
...具体函数实现略过
//此处调用 OnDrawIten
this.OnDrawItem(new DrawItemEventArgs(graphics, this.Font, rect, lParam.itemID, (DrawItemState) lParam.itemState, this.ForeColor, this.BackColor));
}那么 WmReflectDrawItem 又是在哪调用的呢,我再查,发现是在 WndProc, 也就是控件的主消息循环中
protected override void WndProc(ref Message m)
{
int msg = m.Msg;
switch (msg)
{
case 0x202b:
this.WmReflectDrawItem(ref m);
return; case 0x202c:
this.WmReflectMeasureItem(ref m);
return; case 0x317:
this.WmPrint(ref m);
return; default:
if (msg != 0x2111)
{
goto Label_029F;
}
this.WmReflectCommand(ref m);
return;
}
}
函数调用是明白了,问题也就来了,以上这几个消息ID(0x202B,0x2111等)我从没见过,在 winuser.h 中也查不到,且值都大于 WM_USER (0x0400), 而且我发现很多控件中都有 WmReflectCommand, WmReflectDrawItem 等函数,其对应的消息ID都一样, 难道是 windows的隐藏消息.
望高人解答.
记得以前处理移动的时候有个消息和sizechange有关
#define WM_WINDOWPOSCHANGING 0x0046
//窗体位置已改变
#define WM_WINDOWPOSCHANGED 0x0047移动的时候又不改变大小, 和 SizeChange 没什么关系
-------------------
搜一个工具: Reflector我感觉像是项目自定义的消息,所以才会使用WM_USER大的值。
-------------------
我也曾怀疑过,但自定义消息应该有个触发消息的地方吧,我根本找不到
protected override void WndProc(ref Message m)
{
Console.WriteLine(m);
base.WndProc(ref m);
}
你可以如下得到这些消息的字符描述:
protected override void WndProc(ref Message m)
{
Console.WriteLine(m);
base.WndProc(ref m);
}
这个是输出到哪里的?如何输出到即时窗口啊?
程序完全可以使用
sendmessage or postmessage 把指定消息发送给指定窗口,相当于一个自定义协议,没有什么奇怪的