プリントダイアログを出さずに印刷する話
MFCな話。
印刷する時はプリントダイアログを使ってDEVMODE構造体を作り、それを用いてdcを更新してごにょごにょする。
CPrintDialog dlg(FALSE); if ( dlg.DoModal() == IDCANCEL ) { return FALSE; } DEVMODE* mode = (DEVMODE*)::GlobalLock(dlg.m_pd.hDevMode); // ...
ダイアログを出さずに印刷する場合は、デフォルトのDEVMODE構造体を作っておき、それに色々な設定をする。
CPrintDialog dlg(FALSE);
dlg.GetDefaults();
DEVMODE* mode = (DEVMODE*)::GlobalLock(dlg.m_pd.hDevMode);
mode->dmOrientation = DMORIENT_LANDSCAPE;
// ...
// DEVMODEで設定出来る内容:DEVMODE structure (Windows)
なのだが、プリンタ固有の機能、例えばフチなし印刷だとか写真モードだとかはドライバ依存で、そう言う機能へのアクセス方法がよくわからない。
いろいろ調べると、そう言ったデータはDEVMODEに続くメモリ領域に保存されているらしい。それをデータとして取り出してどうにか保持すれば、初回(データを作る際)はともかくそれ以降は、ダイアログを出さずそのデータを流用出来るのではないか。と考えてやってみたら成功した。
DEVMODEに続く領域、というのがどれくらいかは、その大きさがDEVMODE構造体内にdmDriverExtraとして保持されている。従って、DEVMODEの先頭を指し示すポインタを起点に、DEVMODE構造体のサイズ+dmDriverExtra分読めば良い。
とりあえずファイルに書き出してみる。
CPrintDialog dlg(FALSE); if (dlg.DoModal() == IDCANCEL) { return FALSE; } CFile file( PATH_TO_SAVED_DEVMODE, CFile::modeWrite | CFile::shareDenyWrite | CFile::modeCreate); DEVMODE* mode = (DEVMODE*)::GlobalLock(dlg.m_pd.hDevMode); file.Write( mode, sizeof( DEVMODE ) + mode->dmDriverExtra ); file.Close(); // ...
再利用時、ファイルから読み出してDEVMODEを作れば、ダイアログを出す必要が無い。
CFile file(PATH_TO_SAVED_DEVMODE, CFile::modeRead | CFile::shareDenyWrite ); DEVMODE tmp; file.Read( &tmp, sizeof( DEVMODE ) ); file.Seek( 0, CFile::begin ); DEVMODE* mode = (DEVMODE*)malloc( sizeof( DEVMODE ) + tmp.dmDriverExtra ); file.Read( mode, sizeof( DEVMODE ) + tmp.dmDriverExtra ); file.Close(); // ... free( mode ); // ...
dmDriverExtraを取得するために、一時的なDEVMODEを作っている。その後先頭にシークし直し、全体が入る領域を確保してから読み出している。