3Dプリンターを監視できるTwitterのbotを作った - 高専生のロボット作りの続きです。
3Dプリンターの監視までは良いんですけど操作もできなくちゃ、、、ということでタイトルの通りです。
方法としては、使用している3Dプリンター操作用ソフト pronterface また、pronterface内のボタンのウィンドウハンドルを取得し、そこにメッセージを送ることで操作するって感じです。
pronterfaceのウィンドウハンドルの取得にはMicrosoft Visual Studio 2015のspy++を使用します。
pronterfaceはあらかじめ起動しておきます。
visual studio2015を起動したら、ツールからspy++(+)をクリック。
検索→ウィンドウ検索をクリックし、ファインダーツールをpronterface画面にドラッグするとpronterfaceのウィンドウハンドルが表示されます。その状態で
OKをクリックすれば、ウィンドウハンドル一覧からpronterfaceの場所に移ります。⊞ボタンを押していけばpronterfaceの子ハンドル(ボタンとかの)がすべて展開されます。
画像はその時の画面です。
ここで、例えば'Pause'ボタンのハンドルは0x000C08FCで、pronterfaceの一個下のpanelから13子目にあることが分かります。
このウィンドウハンドルそのもの、または、何個目にあるのか どちらかが分かればよいです。
では、コードです
import ctypes import array WM_GETTEXTLEN = 0x000E WM_GETTEXT = 0x000D WM_LBUTTONDOWN = 0x201 WM_LBUTTONUP = 0x202 MK_LBUTTON = 0x0001 class Control3DPrinter: def __init__(self): p_handle = ctypes.windll.user32.FindWindowW(0, "Pronterface") c1_handle = ctypes.windll.user32.FindWindowExW(p_handle, 0, "wxWindowClassNR", "panel") c2_handles = array.array("i") ENUM_CHILDs = ctypes.WINFUNCTYPE(\ ctypes.c_int,\ ctypes.c_int,\ ctypes.py_object) ctypes.windll.user32.EnumChildWindows(\ c1_handle,\ ENUM_CHILDs(self.addHandle),\ ctypes.py_object(c2_handles)) self.PAUSE_handle = c2_handles[12] self.OFF_handle = c2_handles[13] self.G28_handle = c2_handles[70] def addHandle(self, handle, list): list.append(handle) return 1 def pushButton(self, button_handle): ctypes.windll.user32.SendMessageW(button_handle, WM_LBUTTONDOWN, MK_LBUTTON, 0) ctypes.windll.user32.SendMessageW(button_handle, WM_LBUTTONUP) def G28(self): self.pushButton(self.G28_handle) def PAUSE(self): self.pushButton(self.PAUSE_handle) def OFF(self): self.pushButton(self.OFF_handle) if __name__ == "__main__": controler = Control3DPrinter() controler.G28()
先ほどの何個目にあるかという情報から、コンストラクタ内でボタンのウィンドウハンドルを取得しています。
別にウィンドウハンドルそのものが分かっているので直接書いてもいいんですけどね。
pushButton(button_handle)関数では引数のウィンドウハンドルに対して、
「マウスをクリック押下し、離した」というメッセージを送信しています。
ウィンドウハンドルに対して適切にメッセージを送信すれば、外部プロセスからでも操作することができます。
また、応用すれば3Dプリンターだけでなく、いろいろなソフトも操作できますね。
UPBOXでもできるようにするので、できたらまた記事書きます。