Excel文書に黄色いカバーが重ならない理由とは?

このQ&Aのポイント
  • 特定の印刷プログラムやWord文書では、黄色いカバーを印刷するために用紙全体を黄色に印刷している
  • しかし、Excel文書では黄色いカバーが重ならず別々に印刷されてしまう
  • Excelが自分の出力領域にロックを掛けている可能性がある
回答を見る
  • ベストアンサー

AlphBlendとExcel???

自社で作成した特定の印刷プログラム(4ケあります)とWord全部の印刷ドキュメントには取扱注意を要する情報が印刷されています これらの特定印刷プログラムやWordで印刷したドキュメントの取扱注意を促すため、用紙全体を薄い黄色に印刷しています まるで用紙全体に黄色いカバーを掛けたように見えますので、充分な注意喚起が出来ます 黄色いカバーをする方法は以下のように単純です 印刷開始のトリガーになるAPIであるEndPageにAPIフックを仕掛けます 【APIフックは ADVANCED WINDOWS 著者 Jeffrey Ricther 発刊元 Microsoft社 を参考にさせて頂きました】 EndPageをフックしたらプログラムが自社開発した特定印刷プログラム、またはWord文書であるか否かを判定します これにはGetModuleFileNameWを呼出し、戻り値の内容を調べます リスト(1)を箇所です 4ケの特定印刷プログラム、Word文書である際には次の処理(薄い黄色でカバー)に流し、他の場合にはいきなり(3)の本物のEndPageに移します 薄い黄色でカバーする方法は、まずプリンターと同じメモリーDCを作ります そのメモリーDC全体を黄色に塗り潰します メモリーDCに作った黄色イメージを10%の透明度でプリンタ領域に上書きします すると実際に印刷された用紙は取扱注意を促す黄色になります 具体的なフックプロセスの主要部分は次の通りです 【実際にはもっとゴチャゴチャしていますが、話を単純化するため枝葉をカットしてあります】 int WINAPI Hook_EndPage(HDC hdc) { (1)GetModuleFileNameWでプログラム名を調べ、特定の印刷プログラム・Word文書であれば次の処理をする もし異なればイキナリ(3)へ飛ばします int Xsize = GetDeviceCaps(hdc, HORZRES); //プリンタの領域サイズを調べる int Ysize = GetDeviceCaps(hdc, VERTRES); hdcMemDC = CreateCompatibleDC(hdc); //プリンタと同じメモリーDCを作る HBITMAP hDrawBmp = CreateCompatibleBitmap(hdc,Xsize,Ysize); //調べたプリンタサイズと同 一のビットマップを作る SelectObject (hdcMemDC, hDrawBmp); //ビットマップをメモリーDCに結び付ける HPEN NEWPEN,OLDPEN; NEWPEN = CreatePen(PS_DASH, 2, RGB(255,255,000)); //黄色ペンを作る OLDPEN = (HPEN)SelectObject(hdcMemDC,NEWPEN); //作った黄色ペンをメモリーDCに結び付ける HBRUSH NEWBRUSH,OLDBRUSH; NEWBRUSH = CreateSolidBrush(RGB(255,255,000)); //黄色のブラシを作る OLDBRUSH = (HBRUSH)SelectObject(hdcMemDC,NEWBRUSH); //作った黄色ブラシをメモリーDCに結び付ける Rectangle(hdcMemDC,0,0,Xsize,Ysize); //黄色ペン、ブラシでメモリーDC全体を真黄色にする SelectObject(hdcMemDC,OLDPEN); //ペンとブラシを元に戻す SelectObject(hdcMemDC,OLDBRUSH); ここを(2)とします(後で説明します)   //メモリーDCに作成した黄色イメージ全体を10%の透明度でプリンタ領域に上書きする BLENDFUNCTION blendFunction; ::memset (&blendFunction, 0, sizeof(blendFunction)); //ゼロクリア   blendFunction.BlendOp = AC_SRC_OVER;   blendFunction.BlendFlags = 0; blendFunction.SourceConstantAlpha = 256/10;  ← 10%の透明度を指定   blendFunction.AlphaFormat = 0;   bool rtn = AlphaBlend(hdc, 0, 0, Xsize, Ysize, hdcMemDC, 0, 0, Xsize, Ysize, blendFunction);   //オリジナルEndPageを呼び出す   int nResult = ((PFNENDPAGE)(PROC) g_EndPage)(hdc);   (3)   return nResult; } このEndPageフックを仕掛けるとC#、C++で作った自社の特定印刷プログラムと全てのWord文書は意図した通り黄色いカバーが掛って印刷されます ところが今回、Excel文書も黄色いカバーを掛けることになりました (1)の箇所でExcelも選別してやればOKになるだろうと安易に考えていましたが、実際にテストしてみると次のような現象が発生してNGなのです Excel文書は従前のごとく印刷されます(黄色いカバーが掛っていません) 次に10%の透明度で印刷された黄色い用紙が出てきます すなわちプリンタ領域に出力されたExcel文書とメモリーDCの黄色いイメージが重ならず別々に印刷されてしまいます このとき印刷中のExcel画面には   現在1/1ページを印刷中です   ⇒ 添付画像を参照ください と表示されますので、Excel自体は1ページの文書を印刷しているつもりなのでしょう Excel文書の後に黄色いカバーがくっついていると思っているのでしょう なぜAlphBlend APIはメモリーDCイメージをExcelプリンター領域に重ねてくれないのでしょうか? まるでExcelが自分の出力領域にロックを掛けているような印象です 念の為、(2)に SetTextAlign (hdc, 0);    //テキスト配置オプションではカレントポジションを使用しない MoveToEx(hdc, 0, 0, NULL);  //カレントポジションをゼロに戻す の2ラインを入れて、印刷カレントポジションを原点に戻しても結果は同一でした 質問】 1. なぜExcel文書だけ黄色いカバーが重ならないのでしょうか? 2. Excelの印刷範囲指定操作    印刷するセルを選択 ⇒ ページレイアウト ⇒ 印刷範囲 ⇒ 印刷範囲の設定 が関係しているのではないかとの参考意見を同僚がくれました では上記の操作はどのようなAPIを出しているのでしょうか? もしそのAPIが分かればフックして調べてみたいと思います このExcel文書に黄色いカバーを掛けることで相当な時間を費やしてしまいました でも手掛かりが全くなく困っております どんなヒントでも結構です、ぜひ教えてください、お願い申し上げます

質問者が選んだベストアンサー

  • ベストアンサー
  • chie65535
  • ベストアンサー率43% (8508/19344)
回答No.1

EXCELの場合、用紙の地の色を変えても「セルの印刷時に、セルの背景色ですべてが塗り潰される」ので、用紙の地の色を変えても無駄です。 やろうと思っても「すべてのセルの背景色を薄い黄色にする」くらいしか出来ません。 折角、黄色いカバーを重ねても、その上から「セルが描画されて、セルの背景色で塗り潰される」のですから、黄色いカバーを重ねても無意味です。

sato-may
質問者

お礼

ありがとうございました 大変参考になりました 今後も宜しくお願い申しあげます

関連するQ&A

  • StartPage(hdc)のhdcはプリンタだけ

    StartPage(hdc)のhdcは必ずプリンタですか? Windows API に StartPage(hdc)、 EndPage(hdc)があります hdcにはプリンタのデバイスコンテキストのハンドラーを指定します ここで逆説的な質問です 『StartPage、EndPageをAPIフックして捕まえたhdcは必ずプリンタもしくはプリンタコンパティブルのメモリーDCですか?』 プリンタ類似以外のデバイスにStartPage、EndPageのAPIが指定されることはありますか?

  • HDCを他の領域にコピーするには?

    HDC hdc = CreateDC("WINSPOOL","プリンタの名前",NULL,NULL); ....(1)プリンタのHDCの作成 HDC hdcMemDC = CreateCompatibleDC(hdc); ....(2)前者と同じ仕様のメモリーHDCの作成 hdcとhdcMemDCはハンドラへのポインタだと思います hdc ....(ポインタ)....... hdcの内容 (A) hdcMemDC ....ポインタ.......hdcMemDCの内容 (B) もしBをA領域に書き写せば TextOut(hdc,0,0,"メモリーDCに書き込めると思います",100); とするとプリンタにではなくメモリ-DCに書込むと思います   ⇒ BをAに書き写さずTextOut(hdcMeMDC,0,0,"メモリーDCに書き込めると思います",100);と同じ結果になるでしょう ところが『BをAに書き写す』方法が分かりません ハンドラの構成、サイズなどの資料を探しましたが適当なものが見つかりません ご存知でしたら教えてください 【追加説明】 TextOut(hdc,0,0,"メモリーDCに書き込めると思います",100); のステートメントを TextOut(hdcMeMDC,0,0,"メモリーDCに書き込めると思います,100); にするには一般的にはAPIフックが必要になります ⇒ もちろん全ソースの手修正でも可能ですが...... APIフックも手修正も回避したいのです

  • プリンタBMP領域のサイズは?

    プリンタと同じメモリDCを作り、そこに書き込んだものをBitBltでコピーして印刷します ← サンプルのコードを参照させて頂きましたので多分間違えは無いと思います ところが確保すべきBMP領域(プリンタのサイズ)が分りません ?????????の箇所に設定すべき定数は何処を参照すれば良いのでしょうか? 困っております、ぜひご指導願います HDC hdc; DOCINFO docinfo; memset(&docinfo, 0, sizeof(DOCINFO)); docinfo.cbSize = sizeof(DOCINFO); docinfo.lpszDocName = L"testprint"; hdc = CreateDC(L"EPMJ3", L"Canon MP280 series Printer", NULL, NULL); StartDoc(hdc, &docinfo); StartPage(hdc); HDC hdcMem = CreateCompatibleDC (hdc); int Xsize = ???????????????? int Ysize = ???????????????? HBITMAP hDrawBmp =CreateCompatibleBitmap(hdc,Xsize,Ysize); SelectObject (hdcMem,hDrawBmp); TextOut(hdcMem, 0, 0 , L"プリンタのBMP領域の大きさは何処で分りますか?", 100); BitBlt(hdc, 0, 0,Xsize, Ysize, hdcMem, 0, 0, SRCCOPY); EndPage(hdc);

  • スクリーンキャプチャしてBMP保存する方法を教えてください

    ダイアログでボタンを押すとスクリーンキャプチャしてBMPファイルとして保存したいのですが、うまく動作しません。 どこがまずいのでしょうか?教えていただけると、嬉しいです。 void Test::OnScreenSave() { HDC hScreenDC; HDC hMemDC; HBITMAP hMemBmp; int scrx, scry; int xsize,ysize; RECT rect; HBITMAP hOld; GetWindowRect(&rect); scrx = GetSystemMetrics(SM_CXSCREEN); scry = GetSystemMetrics(SM_CYSCREEN); hScreenDC = CreateDC("DISPLAY", NULL, NULL, NULL); xsize = rect.right -rect.left; ysize = rect.bottom - rect.top; hMemDC = CreateCompatibleDC(hScreenDC); hMemBmp = CreateCompatibleBitmap(hScreenDC, xsize, ysize); hOld = (HBITMAP)SelectObject(hMemDC, hMemBmp); BitBlt(hMemDC, 0, 0, xsize, ysize, hScreenDC, rect.left, rect.top, SRCCOPY); int nWid3 = (xsize * 3 + 3) & 0xfffffffc; int nBmp = nWid3 * ysize; BYTE *p = new BYTE[nBmp + 54]; SelectObject(hMemDC, hOld); // hMemBmpを非選択とする int lines = GetDIBits(hMemDC, hMemBmp, 0, ysize, (LPBYTE)(p + 54), (LPBITMAPINFO)(p + 14), DIB_RGB_COLORS); // lines -> 0 となり、何もコピーされない。 if(OpenClipboard() != 0){ EmptyClipboard(); SetClipboardData(CF_BITMAP, hMemBmp); // この処理は正常に実行されている CloseClipboard(); } DeleteDC(hMemDC); DeleteDC(hScreenDC); delete [] p; }

  • 印刷範囲を規定するAPI?

    以下のような機能を持つAPIがあると耳にしたことがあります 色々と調べましたが見付けられません もしご存じであればお教え願います 探しているAPIの名前を仮に APIxxx とします BOOL APIxxx(hdc, int Xpoint, int Ypoint); hdc はプリンターのディバイスコンテキスト Xpoint、Ypoint は (0, 0)を原点とするプリンタ印刷領域の座標です まず印刷領域に textout(hdc,~) Rectangle(hdc,~) などのAPIを使用して印刷イメージを組立てます この後、今の主題である APIxxxを発すると (0, 0)~(Xpoint, Ypoint)の四角形以外の印刷データは無視され、Endpage APIを出して印刷開始しても実際に印刷されるのは(0, 0)~(Xpoint, Ypoint)の四角形範囲だけとなる 四角形以外の残りの部分は白紙状態で印刷されます このような機能を持つAPIxxxを探しています うろ覚えであるので説明に誤りがある可能性が相当あります 類似のAPIでも結構です 似たような機能のAPIをご存知でしたら教えてください 補足】この APIxxxは Excelの印刷範囲を指定操作 印刷するセルを選択 ⇒ ページレイアウト ⇒ 印刷範囲 ⇒ 印刷範囲の設定 で印刷セルの範囲を指定する時にも使用されているとも聞いたことがあるような気がします

  • UNICODE指定のプロジェクトで関数Wの呼出し?

    .NET VC++で簡単な印刷プログラムを作りました hdc = CreateDC(TEXT("EPMJ3"), TEXT("Canon MP280 series Printer"), NULL, NULL);・・・(1) StartDoc(hdc, &docinfo);                           ・・・(2) StartPage(hdc); TextOut (hdc, 10, 200,L"テスト印刷の1行目です。", 12);           ・・・(3) TextOutW(hdc, 10, 100,L"テスト印刷の2行目です。", 12);           ・・・(4)  EndPage(hdc); EndDoc(hdc); DeleteDC(hdc); プロジェクトの文字コードはUNICODEを指定しております (1)はCreateDocW関数 (2)はStartDocW関数が呼ばれます (3)は当然TextOutW関数になるだろうと思っていたら、TextOutA関数が呼ばれいます 試しに(4)のように直接TextOutW関数を指定してみたら、これも結果に於いてTextOutA関数が呼ばれています    【以上の事柄はAPIフックを仕掛けて調べました】 なぜ私のコンパイラはUNICODE用のTextOut関数を呼出してくれないのですか????

  • win32プログラム

    以下のコードで 1、CreateSolidBrush()で色設定しつつ 2、SelectObject()で、前のブラシのハンドルを受け取り 3、DeleteObject()で前の色を削除。     これらを一つの文で行っているんですか?  これらの記述は、一般的な方法ですか?  ブラシ(CreateSolidBrush()など)特に削除しなくても、  プログラム 出来る気がしますが、  削除しないと何か問題はありますか?  教えてください。 SelectObject ( hdc,CreateSolidBrush( RGB( 255,0,255))); Polygon(hdc,a,6); DeleteObject( SelectObject( hdc, CreateSolidBrush(RGB(55,77,33)))); PolyPolygon(hdc,b,d,2); DeleteObject( SelectObject(hdc, GetStockObject(WHITE_BRUSH)));

  • スクリーンキャプチャしてBMPファイルに保存する方法を教えて下さい

    スクリーンキャプチャしてBMPファイルに保存する方法を教えて下さい. ダイアログでボタンを押したらスクリーンキャプチャして、それをBMPファイルで保存したいのですがうまく動作しません。 ダイアログ画面のサイズは、横 659 画素、縦 486 行です。 GetDIBits()で162行まではコピー出来るのですが、それ以上ではエラーを起こします。 クリップボードに貼り付ける処理は正常に動作しています。 どこがまずいのかを教えていただけたら嬉しいです。 よろしくお願い致します。 void Test::OnScreenSave() { HDC hScreenDC; HDC hMemDC; HBITMAP hMemBmp; int scrx, scry; int xsize,ysize; RECT rect; HBITMAP hOld; GetWindowRect(&rect); scrx = GetSystemMetrics(SM_CXSCREEN); scry = GetSystemMetrics(SM_CYSCREEN); hScreenDC = CreateDC("DISPLAY", NULL, NULL, NULL); xsize = rect.right -rect.left; ysize = rect.bottom - rect.top; hMemDC = CreateCompatibleDC(hScreenDC); hMemBmp = CreateCompatibleBitmap(hScreenDC, xsize, ysize); hOld = (HBITMAP)SelectObject(hMemDC, hMemBmp); BitBlt(hMemDC, 0, 0, xsize, ysize, hScreenDC, rect.left, rect.top, SRCCOPY); int nWid = (xsize * 3 + 3) & 0xfffffffc; int nBmp = nWid * ysize; LPBYTE p = new BYTE[nBmp + 54]; LPBYTE pImg = (LPBYTE)(p + 54); LPBITMAPINFO pInfo = (LPBITMAPINFO)(p + 14); pInfo->bmiHeader.biSize=sizeof(BITMAPINFOHEADER); pInfo->bmiHeader.biWidth=nWid; pInfo->bmiHeader.biHeight=ysize; pInfo->bmiHeader.biPlanes=1; pInfo->bmiHeader.biBitCount=24; pInfo->bmiHeader.biCompression=BI_RGB; // 非圧縮フォーマット BI_RGB = 0 SelectObject(hMemDC, hOld); // hMemBmpを非選択とする int lines = GetDIBits(hMemDC, hMemBmp, 0, 162, pImg, pInfo, DIB_RGB_COLORS); // 162ラインまではコピー出来るが、それ以上ではエラーとなる。 if(OpenClipboard() != 0){ EmptyClipboard(); SetClipboardData(CF_BITMAP, hMemBmp); // この処理は正常に実行されている CloseClipboard(); } DeleteDC(hMemDC); DeleteDC(hScreenDC); delete [] p; }

  • 出来上がった印刷イメージをボカす方法???

    .NETのC++を使用して印刷プログラムを組んでいます 定石通りに CreateDC StartDoc StartPage ・ ・ (1) ・ ・ EndPage  (2) EndDoc DeleteDC としております StartPageからEndPageの間の(1)の部分でベタベタと文字やイメージを書込んでいます 主題】 ⇒ 全てを書込んだ(2)の直前で作上げた印刷イメージ(文字、画像の全て)をハーフトーンにボカしたのです (1)の部分は複雑でもうこれ以上手を加えられません 各々のTextOut等のAPIの呼出し方法を修正せず、EndPageの直前で印刷イメージを一括してボカす方法があればご指導願います ??? 便利なAPIはありませんか ???

  • 検索系ソフトは如何にして検索結果画面を印刷するのか

    プリンタ出力APIの代表的なもの TextOut、ExtTextOut、DrawText、DrawTextEx のAPIフックをしました 一般のアプリはもちろん、Word、Execl、秀丸、メモ帳などは確実に印刷の最中にこれらのAPIをフックします ところがGoogle、Yahoo、Gooなどの検索結果画面を印刷しても、これらのTextOut、ExtTextOut、DrawText、DrawTextExのAPIをフックすることはありませんでした 検索系のソフトは一般のAPIを使用せず、何か特別の印刷APIを持っているのでしょうか? それともHTML文で表示した画面はAPI印刷しないのでしょうか? なにかヒントがありましたら教えてください、お願いします