處理 python COM中的枚舉對象

來源:互聯網
上載者:User

 

在工作中需要做測試,開發是用了python,一來文法簡單,而來也有robotframework可以配合使用。開發一般用QTP測試比較少,QTP測試也比較慢。所以可以直接使用python開發的庫,或者最多提煉一些關鍵詞,用robotframework來做測試也好。

測試方面也針對同樣的測試項做了開發,由於終端傳遞出來的是c資料結構,比較複雜,而用dll調用的方式由於沒有跟c很好的介面,導致提取結構非常辛苦,後來想了個辦法,用micString+micByRef預先分配好字串,然後dll庫內把資料用sprintf格式化出name=value;這種格式來使用。然後在vbs中再恢複出來,非常辛苦。當然,這些值也可以從頁面取到,不過QTP操作頁面有時候速度比較慢,沒有直接從介面取資料快。

 

針對這種情況,用python+python win32擴充把python對象封裝出來供使用。裡面使用了ctypes庫,以便於定義c語言的結構,能做到跟c語言布局一樣。而且可以定義複雜的資料結構。也很容易在ctypes對象和string之間做pack和unpack。另外,使用了python win32擴充中的win32com.server.util的集合對象,以便於在vbs中使用for each...next結構。 廢話不多說了。下面貼出代碼

 

 

 

 

import string

import pythoncom

import pywintypes

import winerror

import types

from ctypes import *

from win32com.server import policy

from win32com.server.util import NewEnum,NewCollection,wrap,unwrap,Collection,ListEnumeratorGateway

from win32com.server.exception import COMException

 

class myStructure(Structure):

    def __str__(self):      

        s=[]

        for k,v in self._fields_:

            if type(v)==type(c_int) or type(v)==type(Structure): #SimpleType

                s.append("%s=%s"%(k,getattr(self,k)))

            elif type(v)==type(Array):

                s.append('%s=%s'%(k,'['+','.join(["%s" % getattr(self,k)[i] for i in range(v._length_)])+']'))

            else:

                pass

        return '%s(%s)'%(self.__class__.__name__,','.join([i for i in s]))

 

class CollectionGateway(Collection):

  "A collection which wraps a sequence's items in gateways"

  def Item(self, *args):

    if len(args) != 1:

      raise COMException(scode=winerror.DISP_E_BADPARAMCOUNT)

 

    try:

      return wrap(self.data[args[0]])

    except IndexError, desc:

      raise COMException(scode=winerror.DISP_E_BADINDEX, desc=str(desc))  

 

  def _NewEnum(self):

    return NewEnum(self.data,ListEnumeratorGateway)  

 

class comPoint(myStructure):

    _fields_=[('x',c_int),('y',c_int)]

    _public_methods_=[]

    _public_attrs_=['x','y']

 

class comPointList(myStructure,CollectionGateway):

    _fields_=[('num',c_int),('list',comPoint * 2)]  

    _reg_progid_ = "Pt.Point"

    _reg_clsid_ = "{CB2E1BC5-D6A5-11D2-852D-204C4F4F5024}"

    _public_methods_=['CStr']

    _public_attrs_=['num']

 

    def CStr(self):

        return str(self)

 

    def Item(self, *args):

        if len(args) != 1:

          raise COMException(scode=winerror.DISP_E_BADPARAMCOUNT)

 

        try:

          return wrap(self.list[args[0]])

        except IndexError, desc:

          raise COMException(scode=winerror.DISP_E_BADINDEX, desc=str(desc))  

 

    def _NewEnum(self):

        return NewEnum(self.list,ListEnumeratorGateway)  

 

if __name__=='__main__':

    import win32com.server.register

    win32com.server.register.UseCommandLine(comPointList)

 

這裡面核心部分是引入了CollectionGateway,這樣對每個集合對象在傳出的時候都會wrap成com對象。_NewEnum則在For Each的時候被自動調用,當然,也暴露了一個num屬性,用於知道有幾個元素,另外,用Item也可以直接取對應元素。

 

下面是測試的vbs代碼

 

Set pl = CreateObject("Pt.Point")<br />MsgBox pl.CStr()<br />For Each Item In pl<br /> MsgBox CStr(Item.x)+" "+CStr(Item.y)<br />Next 

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.