千里之行,始于足下
剖析 Dispatcher PushFrame函数,一般用更新动画特效
在
private void PushFrameImpl(DispatcherFrame frame)
{
....
//一直更新frame 并从window消息队列中获取消息 直到 continue=false
while (frame.Continue && this.GetMessage(ref msg, IntPtr.Zero, 0, 0))
{
this.TranslateAndDispatchMessage(ref msg);
}
....
}
GetMessage 是从Win32API 得到消息,如果有消息没有处理就发送给Win32 Translate和DIspatch消息队列(翻译和派遣)
private void TranslateAndDispatchMessage(ref MSG msg)
{
if (!ComponentDispatcher.RaiseThreadMessage(ref msg))
{
UnsafeNativeMethods.TranslateMessage(ref msg);
UnsafeNativeMethods.DispatchMessage(ref msg);
}
}
public static bool RaiseThreadMessage(ref MSG msg)
{
ComponentDispatcherThread currentThreadData = CurrentThreadData;
return currentThreadData.RaiseThreadMessage(ref msg);
}
其中 ComponentDispatcherThread中_threadFilterMessage是委托,具体发送给 HwndSource
确认是否处理这个消息,
public bool RaiseThreadMessage(ref MSG msg)
{
bool flag = false;
if (this._threadFilterMessage != null)
{
this._threadFilterMessage(ref msg, ref flag);
}
if (flag)
{
return flag;
}
if (this._threadPreprocessMessage != null)
{
this._threadPreprocessMessage(ref msg, ref flag);
}
return flag;
}
switch (msgdata.msg.message)
{
case 256:
case 260:
{
HwndSource._eatCharMessages = true;
DispatcherOperation dispatcherOperation = base.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new DispatcherOperationCallback(HwndSource.RestoreCharMessages), null);
base.Dispatcher.CriticalRequestProcessing(true);
msgdata.handled = this.CriticalTranslateAccelerator(ref msgdata.msg, systemModifierKeys);
if (!msgdata.handled)
{
HwndSource._eatCharMessages = false;
dispatcherOperation.Abort();
}
if (this.IsInExclusiveMenuMode)
{
if (!msgdata.handled)
{
UnsafeNativeMethods.TranslateMessage(ref msgdata.msg);
}
msgdata.handled = true;
}
break;
}
在 HwndSource中处理 private object OnPreprocessMessage(object param),具体怎么处理就不讨论了。
总结一下
在Window下开发不管你是用什么界面开发库,你始终是通过系统和用户交互,绕不管window系统消息机制,区别是谁的界面开发库利用 win32API在各种场合下占用资源更少,速度更快。WPF这个方面有大区别以前的winfom界面开发库。
—-怎么更新界面
—-
版权声明:本文为weixin_37753976原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。