Открытие метафайлов в Visual C
От: Elder  
Дата: 18.01.02 13:32
Оценка:
Помогите, как открыть метафайлы (wmf) в Visual C++. Функция PlayMetafile() их не открывает (вернее открывает метафайлы, созданные функцией CopyMetafile(), а остальные не открывает, не смотря на то, что я и вырезаю у них первые 22 байта, как сказано).
Re: Открытие метафайлов в Visual C
От: Archie Беларусь  
Дата: 18.01.02 13:47
Оценка: 8 (2)
Здравствуйте Elder, Вы писали:

E>Помогите, как открыть метафайлы (wmf) в Visual C++. Функция PlayMetafile() их не открывает (вернее открывает метафайлы, созданные функцией CopyMetafile(), а остальные не открывает, не смотря на то, что я и вырезаю у них первые 22 байта, как сказано).


а с каких это пор PlayMetafile начала открывать файлы ?
в общем вот пример

HENHMETAFILE hMetaFile;
        METAHEADER wmfHeader;
        METAFILEPICT wmfPict;
        DWORD dwFileKey;
        WORD *pwBuffer = NULL;
        int nFileHandle;
        
        if( (nFileHandle = _topen(strFileName, _O_BINARY | _O_RDONLY, _S_IREAD)) == -1 ) 
          throw 1L;
        
        if( !(_read(nFileHandle, &dwFileKey, sizeof(DWORD)) > 0 ) ) 
          throw 1L;
        
        if (dwFileKey == 0x9AC6CDD7)
        {
          if (_lseek(nFileHandle, 22L, SEEK_SET) == -1) 
            throw 2L;
          if (!(_read(nFileHandle, &wmfHeader, sizeof(METAHEADER)) > 0 )) 
            throw 3L;
          
          pwBuffer = new WORD[wmfHeader.mtSize];
          if (pwBuffer == NULL) 
            throw 4L;
          
          if (_lseek(nFileHandle, 22L, SEEK_SET) == -1) 
            throw 5L;
          if (!(_read(nFileHandle, pwBuffer, wmfHeader.mtSize * sizeof(WORD)) > 0 )) 
            throw 6L;
          
          memset(&wmfPict, 0, sizeof(METAFILEPICT));
          wmfPict.mm = MM_HIENGLISH;
          wmfPict.xExt = 1000; //rect.Width();
          wmfPict.yExt = 1000; //abs(rect.Height());
          wmfPict.hMF = SetMetaFileBitsEx(wmfHeader.mtSize * sizeof(WORD), (BYTE*) pwBuffer);
          if (wmfPict.hMF == NULL) throw 7L;
          
          hMetaFile = SetWinMetaFileBits(wmfHeader.mtSize * sizeof(WORD), (BYTE*) pwBuffer, 0, &wmfPict);
          if (hMetaFile == NULL) throw 8L;
        }
        else
        {
          hMetaFile = GetEnhMetaFile(strFileName);
          if (hMetaFile == NULL) throw 9L;
        }
        
        if( wmfPict.hMF )
          DeleteMetaFile( wmfPict.hMF );
        _close( nFileHandle );
        if( pwBuffer != NULL ) 
          delete [] pwBuffer;

// ... использование hMetaFile, например в

      ::DeleteEnhMetaFile(m_hMetaFile);
Re[2]: Открытие метафайлов в Visual C
От: Archie Беларусь  
Дата: 18.01.02 13:49
Оценка:
только вместо
A> ::DeleteEnhMetaFile(m_hMetaFile);
надо
::DeleteEnhMetaFile(hMetaFile);
Re[2]: Открытие метафайлов в Visual C
От: Elder  
Дата: 18.01.02 20:29
Оценка:
Здравствуйте Archie, Вы писали:

A>Здравствуйте Elder, Вы писали:


E>>Помогите, как открыть метафайлы (wmf) в Visual C++. Функция PlayMetafile() их не открывает (вернее открывает метафайлы, созданные функцией CopyMetafile(), а остальные не открывает, не смотря на то, что я и вырезаю у них первые 22 байта, как сказано).


A>а с каких это пор PlayMetafile начала открывать файлы ?


Ну, имелась в виду, конечно, GetMetaFile (или GetEnhMetaFile).

A>в общем вот пример


За пример спасибо, но вот что-то я опять не понимаю — пытаюсь читать обычный (не aldus) метафайл

A>
MetaFileHandle=GetEnhMetaFile("a.wmf");
CMetaFileDC* RepMetaFile = new CMetaFileDC();
CRect rc(0,0,10000,10000);
RepMetaFile->CreateEnhanced(NULL,NULL,&rc,NULL);
RepMetaFile->PlayMetaFile(MetaFileHandle,NULL);    // а вот тут она уже не работает, возвращает 0
A>


Где ошибка-то?
Re[3]: Открытие метафайлов в Visual C
От: Elder  
Дата: 19.01.02 10:22
Оценка:
Здравствуйте Elder, Вы писали:

То есть, текст выглядит так.
MetaFileHandle=GetEnhMetaFile("a.wmf");
CMetaFileDC* RepMetaFile = new CMetaFileDC();
CRect rc(0,0,10000,10000);
RepMetaFile->>CreateEnhanced(NULL,NULL,&rc,NULL);
RepMetaFile->>PlayMetaFile(MetaFileHandle,&rc);    // а вот тут она уже не работает, возвращает 0


Где ошибка-то?

И еще, можно ли каким-то образом обработать метафайл из консольного приложения, т.е. не создавая окна и работая затем через HWND, а как бы внутри считать, кое-чего дорисовать и затем снова записать. Может есть какие-нибудь библиотеки, где это реализовано?
Re: Открытие метафайлов в Visual C
От: Юнусов Булат Россия  
Дата: 19.01.02 13:48
Оценка: 1 (1)
Здравствуйте Elder, Вы писали:

E>Помогите, как открыть метафайлы (wmf) в Visual C++. Функция PlayMetafile() их не открывает (вернее открывает метафайлы, созданные функцией CopyMetafile(), а остальные не открывает, не смотря на то, что я и вырезаю у них первые 22 байта, как сказано).

Вот нрыл когда то класс для сабжа — работает

// cemf.h : interface of the CEMF class
//
/////////////////////////////////////////////////////////////////////////////
#ifndef EMF_H
#define EMF_H

class CEMF : public CObject
{
    // Operations
public:
     CEMF();
     ~CEMF();
     BOOL Load(const char *szFileName);
    BOOL Draw(CDC* pDC, RECT* pRect);
    LPENHMETAHEADER GetEMFHeader(){return ((m_pEMFHdr) ? m_pEMFHdr : NULL);};
    LPTSTR GetEMFDescString(){return ((m_pDescStr) ? m_pDescStr : NULL);};
    HENHMETAFILE GetEMFHandle(){return ((m_hemf) ? m_hemf : NULL);};
    
    
protected:
    BOOL GetEMFCoolStuff();
    BOOL LoadPalette();
    
    // Attributes
protected:
    CString m_szPathName;
    HENHMETAFILE m_hemf;
    LPENHMETAHEADER m_pEMFHdr;
    LPTSTR m_pDescStr;
    LPPALETTEENTRY m_pPal;
    UINT m_palNumEntries;
    LPLOGPALETTE m_pLogPal;
    LOGPALETTE m_LogPal;
    HPALETTE m_hPal;
};

#endif






// cemf.cpp implementation of the CEMF class

#include "stdafx.h"
#include "cemf.h"

//////////////////////////////////////////////////////////////////////////
//constructor
CEMF::CEMF()
{
    m_pEMFHdr = NULL;
    m_pDescStr = NULL;
    m_pPal = NULL;
    m_hemf = NULL;
    m_pLogPal = NULL;
    m_hPal = NULL;
    m_szPathName = "";
}

//////////////////////////////////////////////////////////////////////////
//destructor
CEMF::~CEMF()
{
    if (m_pEMFHdr)
        free(m_pEMFHdr);
    if (m_pDescStr)
        free(m_pDescStr);
    if (m_pPal)
        free(m_pPal);
    if (m_pLogPal)
        free (m_pLogPal);
    if (m_hPal)
        DeleteObject(m_hPal);
    if (m_hemf)
        DeleteEnhMetaFile(m_hemf);
}

//////////////////////////////////////////////////////////////////////////
//Load()
BOOL CEMF::Load(const char *szFileName)
{
    UINT uiSig;
    //save the filename
    m_szPathName = szFileName;
    
    //check the file signature to see if this is an enhanced metafile
    CFile cfEMF;
    cfEMF.Open(m_szPathName, CFile::modeRead | CFile::shareDenyWrite);
    cfEMF.Read(&uiSig, sizeof(UINT));
    cfEMF.Close();
    
    //if this is an EMF then obtain a handle to it
    if (uiSig == EMR_HEADER)
    {
        m_hemf = GetEnhMetaFile(m_szPathName);
        GetEMFCoolStuff();
        LoadPalette();
    }
    else
        m_hemf = NULL;
    
    //return success
    return ((m_hemf) ? TRUE : FALSE);
}

//////////////////////////////////////////////////////////////////////////
//Draw()
BOOL CEMF::Draw(CDC *pdc, RECT *pRect)
{
    ASSERT(m_hemf);
    
    BOOL fRet = FALSE;
    CRect crect;
    CPalette *cpalOld = NULL;
    
    if (m_hemf)
    {
        if (m_hPal) 
        {
            CPalette cpal;
            if ((cpalOld = pdc->SelectPalette(cpal.FromHandle(m_hPal), FALSE)))
                pdc->RealizePalette();
        }
        fRet = pdc->PlayMetaFile(m_hemf, pRect);
        
        if (cpalOld)
            pdc->SelectPalette(cpalOld, FALSE);
    }
    return (fRet);
}

//////////////////////////////////////////////////////////////////////////
//GetEMFCoolStuff()
BOOL CEMF::GetEMFCoolStuff()
{
    if (m_hemf)
    {
        //
        //obtain the sizes of the emf header, description string and palette
        //
        UINT uiHdrSize = ::GetEnhMetaFileHeader(m_hemf, 0, NULL);
        UINT uiDescStrSize = ::GetEnhMetaFileDescription(m_hemf, 0, NULL);
        UINT uiPalEntries = ::GetEnhMetaFilePaletteEntries(m_hemf, 0, NULL);
        //
        //if these are lengths > 0 then allocate memory to store them
        //
        if (uiHdrSize)
            m_pEMFHdr = (LPENHMETAHEADER)malloc(uiHdrSize);
        if (uiDescStrSize)
            m_pDescStr = (LPTSTR)malloc(uiDescStrSize);
        if (uiPalEntries)
            m_pPal = (LPPALETTEENTRY)malloc(uiPalEntries * sizeof(PALETTEENTRY));
        //
        //so far the emf seems to be valid so continue
        //
        if (uiHdrSize)
        {
            //
            //get the actual emf header and description string
            //
            if (!::GetEnhMetaFileHeader(m_hemf, uiHdrSize, m_pEMFHdr))
                return (FALSE);
            else
            {
                //
                //get the description string if it exists
                //
                if (uiDescStrSize)
                    ::GetEnhMetaFileDescription(m_hemf, uiDescStrSize, m_pDescStr);
                //
                //get the palette if it exists
                //
                if (uiPalEntries)
                {
                    ::GetEnhMetaFilePaletteEntries(m_hemf, uiPalEntries, m_pPal);
                    m_palNumEntries = uiPalEntries;
                }
            }
        }
    }
    return (TRUE);
}

//////////////////////////////////////////////////////////////////////////
//LoadPalette()
BOOL CEMF::LoadPalette()
{
    if (m_pPal)
    {
        m_pLogPal = (LPLOGPALETTE) malloc(sizeof(LOGPALETTE) +(sizeof (PALETTEENTRY) * m_palNumEntries));
        m_pLogPal->palVersion = 0x300;
        m_pLogPal->palNumEntries = m_palNumEntries;
        
        //copy palette entries into palentry array
        for (int i = 0; i < m_pLogPal->palNumEntries; i++)
            m_pLogPal->palPalEntry[i] = *m_pPal++;
        
        //position the ptr back to the beginning should we call this
        //code again
        m_pPal -= m_pLogPal->palNumEntries;
        
        //create the palette
        if ((m_hPal = ::CreatePalette((LPLOGPALETTE)m_pLogPal)))
            return TRUE;
    } 
    return FALSE;
}


Удачи
Булат
Re[2]: Открытие метафайлов в Visual C
От: Юнусов Булат Россия  
Дата: 19.01.02 13:50
Оценка:
Здравствуйте Юнусов Булат, Вы писали:

ЮБ>Здравствуйте Elder, Вы писали:


E>>Помогите, как открыть метафайлы (wmf) в Visual C++. Функция PlayMetafile() их не открывает (вернее открывает метафайлы, созданные функцией CopyMetafile(), а остальные не открывает, не смотря на то, что я и вырезаю у них первые 22 байта, как сказано).

ЮБ>Вот нрыл когда то класс для сабжа — работает
Где взял — не помню только, а то бы ссылку кинул
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.