OnScreenKeyboardClass.cs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. using System;
  2. using System.Diagnostics;
  3. using System.Runtime.InteropServices;
  4. using System.Threading.Tasks;
  5. namespace CCDCount.DLL.Tools
  6. {
  7. public static class OnScreenKeyboard
  8. {
  9. [DllImport("user32.dll", SetLastError = true)]
  10. static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
  11. [DllImport("user32.dll")]
  12. static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
  13. [DllImport("user32.dll")]
  14. static extern bool SetForegroundWindow(IntPtr hWnd);
  15. [DllImport("user32.dll")]
  16. static extern bool IsWindowVisible(IntPtr hWnd);
  17. const int SW_SHOW = 5;
  18. const int SW_RESTORE = 9;
  19. const int SW_HIDE = 0;
  20. public static async void Show()
  21. {
  22. // 首先确保没有旧进程
  23. KillTabTipProcess();
  24. // 等待进程完全终止
  25. await Task.Delay(300);
  26. // 启动新实例
  27. if (StartNewInstance())
  28. {
  29. // 等待窗口出现
  30. await Task.Delay(500);
  31. IntPtr keyboardWnd = FindWindow("IPTip_Main_Window", null);
  32. if (keyboardWnd != IntPtr.Zero)
  33. {
  34. ShowWindow(keyboardWnd, SW_RESTORE);
  35. SetForegroundWindow(keyboardWnd);
  36. }
  37. }
  38. }
  39. private static async Task ShowKeyboardAsync()
  40. {
  41. // 尝试查找已运行的键盘实例
  42. IntPtr keyboardWnd = FindWindow("IPTip_Main_Window", null);
  43. if (keyboardWnd != IntPtr.Zero && IsWindowVisible(keyboardWnd))
  44. {
  45. // 键盘已经在显示中
  46. SetForegroundWindow(keyboardWnd);
  47. return;
  48. }
  49. // 尝试使用COM接口
  50. if (TryShowWithCom())
  51. return;
  52. // 启动新实例
  53. if (StartNewInstance())
  54. {
  55. // 等待窗口出现
  56. await Task.Delay(300);
  57. keyboardWnd = FindWindow("IPTip_Main_Window", null);
  58. }
  59. // 显示窗口
  60. if (keyboardWnd != IntPtr.Zero)
  61. {
  62. ShowWindow(keyboardWnd, SW_RESTORE);
  63. SetForegroundWindow(keyboardWnd);
  64. }
  65. }
  66. private static bool TryShowWithCom()
  67. {
  68. try
  69. {
  70. Type type = Type.GetTypeFromProgID("TabTip.TabTip");
  71. if (type != null)
  72. {
  73. object instance = Activator.CreateInstance(type);
  74. type.InvokeMember("Show", System.Reflection.BindingFlags.InvokeMethod, null, instance, null);
  75. Marshal.ReleaseComObject(instance);
  76. return true;
  77. }
  78. }
  79. catch
  80. {
  81. // COM方法失败,继续尝试其他方法
  82. }
  83. return false;
  84. }
  85. private static bool StartNewInstance()
  86. {
  87. try
  88. {
  89. string[] keyboardPaths = {
  90. @"C:\Program Files\Common Files\Microsoft Shared\ink\TabTip.exe",
  91. @"C:\Program Files (x86)\Common Files\Microsoft Shared\ink\TabTip.exe"
  92. };
  93. foreach (string path in keyboardPaths)
  94. {
  95. if (System.IO.File.Exists(path))
  96. {
  97. Process.Start(new ProcessStartInfo
  98. {
  99. FileName = path,
  100. UseShellExecute = true
  101. });
  102. return true;
  103. }
  104. }
  105. }
  106. catch
  107. {
  108. // 启动失败
  109. }
  110. return false;
  111. }
  112. public static void Hide()
  113. {
  114. IntPtr keyboardWnd = FindWindow("IPTip_Main_Window", null);
  115. if (keyboardWnd != IntPtr.Zero)
  116. {
  117. ShowWindow(keyboardWnd, SW_HIDE);
  118. }
  119. KillTabTipProcess();
  120. }
  121. public static void KillTabTipProcess()
  122. {
  123. try
  124. {
  125. Process[] processes = Process.GetProcessesByName("TabTip");
  126. foreach (Process process in processes)
  127. {
  128. process.Kill();
  129. process.WaitForExit();
  130. }
  131. }
  132. catch
  133. {
  134. // 忽略异常
  135. }
  136. }
  137. }
  138. }