【VC++】デバイスコンテキストを使って帳票を出力する
<機能>
(1)コモンダイアログ(印刷)を表示します
(2)デバイスコンテキストに文字を線を描画して帳票を生成します
(StartDoc→StartPage→EndPage→EndDoc)
(3)サンプルとして領収書を作成します
<イメージ>
<動作検証&開発環境>
Visual Studio Community 2017
<使い方>
Win32アプリケーションを作成します
1.Windowsデスクトップを選択
2.アプリケーションの種類で「コンソールアプリケーション」を選択
3.共通ヘッダの「MFC」にチェック
4.ソースを追加
//プロトタイプ宣言
void SamplePrintOut(CDC *pDC);
void SetLogFont(CDC *pDC, LOGFONT& logfont, CString csFontName, int iSize);
void DeleteFont();
void LineOut(CDC *pDC, int stx, int sty, int edx, int edy);
void SamplePrintOut(CDC *pDC);
void SetLogFont(CDC *pDC, LOGFONT& logfont, CString csFontName, int iSize);
void DeleteFont();
void LineOut(CDC *pDC, int stx, int sty, int edx, int edy);
//フォントを宣言
CFont *pFont10; //10ポイントのフォントを宣言
CFont *pFont20; //20ポイントのフォントを宣言
CFont *pFont10; //10ポイントのフォントを宣言
CFont *pFont20; //20ポイントのフォントを宣言
// 唯一のアプリケーション オブジェクトです。
CWinApp theApp;
using namespace std;
int main()
{
int nRetCode = 0;
{
int nRetCode = 0;
HMODULE hModule = ::GetModuleHandle(nullptr);
if (hModule != nullptr)
{
// MFC を初期化して、エラーの場合は結果を印刷します。
if (!AfxWinInit(hModule, nullptr, ::GetCommandLine(), 0))
{
// TODO: 必要に応じてエラー コードを変更してください。
wprintf(L"致命的なエラー: MFC の初期化ができませんでした。¥n");
nRetCode = 1;
}
else
{
//コモンダイアログ[印刷]で提供されているダイアログ
CPrintDialog dlg(FALSE);
//通常使うプリンターのデバイス コンテキストを取得するとき
//dlg.GetDefaults();
//コモンダイアログを表示するとき
if (dlg.DoModal() != IDOK) return nRetCode;
CDC prDC;
HDC hd = dlg.GetPrinterDC();
prDC.Attach(hd);
//プリンタデバイスコンテキストの情報が必要な時は GetDeviceCaps で取得
//int iPixelx = prDC.GetDeviceCaps(LOGPIXELSX); //水平方向のピクセル数
//int iPixely = prDC.GetDeviceCaps(LOGPIXELSY); //垂直方向のピクセル数
{
// MFC を初期化して、エラーの場合は結果を印刷します。
if (!AfxWinInit(hModule, nullptr, ::GetCommandLine(), 0))
{
// TODO: 必要に応じてエラー コードを変更してください。
wprintf(L"致命的なエラー: MFC の初期化ができませんでした。¥n");
nRetCode = 1;
}
else
{
//コモンダイアログ[印刷]で提供されているダイアログ
CPrintDialog dlg(FALSE);
//通常使うプリンターのデバイス コンテキストを取得するとき
//dlg.GetDefaults();
//コモンダイアログを表示するとき
if (dlg.DoModal() != IDOK) return nRetCode;
CDC prDC;
HDC hd = dlg.GetPrinterDC();
prDC.Attach(hd);
//プリンタデバイスコンテキストの情報が必要な時は GetDeviceCaps で取得
//int iPixelx = prDC.GetDeviceCaps(LOGPIXELSX); //水平方向のピクセル数
//int iPixely = prDC.GetDeviceCaps(LOGPIXELSY); //垂直方向のピクセル数
//印刷用の論理フォント(フォント種類やサイズ情報を含む)
LOGFONT logfont;
//10ポイント「MS 明朝」フォント
SetLogFont(&prDC, logfont, _T("MS 明朝"), 10);
pFont10 = new CFont;
pFont10->CreateFontIndirect(&logfont);
//20ポイント「HG丸ゴシックM-PRO」フォント
SetLogFont(&prDC, logfont, _T("HG丸ゴシックM-PRO"), 20);
pFont20 = new CFont;
pFont20->CreateFontIndirect(&logfont);
LOGFONT logfont;
//10ポイント「MS 明朝」フォント
SetLogFont(&prDC, logfont, _T("MS 明朝"), 10);
pFont10 = new CFont;
pFont10->CreateFontIndirect(&logfont);
//20ポイント「HG丸ゴシックM-PRO」フォント
SetLogFont(&prDC, logfont, _T("HG丸ゴシックM-PRO"), 20);
pFont20 = new CFont;
pFont20->CreateFontIndirect(&logfont);
//サンプル帳票の印刷処理開始
SamplePrintOut(&prDC);
SamplePrintOut(&prDC);
//後処理
prDC.Detach();
DeleteDC(hd);
prDC.Detach();
DeleteDC(hd);
//フォントオブジェクトの破棄
DeleteFont();
}
}
else
{
// TODO: 必要に応じてエラー コードを変更してください。
wprintf(L"致命的なエラー: GetModuleHandle が失敗しました¥n");
nRetCode = 1;
}
DeleteFont();
}
}
else
{
// TODO: 必要に応じてエラー コードを変更してください。
wprintf(L"致命的なエラー: GetModuleHandle が失敗しました¥n");
nRetCode = 1;
}
return nRetCode;
}
}
/*************************************************
関数名 SamplePrintOut
機能 サンプル帳票を生成
*************************************************/
void SamplePrintOut(CDC *pDC)
{
CFont *pOld;
関数名 SamplePrintOut
機能 サンプル帳票を生成
*************************************************/
void SamplePrintOut(CDC *pDC)
{
CFont *pOld;
//印刷領域を取得
CRect rect;
pDC->GetClipBox(&rect);
CRect rect;
pDC->GetClipBox(&rect);
//印刷ドキュメント(入出力ファイル情報)の設定
DOCINFO dinfo;
memset((char *)&dinfo, 0x00, sizeof(DOCINFO));
//DOCINFO構造体のサイズ
dinfo.cbSize = sizeof(DOCINFO);
//ドキュメント名
dinfo.lpszDocName = _T("やさしいプログラミング備忘録 VC++サンプル");
DOCINFO dinfo;
memset((char *)&dinfo, 0x00, sizeof(DOCINFO));
//DOCINFO構造体のサイズ
dinfo.cbSize = sizeof(DOCINFO);
//ドキュメント名
dinfo.lpszDocName = _T("やさしいプログラミング備忘録 VC++サンプル");
//ドキュメント開始
pDC->StartDoc(&dinfo);
//ページ開始
pDC->StartPage();
pDC->StartDoc(&dinfo);
//ページ開始
pDC->StartPage();
//大きいフォントを指定
pOld = pDC->SelectObject(pFont20);
//文字を出力
pDC->TextOut(700, 900, _T("領 収 書"));
pDC->TextOut(1700, 1400, _T("株式会社 ○○○○商事 様"));
pDC->TextOut(1100, 2000, _T("¥ 59,800(消費税込み)"));
//小さいフォントを指定
pDC->SelectObject(pFont10);
pDC->TextOut(3000, 950, _T("No.○○-1234567890"));
pDC->TextOut(3000, 1100, _T("2017年10月10日"));
pDC->TextOut(1600, 2500, _T("但し パンフレットデザイン費、及び印刷代金として"));
pDC->TextOut(1600, 2700, _T("上記正に領収いたしました。"));
pDC->TextOut(2200, 3500, _T("神奈川県横浜市○○区○○○1−2−3 ××ビル2階"));
pDC->TextOut(2700, 3650, _T("やさしいプログラミング備忘録 株式会社"));
pOld = pDC->SelectObject(pFont20);
//文字を出力
pDC->TextOut(700, 900, _T("領 収 書"));
pDC->TextOut(1700, 1400, _T("株式会社 ○○○○商事 様"));
pDC->TextOut(1100, 2000, _T("¥ 59,800(消費税込み)"));
//小さいフォントを指定
pDC->SelectObject(pFont10);
pDC->TextOut(3000, 950, _T("No.○○-1234567890"));
pDC->TextOut(3000, 1100, _T("2017年10月10日"));
pDC->TextOut(1600, 2500, _T("但し パンフレットデザイン費、及び印刷代金として"));
pDC->TextOut(1600, 2700, _T("上記正に領収いたしました。"));
pDC->TextOut(2200, 3500, _T("神奈川県横浜市○○区○○○1−2−3 ××ビル2階"));
pDC->TextOut(2700, 3650, _T("やさしいプログラミング備忘録 株式会社"));
//線を引く
LineOut(pDC, 3000, 1050, 4300, 1050);
LineOut(pDC, 1050, 2200, 4000, 2200);
LineOut(pDC, 3000, 1050, 4300, 1050);
LineOut(pDC, 1050, 2200, 4000, 2200);
//ページ終了
pDC->EndPage();
//ドキュメント終了
pDC->EndDoc();
pDC->EndPage();
//ドキュメント終了
pDC->EndDoc();
}
/*************************************************
関数名 SetLogFont
機能 フォントに種別、サイズを設定する
*************************************************/
void SetLogFont(CDC *pDC, LOGFONT& logfont, CString csFontName, int iSize)
{
memset(&logfont, 0x00, sizeof(logfont));
lstrcpy(logfont.lfFaceName, csFontName);
//LOGFONT構造体についてはDeveloperNetwork参照
//出力精度を指定
logfont.lfOutPrecision = OUT_TT_PRECIS;
//クリッピング領域を外れた時の精度
logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
//出力品質を指定
logfont.lfQuality = PROOF_QUALITY;
//ピッチとファミリを指定
logfont.lfPitchAndFamily = VARIABLE_PITCH | FF_SWISS;
//文字セットを指定
logfont.lfCharSet = SHIFTJIS_CHARSET;
//文字または文字の論理単位で、高さを指定(デバイス論理インチのピクセル数)
//MicrosoftSupport参考
logfont.lfHeight = -MulDiv(iSize, pDC->GetDeviceCaps(LOGPIXELSY), 72);
}
関数名 SetLogFont
機能 フォントに種別、サイズを設定する
*************************************************/
void SetLogFont(CDC *pDC, LOGFONT& logfont, CString csFontName, int iSize)
{
memset(&logfont, 0x00, sizeof(logfont));
lstrcpy(logfont.lfFaceName, csFontName);
//LOGFONT構造体についてはDeveloperNetwork参照
//出力精度を指定
logfont.lfOutPrecision = OUT_TT_PRECIS;
//クリッピング領域を外れた時の精度
logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
//出力品質を指定
logfont.lfQuality = PROOF_QUALITY;
//ピッチとファミリを指定
logfont.lfPitchAndFamily = VARIABLE_PITCH | FF_SWISS;
//文字セットを指定
logfont.lfCharSet = SHIFTJIS_CHARSET;
//文字または文字の論理単位で、高さを指定(デバイス論理インチのピクセル数)
//MicrosoftSupport参考
logfont.lfHeight = -MulDiv(iSize, pDC->GetDeviceCaps(LOGPIXELSY), 72);
}
/*************************************************
関数名 SetLogFont
機能 フォントに種別、サイズを設定する
*************************************************/
void DeleteFont()
{
if (pFont10) {
pFont10->DeleteObject();
delete pFont10;
}
if (pFont20) {
pFont20->DeleteObject();
delete pFont20;
}
}
関数名 SetLogFont
機能 フォントに種別、サイズを設定する
*************************************************/
void DeleteFont()
{
if (pFont10) {
pFont10->DeleteObject();
delete pFont10;
}
if (pFont20) {
pFont20->DeleteObject();
delete pFont20;
}
}
/*************************************************
関数名 LineOut
機能 線を引く
*************************************************/
void LineOut(CDC *pDC, int stx, int sty, int edx, int edy)
{
CPen newPen;
CPen *pOld = NULL;
newPen.CreatePen(PS_SOLID, 3, RGB(0, 0, 0));
pOld = pDC->SelectObject(&newPen);
関数名 LineOut
機能 線を引く
*************************************************/
void LineOut(CDC *pDC, int stx, int sty, int edx, int edy)
{
CPen newPen;
CPen *pOld = NULL;
newPen.CreatePen(PS_SOLID, 3, RGB(0, 0, 0));
pOld = pDC->SelectObject(&newPen);
pDC->MoveTo(stx, sty);
pDC->LineTo(edx, edy);
pDC->LineTo(edx, edy);
pDC->SelectObject(pOld);
}
}
よろしければポチッと押してください