WPF 分析 Dispatcher PushFrame

  • Post author:
  • Post category:其他


千里之行,始于足下

剖析 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 版权协议,转载请附上原文出处链接和本声明。