if __FILE__ == $0 $KCODE='SJIS' class Win32GuiTest # by jun hirabayashi jun@ hirax.net 2008.11.15- 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') @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 # ------- under construction ----------------------- def PushButton(button, delay) end def PushChildButton( parent, button , delay ) end end gui=Win32GuiTest.new gui.run('wordpad.exe') sleep 2 gui.setForegroundWindow( gui.findWindowLikeName('ワードパッド').first[0] ) gui.setFocus( gui.findWindowLikeClass('RichEdit20W').first[0] ) gui.sendKeys('This is a sample.{ENTER}',1) gui.sendKeys('^a^c') 5.times do |i| gui.sendKeys("#{i} ...{ENTER}") gui.sendKeys('^v') end gui.sendKeys('%f',2) gui.sendKeys('x',1) gui.sendKeys('n',1) end