• ベストアンサー

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

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

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

  • ベストアンサー
回答No.1

MSDNのStartPageの解説を見ると、デバイスコンテキストの種類が制限されているようには書かれていませんし、動作内容もEndPageが呼ばれるまでResetDCを無効にするというもので、プリンターに限らず使用できるように思えます。 試に、画面のデバイスコンテキストに対してStartPage/EndPageを使用してみて、使用しない場合と違いがあるのかを試してみればいいのでは? 違いがないのであれば、画面のデバイスコンテキストが渡される可能性も考えなければならないと思います。使い方はプログラマー次第ですから。 なお、HDCはデバイスコンテキスト「ハンドル」です。 ハンドラーというのは、例えばWM_PAINTメッセージが来た場合に、実際に描画する部分のルーチンなどをWM_PAINTのハンドラーなどと使います。 StartPage http://msdn.microsoft.com/ja-jp/library/cc428766.aspx

sato-may
質問者

お礼

ありがとうございます ご助言の通りディスプレイに対してテストしたことがあります ごく普通にStartPage/EndPageは正常終了しました でもこれは私の環境の特異現象である恐れがありましたので、質問させて頂いたのです 実際にテストした結果以外に結論はありませんでしょうか? 大変参考になりました ありがとうございました

関連するQ&A

  • 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フックも手修正も回避したいのです

  • GetPixelに使うHDCの作り方

    ビットマップハンドルhBitmap の(x,y)の画素の色を読み取るプログラムに使うデバイスコンテキストとして、  hDC = CreateCompatibleDC(NULL);  SelectObject(hDC, hBitmap);  rgb = GetPixel(hDC, x,y);  DeleteDC(hDC); のように、NULL を指定して、画面と互換性のあるメモリデバイスコンテキストを指定したのですが、正しい色が読み出せません。hDC = GetDC(NULL);でも同じく駄目でした。hDCはどのように作ったらよいのでしょう。 なお、関数の中でGetPixel()を使いたいので、hWnd などは使えません。

  • 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文書に黄色いカバーを掛けることで相当な時間を費やしてしまいました でも手掛かりが全くなく困っております どんなヒントでも結構です、ぜひ教えてください、お願い申し上げます

  • 印刷範囲を規定する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関数を呼出してくれないのですか????

  • プリンターであるか否かの判断?

    特殊な目的の為、文字列変数Deviceを受取りその内容がプリンターを示すものであれば、APIのCreatDCでプリンターのHDCを作成します そしてそのプリンターのHDCを使用してStartDoc、StartPage、Textout等の一連の印刷動作をしたいと思います それには先ず文字列変数Deviceの内容がプリンターを示しているか? を判別しなくてはなりません 色々調べましたら WINSPOOL である場合はプリンターです 内容が NULL(空白)であればプリンターと判断すべきらしいです また内容が "ディスプレイ" ならば当然除外します しかしこんな判定法で宜しいのでしょうか? 特に文字列変数Deviceの内容が、コントロールパネル⇒デバイスとプリンター によって表示される Canon MP280 series Printer などの具体的なプリンター名称であった場合不安です 文字列変数Deviceの内容がプリンターを示しているか否かを判定する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);

  • [Active Basic]BitBltで画像を表示

    ActiveBasicでプログラムを書いています。 少しずつデバイスコンテキストが使えるようになってきて、簡単なブロック崩しを作ってみようと思い、作り始めました。 以前、デバイスコンテキストを使えるようになろうと、上から物体が降ってきて、それを避けるというゲームを書いてみたのですが、画像(ビットマップ)の表示方法が分からず、すべて MainWnd_Paint(hDC As HDC) に中に書きました。 すると、処理ごとにいらないものまで描写されるので画面がかなりちらついてしまいました。 ActiveBasicのヘルプ(http://www.activebasic.com/help_center/articles/win32/step16/index.html)を参考にして、プログラムを書いてみたのですが、背景が描写されません。 コードを下に書きますので、すみませんが添削の方をお願いします。 まだ、プログラムを始めたばかりのほやほやですので、なるべくやさしくお願いします。 '------------グローバル------------ Dim ImgBack As HBITMAP '背景画像 Dim hBackDC As HDC '背景画像用デバイスコンテキスト Dim hMemDC As HDC 'BitBlt用のデバイスコンテキスト '------------グローバル------------ Sub MainWnd_Create(ByRef CreateStruct As CREATESTRUCT) Dim hDC As HDC 'イメージを読み込んでいく ImgBack = LoadImage(0,".\pic\back.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE) 'デバイスコンテキストをそれぞれ作成 hDC = GetDC(hMainWnd) hBackDC = CreateCompatibleDC(hDC)'背景用DC hMemDC = CreateCompatibleDC(hDC)'BitBlt用DC '背景を描写 SelectObject(hBackDC,ImgBack) BitBlt(hMemDC,0,0,640,480,hBackDC,0,0,SRCCOPY) '最後にhDCだけ開放 ReleaseDC(hMainWnd,hDC) End Sub Sub MainWnd_Paint(hDC As HDC) End Sub 後、BitBltを MainWnd_Paint(hDC As HDC) の中に表記すると、画像が表示されます。 何故か、いまいち分かっていません・・・ すみませんが、ご教授ください。

  • c言語を使いダイアログにbmpを表示したい 

    はじめまして、 私は、c言語は初心者なのでが、ダイアログボックスに、画像(bmp)が表示することができません。 ソースは、 hdc = BeginPaint(hDlg, &ps); //指定ウィンドウ内での描写準備 // ビットマップをファイルからロードする hBitmap = ::LoadBitmap( NULL, _T("test.bmp") ); // ウィンドウのデバイスコンテキストハンドルを取得する hDC = GetDC( hDlg ); // メモリデバイスコンテキストを作成する hCompatDC = CreateCompatibleDC( hDC ); // ロードしたビットマップを選択する GetObject(hBitmap, sizeof(BITMAP), &bmp); // ビットマップをウィンドウに転送する(表示する) if(hBitmap != NULL){ StretchBlt( hDC, 0, 0, 100, 100, hCompatDC, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY ); SendDlgItemMessage( hDlg, IDC_STATIC, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBitmap); } なのですが、これはメインウィンドウでは動くのですが、ダイアログボックスでは動かずこまっています。 どうか、助言のほどよろしくお願いします。

  • GDI+について

    いつもお世話になっております。 今回教えていただきたいことは、GDI+についてです。 今まで GDI と OpenGL を組み合わせてプログラミングをしていましたが、GDIでは自前でアンチエリアス処理をしなければならないなど面倒な部分が多く困っていました。 そこで GDI+ を使用して楽にプログラミングしようと考えて色々とプログラムをしてみたのですが、ここにきて壁にぶち当たりましたので、先人の方にご教授していただきたいのです。 《 GDI でプログラムしていた時 》 (1)画像バッファを作成しておく  //ディスクトップのDCを取得  HDC hdcTmp = GetDC( GetDesktopWindow() );  //ビットマップのハンドルと、作成したバッファの先頭アドレスを取得  hBitmap = CreateDIBSection( hdcTmp, &bmi, DIB_RGB_COLORS, (void**)&buffer, 0, 0 );  //HBITMAPにHDCを結び付ける  hdc = CreateCompatibleDC( hdcTmp );     //DIBSection用メモリデバイスコンテキスト作成  hOldHandle = SelectObject( hdc, hBitmap );       //画像バッファ(m_hBitmap)をメモリデバイスコンテキストに選択 (GDIでも描画出来るようにするため) (2)画像バッファ上にGDIで描画する  hdcに対してGDIの関数を使用して描画 (3)BitBlt()でウィンドウに転送する  WM_PAINTのメッセージのときだけウィンドウに対して転送 上記(1)(2)(3)のようにして描画を行っていました。 ■したいこと(1)■ 今したい事は 上記(1)で作成したGDI の画像バッファのhdcを使ってGDI+関数で描画したいのです。 そうするといままで使っていたGDIの知識を生かして両方使えます。 ■したいこと(2)■ したいこと(1)がもし出来ないのであればGDI+での画像バッファがつくれるかどうか、その画像バッファのデバイスコンテキスト は取得できるのかどうか教えていただきたいと思います 情報不足かもしれませんが、ご教授よろしくお願いいたします。

専門家に質問してみよう