dm_operate.py 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. import ctypes
  2. import os
  3. import time
  4. from win32com.client import Dispatch
  5. from tools.log import logger
  6. class Dm:
  7. def __init__(self):
  8. """创建当前大漠对象。"""
  9. self.dm = Dispatch('dm.dmsoft')
  10. @staticmethod
  11. def reg_free(dm_path):
  12. """
  13. 免注册加载大漠插件的 DLL 文件。
  14. :param dm_path: DLL 文件路径
  15. """
  16. try:
  17. dm_dll = os.path.join(dm_path, 'dm.dll')
  18. dm_reg_dll = os.path.join(dm_path, 'DmReg.dll')
  19. # 确保 DLL 文件存在
  20. if not os.path.exists(dm_dll):
  21. return False, f"{dm_dll} not found."
  22. # 加载 DLL 并创建大漠插件对象
  23. patch = ctypes.windll.LoadLibrary(dm_reg_dll)
  24. patch.SetDllPathW(dm_dll, 0)
  25. dm = Dispatch('dm.dmsoft') # 创建对象
  26. ver = dm.ver()
  27. return True, ver
  28. except Exception as e:
  29. return False, f"加载大漠插件失败: - {e}"
  30. def __getattr__(self, name):
  31. """
  32. 通过代理调用大漠插件的 COM 方法。
  33. :param name: 大漠插件的方法名
  34. :return: 对应的方法
  35. """
  36. def method(*args):
  37. return getattr(self.dm, name)(*args)
  38. return method
  39. def register_vip(self, reg_code: str, extra_code: str):
  40. """
  41. 注册大漠插件。
  42. :param reg_code: 注册码
  43. :param extra_code: 附加码
  44. :return: 0 - 失败,1 - 成功
  45. """
  46. return self.dm.Reg(reg_code, extra_code)
  47. def get_version(self):
  48. """
  49. 获取大漠插件版本号。
  50. :return: 版本号字符串
  51. """
  52. return self.dm.Ver()
  53. def get_path(self):
  54. """
  55. 获取全局路径
  56. :return:当前设置的全局路径
  57. """
  58. return self.dm.GetPath()
  59. def set_path(self, path):
  60. """
  61. 设置大漠插件的工作路径。
  62. :param path: 工作路径
  63. :return: 0 - 失败,1 - 成功
  64. """
  65. return self.dm.SetPath(path)
  66. def bind_window(self, hwnd, display="gdi", mouse="windows", keypad="windows", mode=0):
  67. """
  68. 绑定指定的窗口。
  69. :param hwnd: 窗口句柄
  70. :param display: 显示模式
  71. :param mouse: 鼠标模式
  72. :param keypad: 键盘模式
  73. :param mode: 绑定模式
  74. :return: 0 - 失败,1 - 成功
  75. """
  76. return self.dm.BindWindow(hwnd, display, mouse, keypad, mode)
  77. def unbind_window(self):
  78. """
  79. 解除绑定窗口。
  80. :return: 0 - 失败,1 - 成功
  81. """
  82. return self.dm.UnBindWindow()
  83. def findPic(self, x1, y1, x2, y2, pic_name, delta_color, sim, direction):
  84. """
  85. 查找图片。
  86. :param x1: 起始坐标 x
  87. :param y1: 起始坐标 y
  88. :param x2: 结束坐标 x
  89. :param y2: 结束坐标 y
  90. :param pic_name: 图片文件名
  91. :param delta_color: 颜色容差
  92. :param sim: 相似度
  93. :param direction: 查找方向
  94. :return:
  95. """
  96. intX = -1
  97. intY = -1
  98. return self.dm.FindPic(x1, y1, x2, y2, pic_name, delta_color, sim, direction, intX, intY)
  99. def findMultiColor(self, x1, y1, x2, y2, first_color, offset_color, sim=0.9, direction=0):
  100. """
  101. 查找多个颜色。
  102. long FindMultiColor(x1, y1, x2, y2,first_color,offset_color,sim, dir,intX,intY)
  103. :param x1: 起始坐标 x
  104. :param y1: 起始坐标 y
  105. :param x2: 结束坐标 x
  106. :param y2: 结束坐标 y
  107. :param first_color: 颜色字符串
  108. :param offset_color: 颜色容差
  109. :param sim: 相似度
  110. :param direction: 查找方向
  111. :return: (1, intX, intY) 1表示找到 0没找到
  112. """
  113. intX = -1
  114. intY = -1
  115. ret = self.dm.FindMultiColor(x1, y1, x2, y2, first_color, offset_color, sim, direction, intX, intY)
  116. return ret
  117. def find_window(self, class_name, title_name):
  118. """
  119. 查找窗口句柄。
  120. :param class_name: 窗口类名
  121. :param title_name: 窗口标题
  122. :return: 窗口句柄
  123. """
  124. return self.dm.FindWindow(class_name, title_name)
  125. def capture_screen(self, x1, y1, x2, y2, file_name):
  126. """
  127. 屏幕截图。
  128. :param x1: 起始坐标 x
  129. :param y1: 起始坐标 y
  130. :param x2: 结束坐标 x
  131. :param y2: 结束坐标 y
  132. :param file_name: 截图文件保存路径
  133. :return: 0 - 失败,1 - 成功
  134. """
  135. return self.dm.Capture(x1, y1, x2, y2, file_name)
  136. # 可以继续添加更多的大漠插件方法
  137. def MoveTo(self, x, y):
  138. self.dm.MoveTo(x, y)
  139. # 鼠标左键点击
  140. def LeftClick(self):
  141. self.dm.LeftClick()
  142. # 移动点击
  143. def MoveClick(self, x, y, offset_x=0, offset_y=0):
  144. self.MoveTo(x + offset_x, y + offset_y)
  145. time.sleep(0.8)
  146. self.LeftClick()
  147. # 双击鼠标左键
  148. def DoubleClick(self, x, y, offset_x=0, offset_y=0):
  149. self.MoveTo(x + offset_x, y + offset_y)
  150. time.sleep(0.5)
  151. self.LeftDoubleClick()
  152. # 左键长按
  153. def LeftLongClick(self, x, y, offset_x=0, offset_y=0, duration=2000):
  154. self.MoveTo(x + offset_x, y + offset_y)
  155. time.sleep(0.5)
  156. self.LeftDown()
  157. time.sleep(duration)
  158. self.LeftUp()
  159. def DeleteText(self):
  160. for i in range(20):
  161. self.dm.KeyPress(8)
  162. time.sleep(0.1)
  163. def SendString(self, handle, text):
  164. ds = self.dm.SendString(handle, text)
  165. return ds
  166. def Capture(self, x1, y1, x2, y2, file):
  167. """抓取指定区域(x1, y1, x2, y2)的图像,保存为file(24位位图)"""
  168. return self.dm.Capture(x1, y1, x2, y2, file)
  169. def Drag(self, x1, y1, x2, y2, duration=1):
  170. """
  171. 滑动坐标
  172. :param duration: 耗时
  173. :param x1: x1
  174. :param y1: y1
  175. :param x2: x2
  176. :param y2: y2
  177. :return:
  178. """
  179. self.dm.MoveTo(x1, y1)
  180. time.sleep(0.5)
  181. self.dm.LeftDown()
  182. time.sleep(0.5)
  183. x = x2 - x1
  184. y = y2 - y1
  185. for i in range(1, 10):
  186. a = x1 + x / 10 * i
  187. b = y1 + y / 10 * i
  188. self.dm.MoveTo(a, b)
  189. time.sleep(duration / 10)
  190. self.dm.LeftUp()
  191. time.sleep(0.5)