現在の ArcGIS 10.0 ArcMap セッションへの参照を (ArcObjects COM 経由で) 取得する必要がある外部 Python/comtypes スクリプト (PythonWin) を作成しています。スクリプトはアプリケーション境界の外にあるため、AppROT (実行中のオブジェクト テーブル) を介してアプリケーション参照を取得しています。以下の最初のコード スニペットは、メインの Python ドライバー モジュールです。これは、AppROT からアプリケーション参照を取得する関数 GetApp() です。このコードは問題なく動作し、シングルトンの AppRef オブジェクトで IApplication を返します。理にかなっており、それが ArcObjects リファレンスが示しているようです。今、私の主な目標は、IMxDocument に到達することです。メイン ループでは、IDocument に正常に到達し、タイトルを印刷できます。ただし、次のクエリ インターフェース行はエラーをスローします - NameError: name 'esriArcMapUI' is not defined. エラーは、PythonWin を閉じて再度開いた後でも一貫して発生します (問題があると結論付ける前に、常に試してください)。[ところで、2 番目のコード スニペットは QI の CType() 関数であり、SignHelpers.py モジュールで定義され、そこからインポートされます。] それで、ここに私の質問があります。
(1) IDocument が存在する COM オブジェクトは?
(2) IDocument から目的の IMxDocument に移動するにはどうすればよいですか? 最初に新しい MxDocument オブジェクトを作成する必要がありますか? [ごめん。2 つの質問があります。]
(3) 新しいオブジェクトを作成する必要がない場合、QI はどのように行うのですか?
私は数年前に VB6 で多くの ArcObjects の作業を行ったので、現時点では明示的な QI と名前空間が問題になっています。IMxDocument にたどり着いたら、家から解放されます。誰でもこれで私に与えることができる助けをいただければ幸いです。
また、以下のコードのフォーマットについてお詫び申し上げます。Python コードを正しくフォーマットする方法がわかりませんでした。インデントが機能せず、Python コードの一部が書式設定文字として解釈されます。
=== code: main py module ===
import sys, os
sys.path.append('C:\GISdata\E_drive\AirportData\ATL\Scripts')
import comtypes
from SignHelpers import *
def GetApp(app):
"""Get a hook into the current session of ArcMap; \n\
Execute GetDesktopModules() and GetStandaloneModules() first"""
print "GetApp called" #@@@
import comtypes.gen.esriFramework as esriFramework
import comtypes.gen.esriArcMapUI as esriArcMapUI
import comtypes.gen.esriCarto as esriCarto
pAppROT = NewObj(esriFramework.AppROT, esriFramework.IAppROT)
iCount = pAppROT.Count
print "appROT count = ", iCount #@@@
if iCount == 0:
print 'No ArcGIS application currently running. Terminating ...'
return None
for i in range(iCount):
pApp = pAppROT.Item(i) #returns IApplication on AppRef
if pApp.Name == app:
print "Application: ", pApp.Name #@@@
return pApp
print 'No ArcMap session is running at this time.'
return None
if __name__ == "__main__":
#Wrap needed ArcObjects type libraries (.olb)...
... code omitted ...
GetDesktopModules(dtOLB) #These force comtypes to generate
GetStandaloneModules(saOLB) #the Python wrappers for .olb's
#Connect to ArcMap
pApp = GetApp("ArcMap")
pDoc = pApp.Document #IDocument on current Document object
print pDoc.Title
pMxDoc = CType(pDoc, esriArcMapUI.IMxDocument) #QI to IMxDocument on MxDocument
=== code for CType() ===
def CType(obj, interface):
try:
newobj = obj.QueryInterface(interface)
return newobj
except:
return None