Multiple EMF files

Multiple EMF files

Post by YYZ » Fri, 01 Oct 2004 13:53:49


I'm trying to create multiple EMF Files (memory only) in a row. The first one
always works, but the rest of them fail getting a MetaFile DC. I
Crea *** hMetaFile, I draw to it, I CloseEnhMetafile, then try to
Crea *** hMetaFile but the resulting DC is always 0.

Do I have to Dele *** hMetaFile of the metafile resulting from CloseEnhMetafile
before I can get another DC? I'm trying to create a group of metafiles (between
0 and 1000 of them at least) and hold those in memory, playing them into other
device contexts as needed through the life of my program, then cleaning them up
at the end.

Is this not possible? Am I missing something stupid?

Matt
 
 
 

Multiple EMF files

Post by christophe » Fri, 01 Oct 2004 17:37:05

Hello,

See what's LastDllError is.
If it's BAD PARAMETERS it may come from the hDCRef parameters
during the draw in EMF you had probably select a GDI object and not
release it or somthing like that (a bitmap selected ?).
Be sure that the DC you get by createEMF is in the same state at the end
of drawing.

Christophe

YYZ a rit :

 
 
 

Multiple EMF files

Post by Mike D Sut » Fri, 01 Oct 2004 19:43:03

gt; I'm trying to create multiple EMF Files (memory only) in a row. The first one

You shouldn't have any problems creating multiple EMF's simultaneously, I don't ever recall seeing CreateEnhMetaFile() fail to be
honest.
Try this, add a new class to your project called "clsSimpleEMF" and paste in this code:

'*** clsSimpleEMF.cls:
Private Declare Function CreateEnhMetaFile Lib "GDI32.dll" Alias "CreateEnhMetaFileA" ( _
ByVal hdcRef As Long, ByVal lpFileName As String, _
ByRef lpRect As Any, ByVal lpDescription As String) As Long
Private Declare Function CloseEnhMetaFile Lib "GDI32.dll" (ByVal hDC As Long) As Long
Private Declare Function DeleteEnhMetaFile Lib "GDI32.dll" (ByVal hEMF As Long) As Long
Private Declare Function PlayEnhMetaFile Lib "GDI32.dll" (ByVal hDC As Long, _
ByVal hEMF As Long, ByRef lpRect As Any) As Long
Private Declare Function GetEnhMetaFileHeader Lib "GDI32.dll" (ByVal hEMF As Long, _
ByVal cbBuffer As Long, ByRef lpEMH As EnhMetaHeader) As Long
Private Declare Function OffsetRect Lib "User32.dll" ( _
ByRef lpRect As RectAPI, ByVal X As Long, ByVal Y As Long) As Long
Private Declare Function SetRect Lib "User32.dll" (ByRef lpRect As RectAPI, _
ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
Private Declare Function SaveDC Lib "GDI32.dll" (ByVal hDC As Long) As Long
Private Declare Function RestoreDC Lib "GDI32.dll" ( _
ByVal hDC As Long, ByVal nSavedDC As Long) As Long

Private Type RectAPI
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type

Private Type SizeL
cx As Long
cy As Long
End Type

Private Type EnhMetaHeader
iType As Long
nSize As Long
rclBounds As RectAPI
rclFrame As RectAPI
dSignature As Long
nVersion As Long
nBytes As Long
nRecords As Long
nHandles As Integer
sReserved As Integer
nDescription As Long
offDescription As Long
nPalEntries As Long
szlDevice As SizeL
szlMillimeters As SizeL
End Type

Private m_hMeta As Long
Private m_Recording As Boolean
Private m_Managed As Boolean
Private SaveState As Long

Public Property Get hDC() As Long
' Only valid while recording
If (m_Recording) Then hDC = m_hMeta
End Property

Public Property Get hEMF() As Long
' Only valid while not recording
If (Not m_Recording) Then hEMF = m_hMeta
End Property

' Defines whether the class should manage its EMF handle
Public Property Get Managed() As Boolean
Managed = m_Managed
End Property
Public Property Let Managed(ByVal inNew As Boolean)
m_Managed = inNew
End Property

Public Function Create() As Boolean
Call Destroy
m_hMeta = CreateEnhMetaFile(0&, vbNullString, ByVal 0&, vbNullString)

If (m_hMeta) Then
' Save the current state, start recording and manage by default
SaveState = SaveDC(m_hMeta)
m_Recording = True
m_Managed = True
Create = True
End If
End Function

Public Function StopRecording() As Boolean
If (Not m_Recording) Then Exit Function

' Restore original state, close MetaDC and store EMF handle
Call RestoreDC(m_hMeta, SaveState)
m_hMeta = CloseEnhMetaFile(m_hMeta)
StopRecording = True
m_Recording = False
End Function

Public Function Destroy() As Boolean ' Clean up resources
If (m_hMeta = 0) Then Exit Function
If (m_Recording) Then Call StopRecordin
 
 
 

Multiple EMF files

Post by YYZ » Sat, 02 Oct 2004 00:26:06


one
CloseEnhMetafile
(between
other
up
don't ever recall seeing Crea *** hMetaFile() fail to be
this code:

I did, and it all worked like you said it would. So, in examining what the
difference was, I noticed your calls:
Crea *** hMetaFile(0&, vbNullString, ByVal 0&, vbNullString)

and mine

Crea *** hMetaFile(0&, 0&, r, "asdf")

were different. I'm an idiot. vbNullString <> 0&. Dumbass.

Thanks for helping out yet again. I actually was using a class, but yours is
better. :) It wraps up all that SaveDC and RestoreDC stuff.

Matt
 
 
 

Multiple EMF files

Post by YYZ » Sat, 02 Oct 2004 00:31:35


Thanks for the suggestion. I was actually using 0& as the DC to create from, so
that wasn't the problem. It was a problem in the 2nd paramter...I was passing
0& instead of vbNullString -- so the error probably was BAD PARAMETERS like you
said.


I do -- SaveDC and RestoreDC are too easy not to use.

Matt