まったくの初心者です。よろしくお願いします。
現在、画像の印刷ができなくて困っております。
環境は、
Windows XP SP2
Visual C++ 6.0
ダイアログベースでの開発です。
現在の状況は、プログラムによって作成されたピクチャボックスの
画像は表示できています。
質問は、そこに[印刷]のボタンを作成して、画像を印刷したいのですが、
プログラムの仕方がわかりません。
いまの印刷ボタンのコードは下のようになっています。
void CSeekDlg::OnButton19()
{
// TODO: この位置にコントロール通知ハンドラ用のコードを追加してください
//CPrintDialogオブジェクトを作成する
CPrintDialog dlgPrint(FALSE, PD_ALLPAGES, this);
if(dlgPrint.DoModal() == IDOK)
{
//印刷に用いるデバイスコンテキストをダイアログから取得し、
//CDCオブジェクトに結びつける
CDC dcPrint;
dcPrint.Attach(dlgPrint.GetPrinterDC());
//DOCINFO構造体を生成し、データを設定
DOCINFO myPrintJob;
myPrintJob.cbSize = sizeof(myPrintJob);
myPrintJob.lpszDocName = MyPrintJob;
myPrintJob.lpszOutput = NULL;
myPrintJob.lpszDatatype = NULL;
myPrintJob.fwType = NULL;
//ドキュメントの印刷を開始
if(dcPrint.StartDoc(&myPrintJob) >= 0)
{
//ページを開始
dcPrint.StartPage();
//描画を開始
dcPrint.TextOut(0, 0, MyPrintJob);
//ページを終了
dcPrint.EndPage();
//ドキュメントを閉じる
dcPrint.EndDoc();
}
//プリンタのデバイスコンテキストを開放
dcPrint.DeleteDC();
}
}
このまま印刷ボタンを押すと、「MyPrintJob」としか印刷されません。当たり前ですが。。。
ピクチャボックスの画像を印刷できるようなプログラムが知りたいです。
どうかよろしくお願いします。
基本的には画面だろうがプリンタだろうがDCに対して
関数を呼び出すと言う点では同じです。
なので、DCに対してbmp画像を描画するにはどうすれば良いかを
調べれば良い事になります。
画面のDCに対してbitmapを描画するサンプルを調べると
何かわかると思います。
あと、画面とプリンタでは解像度が違います。
従って画面と全く同じ方法で描画してしまうと
解像度の違いで表示される大きさが変わってきます。
一般的にはプリンタの方が解像度が大きいので
画面よりも小さなサイズで印刷されるはずです。
解像度が大きいではなくて解像度が高いと書くべきだったかも。
> dcPrint.TextOut(0, 0, MyPrintJob);
// dcPrint.SetViewportOrg(...);
// dcPrint.SetWindowExt(...);
// dcPrint.SetViewportExt(...);
SendDlgItemMessage(
ピクチャボックスID, WM_PRINTCLIENT, WPARAM(dcPrint.GetSafeHdc()), PRF_CLIENT
);
手軽にやるならば上記方法でいけそうではある。(動作未確認なのでできない場合は謝る)
まじめにやるならば以下のような感じか
1、STM_GETIMAGE でピクチャボックスに設定しているHBITMAPを取得
2、CreateCompatibleDC() でメモリDCを作成して [1] を SelectObject()
3、dcPrint.BitBlt( [2] )
PATIO様、gak様ありがとうございます。
ただいま、gak様の
// dcPrint.SetViewportOrg(...);
// dcPrint.SetWindowExt(...);
// dcPrint.SetViewportExt(...);
SendDlgItemMessage(
ピクチャボックスID, WM_PRINTCLIENT, WPARAM(dcPrint.GetSafeHdc()), PRF_CLIENT
);
の方法に書き変えたところ、なんとか小さな四角形が紙の左上に表示されるようになりま
した。
しかし、その中にはなにも写っていません・・・。
実は、ピクチャボックスに設定しているものは、
void CSeekDlg::OnButton1()
{
// TODO: この位置にコントロール通知ハンドラ用のコードを追加してください
FILE *file;
double lk1=0,lk2=0,lk3=0,lk4=0,lk5=0,lk6=0;
file = fopen(c:\\data_check\\0\\test.txt,rb);
fread(&dk, sizeof(dk),1,file);
fread(&io, sizeof(io),1,file);
//ピクチャーボックス設定
CWnd* h=GetDlgItem(IDC_PICT);
CDC* pDC=h->GetDC();
SetPict0(h,pDC);
CPen p(PS_SOLID,1,RGB(0,0,255));
CPen* oldp=pDC->SelectObject(&p);
//目標軌道表示
Line(pDC,0,0,(int)(ganma*ganma*io.X2a),(int)(ganma*ganma*io.Y1a),RGB(0,0,0));
Line(pDC,0,0,(int)(ganma*ganma*io.X1a),(int)(ganma*ganma*io.Y1a),RGB(0,0,0));
int k;
for(k=0;k<dk.kn;k++){
if(dk.ex[k]==0)
{
Line(pDC,(int)dk.cg_xa[k],(int)dk.cg_ya[k],(int)dk.cg_xa[k+1],(int)dk.cg_ya[k+1],RGB(0,200,150));
}
・・・
というふうに、Line関数で書かれたものなのでBITMAPではありません。
なので、このLine関数によって書かれた線をBITMAPに変換したいのですが、そのような方
法はあるのでしょうか。
また解像度についても調べているのですが、なかなか有益な情報が得られません。解像度
の変更の仕方などあればご教授お願いします。
解像度を変更するのではなくて解像度に合わせて描画するのが正解です。
具体的には画像であれば、引き伸ばして貼り付ける。
直接描画するのであれば、解像度の違いの分だけ拡大して描画する。
となります。
まあ、マッピングの調整等で同じような事が出来ると思いますけれど、
実際に計算して行うのか、マッピングで済ませてしまうのかは
御自分で判断して良いと思います。
あと、ここに書いている方法だと他のウインドウが重なると
書いていた内容が消えませんか?
通常、描画処理をボタンのイベント内には書きませんよ。
描画に関する処理はダイアログならOnPaint内に書く必要があります。
この辺は、画面描画の基本なのでちゃんと勉強した方がいいです。
この辺の理屈を理解せずに進むとハマリますから。
ピクチャボックスをただの枠にしてしまって、
描画範囲を特定する為の手段と割り切ってしまうと
ダイアログのクライアント領域に描画できるようになるので
ダイアログ内に描画用の関数を作成してその関数を
画面描画にも印刷にも使うようにすると無駄が無いかもしれません。
自前でビットマップを作成してそこに描画しておいて
そのビットマップをピクチャボックスに設定すると言う手もあるとは
思いますけれど、まずは普通に画面に書くところからやった方が
いいかなと思います。
ちなみにWindowsの画面の描画仕組みの触りだけであれば、
ここの掲示板の中でも何度か書いています。
検索してみると引っかかるかもしれません。
ポイントはWindowsのプログラムの基本はイベントドリブンだと言う事。
そして、そのイベントの殆どはWindows OSが各アプリに対して出していて
アプリケーションはそのイベントにそって動作していると言うことです。
これは、画面描画に関しても例外では有りません。
PATIO様ありがとうございます。
このプログラミングの改良を試みており、ただいま勉強中なのですが、まだまだ勉強不足
のようです。
まずはOnPaint関数による描画を学んで、PATIO様のおっしゃることが十分理解できるよう
になってから、印刷に移りたいと思います。
ご教授ありがとうございました。またわからないことがあったら質問するので、よろしく
お願いします。