CogGdiRender.cs 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. using System;
  2. using System.Windows.Forms;
  3. namespace Plugins.Vpp.Views
  4. {
  5. /// <summary>
  6. /// Cognex 显示控件渲染引擎统一修复:
  7. /// CogRecordDisplay 等显示控件默认用硬件加速渲染(CogRenderEngine),在向日葵远程 /
  8. /// 部分显卡驱动 / 远程会话环境下会整块白屏(本机已用最小程序实测复现:WinForms/WPF 均正常,
  9. /// 仅 Cog 显示白屏;切 GDI 渲染引擎后立即恢复)。
  10. /// 该属性只能在控件句柄创建之后读写(此前读写抛 InvalidOperationException),
  11. /// 这里统一在 HandleCreated 时机切换,并递归应用到容器里的所有 Cog 显示控件
  12. /// (覆盖 CogToolBlockEditV2 内部动态创建的工具编辑显示面板)。
  13. /// </summary>
  14. internal static class CogGdiRender
  15. {
  16. /// <summary>递归把 root 树内所有带 RenderEngine 属性的 Cog 显示控件切到 GDI 渲染。</summary>
  17. public static void Apply(Control root)
  18. {
  19. if (root == null) return;
  20. Hook(root);
  21. foreach (Control child in root.Controls)
  22. Apply(child);
  23. }
  24. private static void Hook(Control c)
  25. {
  26. if (c == null || !c.GetType().Name.StartsWith("Cog", StringComparison.OrdinalIgnoreCase)) return;
  27. var prop = c.GetType().GetProperty("RenderEngine");
  28. if (prop == null || !prop.CanWrite) return;
  29. if (c.IsHandleCreated)
  30. SetEngine(c, prop);
  31. else
  32. {
  33. EventHandler onCreated = null;
  34. onCreated = (s, e) =>
  35. {
  36. c.HandleCreated -= onCreated;
  37. SetEngine(c, prop);
  38. };
  39. c.HandleCreated += onCreated;
  40. }
  41. }
  42. private static void SetEngine(Control c, System.Reflection.PropertyInfo prop)
  43. {
  44. try
  45. {
  46. var gdi = Enum.ToObject(prop.PropertyType, 1); // CogRenderEngineConstants.CogGDIRenderEngine = 1
  47. prop.SetValue(c, gdi, null);
  48. }
  49. catch { /* 单个控件切换失败不影响其它控件 */ }
  50. }
  51. }
  52. }