はじめまして limiと申します。
過去ログを探してみたのですが該当する問題に対して有効な手段が
見つかりませんでした。
やりたい事としては
・一時作成したDCに対して描画内容を記述し、
実際のDCにコピーして印刷・印刷プレビュー表示をする
です。
現象としては、
通常には普通の大きさの文字で表示されるのですが、
印刷や印刷プレビューにするととても小さな文字に
縮小印刷(プレビュー)されてしまいます。
何か処理が抜けているのかと考えているのですが
アドバイスお願いできないでしょうか。
よろしくお願いします。
※ウイザードで生成したソースに対してOnDrawしか記述を
追加しておりません。
void Cprint_sampleView::OnDraw(CDC* pDC)
{
Cprint_sampleDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
//画面サイズ取得
CRect rect;
GetClientRect(rect);
//仮想デバイスコンテキスト作成
CDC myDC;
myDC.CreateCompatibleDC(pDC);
//仮想デバイスコンテキスト用ビットマップ作成
CBitmap myBitMap;
CBitmap* oldBitMap;
myBitMap.CreateCompatibleBitmap(pDC,rect.right,rect.bottom);
oldBitMap = myDC.SelectObject(&myBitMap);
//myDC.BitBlt(0,0,rect.right,rect.bottom,pDC,0,0,SRCCOPY);
//ブラシパターンをコピー
myDC.PatBlt(0,0,rect.Width(),rect.Height(),PATCOPY);
//仮想デバイスコンテキストに描画
myDC.SetBkMode(TRANSPARENT);
myDC.TextOut(0,0,テスト);
//仮想デバイスコンテキスト→現在のデバイスコンテキストにビットマップコピー
pDC->BitBlt(0,0,rect.Width(),rect.Height(),&myDC,0,0,SRCCOPY);
//解放処理
myDC.SelectObject(oldBitMap);
myBitMap.DeleteObject ();
myDC.DeleteDC();
}
プリンタでは、1ピクセルのサイズが画面に比べてとても小さいので、
画面サイズのビットマップをそのまま印刷すると、
画面上の見た目より小さくなります。
GetClientRect() ではなく、
pDC->GetDeviceCaps(HORZRESやVERTRES) で描画域のサイズを得ます。
画面とプリンタでは解像度が違う為(dairygoodsさんの説明がそれです)ですね。
画面の解像度は状況によって違いはありますけれど、100DPI位です。
プリンタの解像度は良く宣伝文句にあるのでわかると思いますが、
画面に比べるとすごく高い解像度になります。
同じ表示サイズ(定規で測ったサイズ)であれば、解像度が高いほど
1ドットのサイズは小さくなります。
画像の大きさはドット数で表されているので1ドットが小さいと
画像の見た目大きさ(定規で測ったサイズ)も小さくなります。
画面上と同じくらいの大きさにしたいのであれば、
解像度の違いを考慮して画像を引き伸ばす必要があります。
この辺は、画面上に図形を書くときにも適応されますから
覚えておいた方が良いと思います。
基本的には描画は解像度を外から与えてやれば、
見た目が同じなる様にプログラミングしておくのが良いと思います。
あと、単に引き伸ばしてしまうと荒れた画像になってしまうので
直接描画できるものなら直接描画した方がいいです。
先に書いているようにプリンタのDCは解像度が大変高いので
それに見合うDCは非常に大きな物になります。
用紙サイズが大きくなるとメモリを恐ろしく食います。
なのでプリンタの出力時はバックバッファを使った描画は
あまりやらないほうがいいです。
画面描画と違ってそこまでスピードが求められる事もないですし。
その昔、バックバッファを使わざる得ない事情があって
印刷時の処理に大変苦労した記憶があります。
用紙全体をカバーするようなバックバッファがとれない事があるので
小さなバックバッファに分割して描画し、つなぎ合わせるという
メンドクサイ事をしていました。
もとい、DCが大きなるというよりも
そこに載せるビットマップが大きくなると言うべきですね。
フルカラーのA3のビットマップなんてとんでもないサイズになりますよ。
dairygoodsさん PATIOさんありがとうございます。
早速やってみます。
まだうまくできていませんが、プリンタ解像度とディスプレイ解像度の違いに
すら気づいていませんでした。
印刷に関する基本的な仕組み(単純な書き方だけではなく)を
理解したいと思うのですが、どの参考書を読んでもさらっとしか
かかれておりません。
もし、お勧めの書籍やHPなどがございましたら教えて頂けないでしょうか。
>印刷に関する基本的な仕組み(単純な書き方だけではなく)
というわけではないですが、
pDC->GetDeviceCaps(LOGPIXELSXやLOGPIXELSY) で解像度を調べることができます。
これをディスプレイデバイス、プリンタデバイスのそれぞれについて求めれば
比率がわかるので、ディスプレイの解像度を基準にした印刷もできるでしょう。
またSetMapModeでマッピングモードを変えることにより
解像度に依存しない描画を選ぶことも可能です。
一番の参考資料はHELP(MSDN)なんですけどね。
恐らくMFCを使っていると思いますので
MFCのフレームワーク上で印刷がどういう動きになるのかを
まず勉強されてはどうでしょうか?
多分、今の状態では複数ページにわたる印刷とかのやり方も
わからないと思いますし。
印刷のキーワードで調べればそれらしいのが出てきたと思います。
印刷の時に解像度を意識して描画する必要があるのは
画面との解像度の違いもありますけれど、プリンタの設定で
解像度をある程度変更できると言うのも理由の一つです。
なので固定の解像度で描画してしまうと設定で変更された時に
意図したサイズで描画できなくなります。
さらに描画時のマッピングモードによって指定した論理座標が
どう物理座標に展開されるのかも変わってきますので
この辺は印刷に限定せずに描画の基本知識として
色々やってみる事をお勧めします。
WindowsのGDIの解説書なんかには書いていそうですけどね。
印刷時のディスプレイとプリンタの解像度の違いを
補正するにはぞれそれ解像度の違いを補正したコーディング
を行うか、マッピングモードを変更することで可能なんですね。
HELP(MSDN)を参考にしていたのでフレームワーク上での動きは
理解していました。
実際どのような動きを実現すればいいのかがわかっていませんでした。
ちょうど本屋でみた「マニュアルが教えないMFC」という本に
印刷部分の流れが載っていましたので今参考にしているところです。
WindowsのGDIの解説書も参考にしてみます。
ありがとうございます。
マッピングモードをMM_LOMETRICに設定することで解決できました。
どうもありがとうございました。