Re: Select polygon on EMF on MouseOver

Tech Tip: Click here to run a free scan for Windows Errors and optimize PC performance




Mike D Sutton wrote:
i do not hit-tested no polygons and nor enumerated EMF.
I've seen through your website for additional informations on how to
face this problem but right now i can't figure out how to do this
"polygon selection" tool on EMF files.
Probably, as a third-party tool support developer (metadraw) said, the
EMF I produce with a opensource conversion tool, has no particular
enumeration, causing the business to be very hard.
This is my first approach to graphical VB, and I don't know how and
where to get some info.
Instead, I've coded a small EPS viewer (that's the goal of the project)
using DrawLine, DrawBezier, DrawPath, FillPath, CreateRegionPath and so
on, with GDI+ wrapper of Avery P. (vbAccelerator)
I'm ended in storing each region in an array, then cycling each region
to see if the mouse coordinates are GdipIsVisibleRegionPoint=true to
"highlight" the relative path.
But when I try to color it, because of the bounding box of the EPS, the
region is always full colored and the image is gone.

The way I'd approach this is to enumerate the EMF using EnumEnhMetaFile() and go through the list of records for those
that can be hit-tested. Here's the full list:
http://msdn.microsoft.com/library/en-us/gdi/metafile_9otu.asp
Some records will define a full shape on their own (i.e. EMR_RECTANGLE), where as others will combine to form a single
shape (i.e. anything within a path bracket) so a 'shape selection' could be multiple records.
The currently selected pen and brush object will have an effect on the hit-testing so my advice would be to create a
path of each shape and use WidenPath() to expand the shape to the current pen width. As far as the brush goes, if you
want to hit-test pattern brushes then it's a much more complex task but doable with some work if required.
Using this path-based approach will however screw-up existing path brackets in the playback DC, so you'd need to create
a new DC and synchronise the various settings to get the correct mapping etc. Once you have a path of the current
record, you can use the PathToRegion() API call to convert this into a region which can be hit-tested using
PtInRegion(). It's not the most efficient technique, but saves you a whole lot of maths!
Hope this helps,

Mike


- Microsoft Visual Basic MVP -
E-Mail: EDais@xxxxxxxx
WWW: Http://EDais.mvps.org/

Mike, thanks a lot for your help.

I understand what you advice, and as far as I know, I need to code the
EnumMetaFileProc() to determine which GDI function correspond to the
EMR record, checking for the iType of the ENHMETARECORD.
During the EnumMetaFileProc, as you said, I will check for
"complementary" objects, such as lines, curves, etc.. that forms a
shape: then looping, I will unify them, to render through GDI, a Region
object.
So according to this, I think I need to do something like:

-NOTE: I'm using GDI+ functions here, and I have some questions about
it -

If MetaRecord.iType = EMR_BEGINPATH (i need to find somewhere the
corresponding numerical value)
Call GdipCreatePath(...)
End if
If MetaRecord.iType = EMR_LINETO (i need to find somewhere the
corresponding numerical value)
Call GdipAddPathLine(...)
End if
If MetaRecord.iType = EMR_BEZIER (i need to find somewhere the
corresponding numerical value)
Call GdipAddPathBezier(...)
End if


...and so on, until...

If MetaRecord.iType = EMR_ENDPATH (i need to find somewhere the
corresponding numerical value)
Call GdipDrawPath(graphics, pen, path) 'is this necessary???
Call GdipCreateSolidFill(ColorARGB(255, 0, 50, 50), brush) 'is this
necessary???
Call GdipFillPath(graphics, brush, path)
Call GdipCreateRegionPath(path, region)
End if

Am i right?

Besides, GDI+ functions used to draw a Path need to be fullfilled with
x y coordinates: where do I find them in the EMR records? Or there's a
better way to code this?

Therefore, on the PictureBox_MouseMove I can check for the
corresponding region where the point lies using
GdipIsVisibleRegionPoint. But, what about the "region" as used in the
last code snippet? It will be recognized or I have to store it before
in an array and loop on it whenever the mouse cursor is moving on the
picturebox?

At this point, I think it will be easy to color the region using
GdipFillRegion: but how do I copy it to a new PictureBox?

I really appreciate your support, this "EMF oriented approach" is
undoubtedly the best way to do the job, it will end to produce a
high-quality, reusable component that can be easily build as an OCX, so
that's the way to do.

Hope to read soon from you,

Thank you again,

Luigi.

.



Relevant Pages

  • Re: Serious GDI Multithreading bug while printing to metafiles
    ... GDI calls end up in the EMF. ... metafile DC and the printer DC. ... Strange is, the CreateFont(), SelectFont, ..., DeleteFontis ...
    (microsoft.public.win32.programmer.gdi)
  • Re: Event ID 6161 and 6162
    ... We solved the issue by working with the application developer to fix the EMF ... The application that leaked GDI handles was the MS Office Document Viewer. ... Restart the job or print it again and 500 more handle leak. ...
    (microsoft.public.windowsxp.print_fax)
  • Re: Problem with Offscreen...
    ... Mike D Sutton a écrit: ... >>I play with the api's gdi to try to create a game engine, I'm a fool, I ... > Dim hOldBMP As Long ... > Again when you select the GDI object into the DC, retain the returned handle and re-select it before destroying either the DC or GDI ...
    (microsoft.public.vb.general.discussion)
  • Re: Problem with Offscreen...
    ... Mike D Sutton a écrit: ... >>I play with the api's gdi to try to create a game engine, I'm a fool, I ... > Dim hOldBMP As Long ... > Again when you select the GDI object into the DC, retain the returned handle and re-select it before destroying either the DC or GDI ...
    (microsoft.public.project.vba)
  • Re: Problem with Offscreen...
    ... Mike D Sutton a écrit: ... >>I play with the api's gdi to try to create a game engine, I'm a fool, I ... > Dim hOldBMP As Long ... > Again when you select the GDI object into the DC, retain the returned handle and re-select it before destroying either the DC or GDI ...
    (microsoft.public.vb.winapi.graphics)