Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I am using ArcGIS 10.0/ArcObjects and Python 2.6. I am trying to get the usage of the ITextSymbol.GetTextSize method correct. The syntax, as established in an earlier question, is:

dblx, dbly = pTextSymbol.GetTextSize(pDisplay.hDC, pDisplay.DisplayTransformation, txt)

and the outparameters are returned just fine. My problem is in figuring out how to use this method so that it does not screw up ArcMap's screen cache. ESRI documentation indicates that it should be surrounded by calls to IDisplay.StartDrawing and IDisplay.FinishDrawing so that the input hDC will be correct. (Indeed, calling GetTextSize without the start and finish drawing results in an invalid hDC.) The syntax that I am using for StartDrawing is as follows:

pDisplay.StartDrawing(0, esriDisplay.esriNoScreenCache)

I have tried both 0 (as discussed in documentation) and pDipsplay.hDC for the first parameter of StartDrawing, but the ArcMap screen still gets stuck in one place. (Panning just causes a redraw from cache right back to the same place.) Either input for the first parameter results in valid outparams but a stuck screen. The problem could also be with the esirNoScreenCache constant, I suppose, but I don't see how. I am not trying to draw anything to the screen at this point. I'm just operating on a TextSymbol, not a TextElement or the like. pDisplay and txt are both valid, in-process objects, so the problem, I think, is with the hDC or the screen cache. I'm at a loss to figure out which. Any insights are greatly welcomed.

share|improve this question
You would be better off asking these questions on the ArcObjects forum at Esri. – Jason Scheirer Jan 17 '11 at 22:16
Did you try using the CacheMemDC as mentioned by Neil here: (posted back in the days when Esri forums were more usable). – Kirk Kuykendall Jan 18 '11 at 2:17
@Kirk - No, I did not try this, but I will investigate. Thanks. – celticflute Jan 18 '11 at 13:25
@Jason - Perhaps the ESRI forums would be a more appropriate place to ask these questions, but I, like many others, am very frustrated with the new forum format, and I rarely get any help at all. – celticflute Jan 18 '11 at 13:28
up vote 2 down vote accepted

When I am doing text measurements, I usually create a text element (TextElement) class, assign its Text and Symbol properties, set it's geometry to a point at any location (say [0, 0]), and then query its size by calling IElement.QueryBounds. Along with a reference to the display, this method expects you to also pass a reference to an existing envelope instance, which will be filled with the element bounds. From there, you can get the envelope's Width and Height. This is particularly useful if you want your measurements to be in the active views's units (map units for map, paper units for the page layout), instead of points, which are returned from ISymbol.GetTextSize().

The CacheMemDc method suggested by Kirk also looks interesting. I've never tried it, I'm curious how it works out for you.

Alternatively, you may try creating your own display object, SimpleDisplay, change its DisplayTransformation to have the same properties as the active view's screen display transformation, and use that when calling GetTextSize().

share|improve this answer
I shall definitely try these solutions. I actually had the QueryBounds method in the code a while ago, but it did not fit well with the logic I had around it; however, if it works, I'll make it fit. I will also investigate the CacheMemDC possibility. I am not really constrained by performance or style. I just need this to work. Thank you for your continued interest and willingness to help. – celticflute Jan 18 '11 at 13:37
and Kirk - The QueryBounds method worked for me. When I had tried using it before, there must have been a bug elsewhere that was affecting it. I also tried the CacheMemDC, and it worked fine, too. The interesting thing about using CacheMemDC is that you don't surround the GetTextSize with StartDrawing and FinishDrawing. It is in fact the StartDrawing method that was the problem, and I never could get it to work. Also, there is no mention of CacheMemDC in the documentation for GetTextSize. Go figure. Thank you, gentlemen ... and Thanks to Neil Clemmons, too! – celticflute Jan 18 '11 at 16:36
StartDrawing method creates the device context of the display on which you can draw (if you pass 0 as the hDC parameter), and FinishDrawing releases (destroys) its context handle. The map manages a set of offscreen cache bitmaps along with their associated device contexts, and CacheMemDc returns them, so that's why there is no need for any StartDrawing calls. Thanks to Neil as well, since I had no idea that the caching features (which I think a typical AO developer rarely accesses) can be used for this kind of tasks. – Petr Krebs Jan 18 '11 at 17:05

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.