pywinautoのexample2 mspaintを自動操作

今日のサンプルは動きがあるからおもしろいかな?
Vistaで動作確認していますが、100%ではありません。。。orz
サンプルベースにしているので。。。(言い訳?)

#coding: utf-8
# -*- encoding: utf-8 -*- 

import sys, locale, codecs

enc = locale.getpreferredencoding()
sys.stdout = codecs.getwriter(enc)(sys.stdout)
sys.stdin = codecs.getreader(enc)(sys.stdin)

# GUI Application automation and testing library
# Copyright (C) 2006 Mark Mc Mahon
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License
# as published by the Free Software Foundation; either version 2.1
# of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
#    Free Software Foundation, Inc.,
#    59 Temple Place,
#    Suite 330,
#    Boston, MA 02111-1307 USA

"Run some automations to test things"

__revision__ = "$Revision: 214 $"

import time

from pywinauto import application
from pywinauto import tests
from pywinauto.findbestmatch import MatchError
from pywinauto import findwindows
from pywinauto import WindowAmbiguousError
from pywinauto.controls import WrapHandle

#早いと動かない場合があるので。。。使わないほうが無難。。。
#from pywinauto.timings import Timings
#Timings.Fast() #ボタンクリック等を早いタイミングにする

app = application.Application()

# for distribution we don't want to connect to anybodies application
# because we may mess up something they are working on!
#目的アプリにconnectする⇒connect出来なかったらアプリを起動させる
try:
    app.connect_(path = ur"c:\windows\system32\mspaint.exe")
except application.ProcessNotFoundError:
    app.start_(ur"c:\windows\system32\mspaint.exe")

#タイトルからwindowハンドルを取得(.*⇒ワイルドカード)
pwin = app.window_(title_re = u".* - ペイント") 

#pwin = app["MSPaintApp"]
# get the previous image size

pwin.MenuSelect(u"変形(&I)->キャンバスの色とサイズ(&A)...") #メニュー選択 MenuSelect(A->B)

#Texts()==['', u'350'] リストから値を取得
prev_width = app[u"キャンパスの色とサイズ"].Edit1.Texts()[1] 
prev_height = app[u"キャンパスの色とサイズ"].Edit2.Texts()[1]

# set our preferred area
#TpyeKeys()とSetEditText()結果は同じ。EditTextに"350”が入力される
app[u"キャンパスの色とサイズ"].Edit1.TypeKeys("350")  # you can use TypeKeys or
app[u"キャンパスの色とサイズ"].Edit2.SetEditText("350")   # SetText - they work differently!

app[u"キャンパスの色とサイズ"].OK.CloseClick()

try:
    # get the reference to the Canvas window
    canvas = pwin.Afx100000008.DrawOutline()
    canvas = pwin.Afx100000008
    canvas.WrapperObject()
except WindowAmbiguousError, e: #WindowAmbiguousError⇒findwindowsの関数。
    print e, e.windows #マッチするwindowがない場合のみ通る
    for w in e.windows:
        w = WrapHandle(w)
        print w.WindowText(), w.Class()
    import sys
    sys.exit()

# make sure the pencil tool is selected
pwin.AfxWnd42u2.ClickInput(coords = (91, 16))

size = 15
num_slants = 20

# draw the axes
#PressMouse()(ペンを押す)⇒MoveMouse()(移動する)⇒ReleaseMouse()(離す)一連の動作で絵を描く
canvas.PressMouse(coords = (size, size * num_slants))
canvas.MoveMouse(coords = (size*num_slants, size*num_slants))
canvas.MoveMouse(coords = (size * num_slants, size))
canvas.ReleaseMouse()

# now draw the lines
print "*** if you move your mouse over Paint as it is drawing ***"
print "*** these lines then it will mess up the drawing!      ***\n"
for i in range(1, num_slants):

    endcoords = (size * (num_slants - i), size * num_slants)
    canvas.PressMouse(coords = (size * num_slants, i * size)) # start
    canvas.MoveMouse(coords = endcoords) # x and y axes
    canvas.ReleaseMouse(coords = endcoords)

# may fail if PIL is not installed
image = canvas.CaptureAsImage() #PILimageを取得
if image: #取得できていれば
    image.save(r"Application_Paint_test.png") #保存
    print "Saved image as: Application_Paint_test.png"

# set it back to  original width and height
pwin.MenuSelect(u"変形(&I)->キャンバスの色とサイズ(&A)...")
# set our preferred area
app[u"キャンパスの色とサイズ"].Edit1.TypeKeys(prev_width)
app[u"キャンパスの色とサイズ"].Edit2.SetEditText(prev_height)
app[u"キャンパスの色とサイズ"].OK.CloseClick()

# close Paint
pwin.MenuSelect(u"ファイル(F)->ペイントの終了(X)")

"""
#試したけどダメだったので、楽なほうに逃げる。。。
#NOボタンが存在すればクリックさせる
if app.Paint[u"保存しない(&N)"].No.Exists():
    #print "It existed!"
    # Click the no button on the message box asking if we want to save
    app.Paint[u"保存しない(&N)"].No.CloseClick()
"""

#保存ダイアログを閉じる
app.Dialog[u"保存しない(&N)"].CloseClick()

PILがこのサンプルでは必要です。ファイルと同階層にキャプチャが取得されています。
ちなみにpywinautoはwin32ネイティブアプリのみ対応しています。
.NETアプリは動かないとハズです。。。またWEBの自動化は得意ではないので、そういった用途にはSeleniumを使うことをお勧めします。(私は使えませんが。。。orz)