if __FILE__ == $0 $KCODE='SJIS' class Win32GuiTest # jun hirabayashi jun@hirax.net 2008.11.15-2008.11.16 require 'Win32API' require 'win32ole' require 'dl/win32' require 'dl/import' # mouse event MOUSEEVENTF_ABSOLUTE = 0x8000 MOUSEEVENTF_MOVE = 0x1 MOUSEEVENTF_LEFTDOWN = 0x2 MOUSEEVENTF_LEFTUP = 0x4 MOUSEEVENTF_RIGHTDOWN = 0x8 MOUSEEVENTF_RIGHTUP = 0x10 MOUSEEVENTF_MIDDLEDOWN = 0x20 MOUSEEVENTF_MIDDLEUP = 0x40 MOUSEEVENTF_XDOWN=0x100 MOUSEEVENTF_XUP=0x200 MOUSEEVENTF_WHEEL=0x80 def initialize @wsh=WIN32OLE.new("WScript.Shell") @setCursorPosAPI=Win32API.new("user32", "SetCursorPos", ['i', 'i'], 'V') @getCursorPosAPI=Win32API.new("user32", "GetCursorPos", ['P'], 'V') @mouseEventAPI=Win32API.new("user32", "mouse_event",['l', 'l','l', 'l','l'],'V') @findWindow=Win32API.new("user32", "FindWindow",['P', 'P'],'I') @getWindowTextAPI=Win32API.new("user32", "GetWindowText",['l','P','l'],'I') @setForegroundWindowAPI=Win32API.new("user32", "SetForegroundWindow",['l'],'V') @getClassNameAPI=Win32API.new("user32", "GetClassName",['l','P','l'],'V') @setFocusAPI=Win32API.new("user32", "SetFocus",['l'],'V') @getForegroundWindowAPI=Win32API.new("user32", "GetForegroundWindow",[],'I') @getWindowRectAPI=Win32API.new("user32", "GetWindowRect",['I','P'],'V') @moveWindowAPI=Win32API.new("user32", "MoveWindow",['I','I','I','I','I','I'],'V') @user32=DL.dlopen("user32") @enumWindows=@user32['EnumWindows', '0PL'] @enumChildWindows=@user32['EnumChildWindows', '0IPL'] end def run(fileOrApl) @wsh.Run(fileOrApl) end def sendKeys(keys, delay=0) sleep delay @wsh.SendKeys(keys) end def sendMouse(command,x=0.2,y=0.3) case command when "LEFTDOWN" sendLButtonDown when "LEFTUP" sendLButtonUp when "MIDDLEDOWN" sendMButtonDown when "MIDDLEUP" sendMButtonUp when "RIGHTDOWN" sendRButtonDown when "RIGHTUP" sendRButtonUp when "LEFTCLICK" sendLButtonDown sleep x sendLButtonUp when "MIDDLECLICK" sendMButtonDown sleep x sendMButtonUp when "RIGHTCLICK" sendRButtonDown sleep x sendRButtonUp when "LEFTDOUBLECLICK" sendLButtonDown sleep x sendLButtonUp sleep y sendLButtonDown sleep x sendLButtonUp when "MIDDLEDOUBLECLICK" sendMButtonDown sleep x sendMButtonUp sleep y sendMButtonDown sleep x sendMButtonUp when "RIGHTDOUBLECLICK" sendRButtonDown sleep x sendRButtonUp sleep y sendRButtonDown sleep x sendRButtonUp when "ABS" mouseMoveAbsPix(x,y) when "REL" pos=getCursorPos mouseMoveAbsPix(pos[0]+x,pos[1]+y) when "WHEEL" mouseMoveWheel(w) else end end def mouseMoveAbsPix(x,y) @setCursorPosAPI.call(x, y) end def mouseMoveWheel(w) @mouseEventAPI.call(MOUSEEVENTF_WHEEL,0,0,w,0) end def findWindowLike(title) findWindowLikeName(title) end def findWindowLikeName(title) wins=[] @enumWindowsProc=DL.callback('IL') do |hwnd| buf=" "*1024 @getWindowTextAPI.call(hwnd,buf,buf.size) wins << [hwnd, buf.sub(/\0.+$/,'')] if /#{title}/=~buf -1 end @enumWindows.call(@enumWindowsProc, 0) wins end def findWindowLikeClass(classname) hwnds=[] @enumWindowsProc=DL.callback('IL') do |hwnd| hwnds<< hwnd -1 end @enumWindows.call(@enumWindowsProc, 0) wins=[] @enumChildWindowsProc=DL.callback('IL') do |hwnd| buf=" "*1024 @getClassNameAPI.call(hwnd,buf,buf.size) wins << [hwnd, buf.sub(/\0.+$/,'')] if /#{classname}/=~buf -1 end hwnds.each do |hwnd| @enumChildWindows.call(hwnd, @enumChildWindowsProc, 0) end wins end def setForegroundWindow(hwnd) @setForegroundWindowAPI.call(hwnd) end def setFocus(hwnd) @setFocusAPI.call(hwnd) end def getCursorPos lpP=" "*8 @getCursorPosAPI.Call(lpP) lpP.unpack("LL") end def mouseEvent(event,x=0,y=0,w=0) @mouseEventAPI.call(event,x,y,w,0) end def sendLButtonUp mouseEvent(MOUSEEVENTF_LEFTUP) end def sendLButtonDown mouseEvent(MOUSEEVENTF_LEFTDOWN) end def sendMButtonUp mouseEvent(MOUSEEVENTF_MIDDLEUP) end def sendMButtonDown mouseEvent(MOUSEEVENTF_MIDDLEDOWN) end def sendRButtonUp mouseEvent(MOUSEEVENTF_RIGHTUP) end def sendRButtonDown mouseEvent(MOUSEEVENTF_RIGHTDOWN) end def sendMouseMoveRel(x,y) sendMouse('REL',x,y) end def sendMouseMoveAbs(x,y) sendMouse('ABS',x,y) end def getForegroundWindow @getForegroundWindowAPI.call end def getWindowRect(hwnd) lpP=" "*16 @getWindowRectAPI.call(hwnd,lpP) lpP.unpack("LLLL") end def moveWindow(hwnd,x=0,y=0,width=500,height=500,repaint=1) @moveWindowAPI.call(hwnd,x,y,width,height,repaint) end # ------- under construction ----------------------- def PushButton(button, delay) end def PushChildButton( parent, button , delay ) end end gui=Win32GuiTest.new gui.run('mspaint.exe') sleep 1 w=gui.findWindowLikeName('ƒyƒCƒ“ƒg').first[0] gui.setForegroundWindow(w) gui.moveWindow(w) r=gui.getWindowRect(gui.getForegroundWindow) sleep 1 360.times do |i| rad=i*2*3.14/360.0 x=r[0]+200+100*Math.cos(rad) y=r[1]+200+100*Math.sin(rad) gui.mouseMoveAbsPix(x.to_i,y.to_i) gui.sendLButtonDown if i==0 end gui.sendLButtonUp gui.sendKeys('%f',2) gui.sendKeys('x',1) gui.sendKeys('y',1) gui.sendKeys('TestBitmap.bmp',2) gui.sendKeys('{ENTER}',2) end