изменение размера emf и его принтинг
От: overdose  
Дата: 09.06.03 12:46
Оценка:
здравствуйте коллеги.
столкнулся я со следующей проблемой и никак не могу ее решить уже неделю.
задача такая. у меня имеется emf определенного размера. мне надо этот размер изменить (уменьшить например), а потом распечатать этот файл на принтере. все получается как бы. размер emf Меняю. отсылаю его на принтер. но после распечатки вижу следующее: emf печатается два раза. первый раз в том размере, что мне надо. и второй раз-расстянутый на весь лист. вернее наоборот. сначала расстянутый на весь лист, а потом сверху наложенный нормального размера, как мне надо.
ниже приведу код, который я юзаю.

меняю размер emf
HDC c=GetDC(NULL);

HDC hEmfDC=::CreateEnhMetaFile(c, 0, &rc, "temp"); //rc содержит новый размер emf
CMetaFileDC* dc=new CMetaFileDC;
::SetMapMode(hEmfDC, MM_HIMETRIC);
dc->Attach(hEmfDC);
dc->SetMapMode(MM_HIMETRIC);
rc.top=-rc.top;
rc.bottom=-rc.bottom;

::PlayEnhMetaFile(dc->GetSafeHdc(),phEmf,&rc)
DeleteEnhMetaFile(phEmf);
phEmf=dc->CloseEnhanced(); //получаю тут новый emf

ZeroMemory(&emh, sizeof(ENHMETAHEADER));
emh.nSize=sizeof(ENHMETAHEADER);
GetEnhMetaFileHeader(phEmf,sizeof(ENHMETAHEADER),&emh);
::SetRect(&rc,emh.rclFrame.left,emh.rclFrame.top,emh.rclFrame.right,emh.rclFrame.bottom);

CloseEnhMetaFile(hEmfDC);
dc->Detach();
delete dc;


теперь посылаю Emf на печать на принтер
if(_printerDC.StartPage()<0)
{
 _printerDC.AbortDoc();
}
else
{
 _printerDC.SetMapMode(MM_HIMETRIC);
 _printerDC.SetViewportOrg(0, 0);
 _printerDC.SetViewportOrg(-_printerDC.GetDeviceCaps(PHYSICALOFFSETX),
          -_printerDC.GetDeviceCaps(PHYSICALOFFSETY));
 ::PlayEnhMetaFile(_printerDC.GetSafeHdc(), phEmf, &rc);
_printerDC.EndPage();
}
 DeleteEnhMetaFile(phEmf);
}
 _printerDC.EndDoc();


вот в принципе и весь код.
расскажите плз, в чем проблема, а то я уже запарился

09.06.03 22:41: Перенесено модератором из 'C/C++' в WinAPI. Оффтопик. — ХД
Re: изменение размера emf и его принтинг
От: Patalog Россия  
Дата: 09.06.03 13:50
Оценка:
Здравствуйте, overdose, Вы писали:

[]

Хм, а сразу PlayEnhMetaFile в контекст принтера с нужным RECT разве не помогает? Или установи SetWorldTransform для принтера.
O>ZeroMemory(&emh, sizeof(ENHMETAHEADER));
O>emh.nSize=sizeof(ENHMETAHEADER);
O>GetEnhMetaFileHeader(phEmf,sizeof(ENHMETAHEADER),&emh);
O>::SetRect(&rc,emh.rclFrame.left,emh.rclFrame.top,emh.rclFrame.right,emh.rclFrame.bottom);

Это вообще танцы с бубном. Зачем?
Почетный кавалер ордена Совка.
Re[2]: изменение размера emf и его принтинг
От: overdose  
Дата: 09.06.03 14:57
Оценка:
Здравствуйте, Patalog, Вы писали:

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


P>[]


P>Хм, а сразу PlayEnhMetaFile в контекст принтера с нужным RECT разве не помогает? Или установи SetWorldTransform для принтера.


не могли бы вы пояснить свою мысль? в коде я написал, что в методе PlayEnhMetaFile я передаю RECT с нужными размерами. контекст принтера у меня настроен на работу с форматом А4. после принтинга я имею то, что имею.
Re: изменение размера emf и его принтинг
От: overdose  
Дата: 09.06.03 17:05
Оценка:
извините. а зачто модерировали мой топик???
Re[2]: изменение размера emf и его принтинг
От: Patalog Россия  
Дата: 10.06.03 05:56
Оценка:
Здравствуйте, overdose, Вы писали:

[]

Потомучта форум C\C++ — это все что касается языка as is.
Почетный кавалер ордена Совка.
Re: изменение размера emf и его принтинг
От: Valerio Россия linkedin.com/in/boronin
Дата: 10.06.03 06:06
Оценка:
Здравствуйте, overdose, Вы писали:

O>ZeroMemory(&emh, sizeof(ENHMETAHEADER));

O>emh.nSize=sizeof(ENHMETAHEADER);
O>GetEnhMetaFileHeader(phEmf,sizeof(ENHMETAHEADER),&emh);
O>::SetRect(&rc,emh.rclFrame.left,emh.rclFrame.top,emh.rclFrame.right,emh.rclFrame.bottom);

если правильно помню, это действие не имеет глубокого сермяжного смысла, т.к. метафайл генерируется внутри с уже прописанными жестко координатами и т.п. Соотв. чтобы Ваш новый кусок подействовал минимально, нужно настроить систему координат и повторить процесс записи

а то что Вы сделали похоже на грубый хак , тогда уж надо все пробежаться по всем записям в метафайле и поправить соотв. все координаты соотв?

вообще, раз уж Вы взялись за метафайлы, очень рекомендую сначала найти и прочесть Фень Юаня Windows GDI programming — там есть глава посвященная именно метафайлам и спулингу печати. И примеры!
... << RSDN@Home 1.0 beta 7a >>
Valery A. Boronin, RSDN Team, linkedin.com\in\boronin
R&D Mgmt & Security. AppSec & SDL. Data Protection and Systems Programming. FDE, DLP, Incident Management. Windows Filesystems and Drivers.
Re[3]: изменение размера emf и его принтинг
От: Patalog Россия  
Дата: 10.06.03 06:35
Оценка:
Здравствуйте, overdose, Вы писали:

[]

O>не могли бы вы пояснить свою мысль? в коде я написал, что в методе PlayEnhMetaFile я передаю RECT с нужными размерами. контекст принтера у меня настроен на работу с форматом А4. после принтинга я имею то, что имею.


Убрать эти танцы с бубном вокруг создания нового метафайла etc., а сразу отправлять его (исходный) на печать.
HWND desktop = GetDesktopWindow();
HDC dc = GetDC(desktop);

//Create metafile. You don't need to do that because you alraedy have it.
RECT rc_meta = { 0, 0, 5000, 5000 }; //..specifies the dimensions (in .01-millimeter units) 
HDC meta_dc = CreateEnhMetaFile(dc, "C:\\Temp\\1.emf", &rc_meta, "");
_ASSERTE(meta_dc);
            
MoveToEx(meta_dc, 50, 50, NULL);
LineTo(meta_dc, 150, 150);
            
SetTextColor(meta_dc, RGB(0, 0, 0));
std::string text = "Sample text";
TextOut(meta_dc, 0, 0, text.c_str(), text.size());
/* 
Other draw stuff
*/
            
HENHMETAFILE meta_file = CloseEnhMetaFile(meta_dc);
_ASSERTE(meta_file);

//print metafile        
PRINTDLG pd = { sizeof(pd) };
pd.Flags = PD_RETURNDC;
BOOL res = PrintDlg(&pd);
    if(res)
    {
        HDC print_dc = pd.hDC;

        DOCINFO di = { sizeof(di), "Sample EMF printing" };
        int job_id = StartDoc(print_dc, &di);
        _ASSERTE(job_id > 0);
        int ret = StartPage(print_dc);
        _ASSERTE(ret > 0);

        RECT rc_clip = { 0 }; //Set dimensions you need (in logical units)
        GetClipBox(print_dc, &rc_clip);

        PlayEnhMetaFile(print_dc, meta_file, &rc_clip);

        EndPage(print_dc);
        EndDoc(print_dc);
    }

DeleteEnhMetaFile(meta_file);
    
ReleaseDC(desktop, dc);
Почетный кавалер ордена Совка.
Re[2]: изменение размера emf и его принтинг
От: Patalog Россия  
Дата: 10.06.03 10:53
Оценка: +1
Здравствуйте, Valerio, Вы писали:
[]

V>если правильно помню, это действие не имеет глубокого сермяжного смысла, т.к. метафайл генерируется внутри с уже прописанными жестко координатами и т.п. Соотв. чтобы Ваш новый кусок подействовал минимально, нужно настроить систему координат и повторить процесс записи


Это действительно не имеет никакого сакрального смысла. Но не потому, что там чего-то жестко зашито. rcFrame — это так, в довесок. Ибо metafile -векторный формат, посему по определению масштабируется.

V>а то что Вы сделали похоже на грубый хак , тогда уж надо все пробежаться по всем записям в метафайле и поправить соотв. все координаты соотв?


Не нужно.

V>вообще, раз уж Вы взялись за метафайлы, очень рекомендую сначала найти и прочесть Фень Юаня Windows GDI programming — там есть глава посвященная именно метафайлам и спулингу печати. И примеры!


Эта глава немного о другом.
Почетный кавалер ордена Совка.
Re[3]: изменение размера emf и его принтинг
От: Valerio Россия linkedin.com/in/boronin
Дата: 10.06.03 13:04
Оценка:
Здравствуйте, Patalog, Вы писали:

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

P>[]

V>если правильно помню, это действие не имеет глубокого сермяжного смысла, т.к. метафайл генерируется внутри с уже прописанными жестко координатами и т.п. Соотв. чтобы Ваш новый кусок подействовал минимально, нужно настроить систему координат и повторить процесс записи


P>Это действительно не имеет никакого сакрального смысла. Но не потому, что там чего-то жестко зашито. rcFrame — это так, в довесок. Ибо metafile -векторный формат, посему по определению масштабируется.


да, конечно! нужно настроить систему координат и повторить процесс воспроизведения, а не записи

V>а то что Вы сделали похоже на грубый хак , тогда уж надо все пробежаться по всем записям в метафайле и поправить соотв. все координаты соотв?


P>Не нужно.


V>вообще, раз уж Вы взялись за метафайлы, очень рекомендую сначала найти и прочесть Фень Юаня Windows GDI programming — там есть глава посвященная именно метафайлам и спулингу печати. И примеры!


P>Эта глава немного о другом.

да я вспомнил, действительно, не о том была речь в книге, а о другом
... << RSDN@Home 1.0 beta 7a >>
Valery A. Boronin, RSDN Team, linkedin.com\in\boronin
R&D Mgmt & Security. AppSec & SDL. Data Protection and Systems Programming. FDE, DLP, Incident Management. Windows Filesystems and Drivers.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.