Skip to main content
replaced http://gis.stackexchange.com/ with https://gis.stackexchange.com/
Source Link

Basically, it's a thread which sends WM_NULL (0) messages to the given window. The __enter__ and __exit__ functions support Python's with statement. Here's how it's used (the ArcObjects related functions are taken from this postthis post in a different question):

Basically, it's a thread which sends WM_NULL (0) messages to the given window. The __enter__ and __exit__ functions support Python's with statement. Here's how it's used (the ArcObjects related functions are taken from this post in a different question):

Basically, it's a thread which sends WM_NULL (0) messages to the given window. The __enter__ and __exit__ functions support Python's with statement. Here's how it's used (the ArcObjects related functions are taken from this post in a different question):

added 7 characters in body
Source Link
Petr Krebs
  • 10.3k
  • 1
  • 23
  • 33

Try it out. I could not fully test it with my ArcMap 10 setup because I did not have any issues with the active view refresh before (it executed immediately and refresh was successful), but the WM_NULL messages do get sent.

Try it out. I could not fully test it with my ArcMap 10 setup because I did not have any issues with the active view refresh (it executed immediately and refresh was successful), but the WM_NULL messages do get sent.

Try it out. I could not fully test it with my ArcMap 10 setup because I did not have any issues with the active view refresh before (it executed immediately and refresh was successful), but the WM_NULL messages do get sent.

added 418 characters in body; added 4 characters in body
Source Link
Petr Krebs
  • 10.3k
  • 1
  • 23
  • 33

So, in the light of the tips in Kirk's link (ArcMap Automation: Man the Message Pumps!) and the knowledge that IObjectFactory must be used your scenario, here's my take take on Python implementation of the discussed workaround.

To reiterate, the problem is that RPC calls, coming from a different process (python) might get stalled in ArcMap. The general idea described in the aforementioned article is that by pummeling ArcMap's message loop with WM_NULL messages, you force it to process your RPC calls as well. 

I am not versed in Python, in fact this might only be my fifth piece of Python code or so, if memory serves. If anyone wants to improve/fix it in any way, go ahead. I ran it on Python 2.6.5.

app =# GetApp()Get the ArcMap's IApplication reference.
# getWe're thein IApplicationa referencedifferent process than ArcMap's, so it gets resolved using IAppROT.
app = GetApp()

# WM_NULL messages will be sent from another thread while
# this block is executing
with EsriAppMessageHelper(app.hWnd):

    objectFactory = CType(app, esriFramework.IObjectFactory) # use IObjectFactory
    mxDoc = CType(app.Document, esriArcMapUI.IMxDocument)
    graphicsContainer = mxDoc.ActiveView.GraphicsContainer

    textElement = CType(objectFactory.Create("esriCarto.TextElement"), esriCarto.ITextElement)

    # initialize the symbols and elements, assign their geometries
    # etc...

    graphicsContainer.AddElement(element, 0)
    mxDoc.ActiveView.PartialRefresh(esriCarto.esriViewGraphics, None, None)

# At this point, we're out of the WITH block.
# The separate thread is stopped and no more WM_NULL messages are being sent.
print "DONE"

So, in the light of the tips in Kirk's link (ArcMap Automation: Man the Message Pumps!) and the knowledge that IObjectFactory must be used your scenario, here's my take on Python implementation of the discussed workaround. I am not versed in Python, in fact this might only be my fifth piece of Python code or so, if memory serves. If anyone wants to improve it in any way, go ahead.

app = GetApp()    # get the IApplication reference

# WM_NULL messages will be sent from another thread while
# this block is executing
with EsriAppMessageHelper(app.hWnd):

    objectFactory = CType(app, esriFramework.IObjectFactory) # use IObjectFactory
    mxDoc = CType(app.Document, esriArcMapUI.IMxDocument)
    graphicsContainer = mxDoc.ActiveView.GraphicsContainer

    textElement = CType(objectFactory.Create("esriCarto.TextElement"), esriCarto.ITextElement)

    # initialize the symbols and elements, assign their geometries
    # etc...

    graphicsContainer.AddElement(element, 0)
    mxDoc.ActiveView.PartialRefresh(esriCarto.esriViewGraphics, None, None)

# At this point, we're out of the WITH block.
# The separate thread is stopped and no more WM_NULL messages are being sent.
print "DONE"

So, in the light of the tips in Kirk's link (ArcMap Automation: Man the Message Pumps!) and the knowledge that IObjectFactory must be used your scenario, here's my take on Python implementation of the discussed workaround.

To reiterate, the problem is that RPC calls, coming from a different process (python) might get stalled in ArcMap. The general idea described in the aforementioned article is that by pummeling ArcMap's message loop with WM_NULL messages, you force it to process your RPC calls as well. 

I am not versed in Python, in fact this might only be my fifth piece of Python code or so, if memory serves. If anyone wants to improve/fix it in any way, go ahead. I ran it on Python 2.6.5.

# Get the ArcMap's IApplication reference.
# We're in a different process than ArcMap's, so it gets resolved using IAppROT.
app = GetApp()

# WM_NULL messages will be sent from another thread while
# this block is executing
with EsriAppMessageHelper(app.hWnd):

    objectFactory = CType(app, esriFramework.IObjectFactory) # use IObjectFactory
    mxDoc = CType(app.Document, esriArcMapUI.IMxDocument)
    graphicsContainer = mxDoc.ActiveView.GraphicsContainer

    textElement = CType(objectFactory.Create("esriCarto.TextElement"), esriCarto.ITextElement)

    # initialize the symbols and elements, assign their geometries
    # etc...

    graphicsContainer.AddElement(element, 0)
    mxDoc.ActiveView.PartialRefresh(esriCarto.esriViewGraphics, None, None)

# At this point, we're out of the WITH block.
# The separate thread is stopped and no more WM_NULL messages are being sent.
print "DONE"
Source Link
Petr Krebs
  • 10.3k
  • 1
  • 23
  • 33
Loading