• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:C++/CLIで印刷する画像が表示されない)

C++/CLIで印刷する画像が表示されない

このQ&Aのポイント
  • C++/CLIで指定した画像が印刷されない場合の解決方法を教えてください
  • 指定したbmpファイルをC++/CLIで印刷させるプログラムを作成していますが、画像が表示されません。どうすれば表示させることができるでしょうか?
  • C++/CLIのプログラムで指定した画像が印刷されない問題について、解決方法を教えてください

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

  • ベストアンサー
  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.3

作成中のアプリって WindowsForm/Console どのようなタイプですか? C++/CLIですと PrintDocumentのイベントで印刷の制御をしますが ・・・ PrintDocumentのBeginPrint/PrintPage/EndPaintなどを使います BeginPrintが印刷の初期設定 EndPrintが印刷の後始末 … 不要な場合もあります PrintPageが印刷処理の本体です 単純な線引きの MoveToEx/LineTo などを実行しても何も描画されませんか? MoveToEx( pd.hDC, 100, 100 ); LineTo( pd.hDC, 500, 800 ); といった具合で ・・・

funaltu
質問者

お礼

いろいろとありがとうございました。 以下のようにソースコードを書いてみたところ、 見事に印刷結果に画像が写りました。 以下ソースコード(タブを全角スペースにしています) bool printFile(char *filename) {  PRINTDLG pd;  DOCINFO di;  HWND hWnd;  HDC hBuffer;  //プリンタの設定  memset(&pd, 0, sizeof(PRINTDLG));  pd.lStructSize = sizeof(PRINTDLG);  pd.hwndOwner = NULL;  pd.hDevMode = NULL;  pd.hDevNames = NULL;  pd.Flags = PD_USEDEVMODECOPIESANDCOLLATE | PD_RETURNDC |   PD_NOPAGENUMS | PD_NOSELECTION | PD_HIDEPRINTTOFILE|   PD_RETURNDEFAULT;  pd.nCopies = 1;  pd.nFromPage = 1;  pd.nToPage = 1;  pd.nMinPage = 1;  pd.nMaxPage = 1;  memset(&di, 0, sizeof(DOCINFO));  di.cbSize = sizeof(DOCINFO);  di.lpszDocName = filename;    //印刷を実行  if (PrintDlg(&pd)==TRUE)  {   StartDoc(pd.hDC, &di);   StartPage(pd.hDC);   //描画を実行   long int lnWidth = 500000;   long int lnHeight = 700000;   HDC hMemDC = CreateCompatibleDC(pd.hDC);   HANDLE hBitmap = LoadImage( NULL, filename, IMAGE_BITMAP,    0, 0, LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE );   HGDIOBJ Obj = SelectObject(hMemDC,hBitmap);   int iRet = GetDeviceCaps(hMemDC,RASTERCAPS);   // コピー   iRet = BitBlt(pd.hDC,0,0,lnWidth,lnHeight,hMemDC,0,0,SRCCOPY);      EndPage(pd.hDC);   EndDoc(pd.hDC);   DeleteDC(pd.hDC);   return true;  }  return false; }

funaltu
質問者

補足

たぶん、WindowsFormです。 Form1.hには以下のコード文が載っていましたので・・・。 public ref class Form1 : public System::Windows::Forms::Form あと単純な線引きのMoveToEx/LineTo を行っても何も描画できませんでした。 以下そのときのコード。 MoveToEx( pd.hDC, 100, 100 , NULL); LineTo( pd.hDC, 500, 800 ); あきらめて、PrintDocumentの処理を入れて確かめて見ます。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (4)

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.5

デフォルトのペンは太さ1の黒が選択される場合が多いと思いますよ // 生成 HPEN hPen = CreatePen( PS_SOLID, 1, RGB( 0, 0, 0 ) ); // 選択 HPEN hOldPen = SelectObject( pd.hDC, hPen ); // 描画処理 // 後始末 SelectObject( pd.hDC, hOldPen ); DeleteObject( hPen ); といった具合です ・・・

funaltu
質問者

お礼

ありがとうございます。表示され、線が印刷されました。 後はビットマップの描画だけクリアできれば完了です。 以下そのときのソースコード。 bool printFile(char *filename) { PRINTDLG pd; DOCINFO di; HWND hWnd; HDC hBuffer; //プリンタの設定 memset(&pd, 0, sizeof(PRINTDLG)); pd.lStructSize = sizeof(PRINTDLG); pd.hwndOwner = NULL; pd.hDevMode = NULL; pd.hDevNames = NULL; pd.Flags = PD_USEDEVMODECOPIESANDCOLLATE | PD_RETURNDC | PD_NOPAGENUMS | PD_NOSELECTION | PD_HIDEPRINTTOFILE| PD_RETURNDEFAULT; pd.nCopies = 1; pd.nFromPage = 1; pd.nToPage = 1; pd.nMinPage = 1; pd.nMaxPage = 1; memset(&di, 0, sizeof(DOCINFO)); di.cbSize = sizeof(DOCINFO); di.lpszDocName = filename; //印刷を実行 if (PrintDlg(&pd)==TRUE) { StartDoc(pd.hDC, &di); StartPage(pd.hDC); //描画を実行 // ペンの生成 HGDIOBJ hPen = CreatePen( PS_SOLID, 1, RGB( 0, 0, 0 ) ); // ペンの選択 HGDIOBJ hOldPen = SelectObject( pd.hDC, hPen ); // 描画処理 int lnWidth = 20000; int lnHeight = 50000; for ( int x = 0; x < 2000; x+= 100 ) { ::MoveToEx( pd.hDC, 100, 100 , NULL); ::LineTo( pd.hDC, x, 1000 ); } // 後始末 SelectObject( pd.hDC, hOldPen ); DeleteObject( hPen ); EndPage(pd.hDC); EndDoc(pd.hDC); DeleteDC(pd.hDC); return true; } return false; }

全文を見る
すると、全ての回答が全文表示されます。
  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.4

OfficeXPや2003などが入っているなら 『Office Document Image Writer』や『XPS Document Writer』といったプリンターが追加されていると思います これを デフォルトのプリンターにして実行してみてはいかがでしょう 線1本では出力されたどうかがわからないのであれば for ( int x = 0; x < 2000; x+= 100 ) {   ::MoveToEx( 100, 100, NULL );   ::LineTo( x, 1000 ); } といった具合で出力してみるとか ・・・ pd.hDCは NULLではないのですよね

funaltu
質問者

お礼

未だに、印刷は白紙のままです。 pd.hDCはNULLではなくきちんとした値でした。 話によると、デフォルトのペンの色や太さを指定する関数があるようですが、 それが原因かと探っているところです。

全文を見る
すると、全ての回答が全文表示されます。
  • ohtawa
  • ベストアンサー率23% (9/38)
回答No.2

C++/CLIだったらもっと高度な簡単な方法があるのでは? たとえば立ち上げ時読み込みを例にとると public: Form1(void) {     InitializeComponent();     ------------------- -------------------     this->bitmap = dynamic_cast<System::Drawing::Bitmap^>(gcnew System::Drawing::Bitmap("tokyo.bmp")); } という風に 印刷などもだいぶ楽にできたと記憶しているが

funaltu
質問者

お礼

ありがとうございます。この方法を早速試してみたのですが、エラーが出てしまいました。 一応、エラーを消そうとしたのですが、画像が印刷されない所か、印刷さえもしませんでした。 理解が足りなくてすみません。

全文を見る
すると、全ての回答が全文表示されます。
  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.1

BitBltの方向が逆ですよ pd.hDCが転送先(ディストネーション側) hMemDCに表示したいBitmapを選択しておいて 転送という方向になるかと ・・・ ご質問の状態では プリンター側のHDCから hMemDCへ転送になります また DOCINFOの lpszDocNameは 印刷ドキュメントの名前であって 印刷したい画像ファイルなどの名前を登録するものではないと思います LoadImageでファイルを読み込むか CLI側でBitmapオブジェクトにイメージを取り込んでprintFileに対して ハンドルを渡してやるか でしょう LoadImageならば HBITMAP hBitmap = LoadImage( NULL, filename, IMAGE_BITMAP,   0, 0, LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE ); // LR_CREATEDIBSECTIONが無いとうまくいかない場合がありました といった具合 ハンドルを渡すのであれば void printFile( IntPtr hImage ) としておいて HBITMAP hBitmap = (HBITMAP)hImage.ToPointer(); 呼び出し側では Bitmap^ oBmp = gcnew Bitmap( "ファイルパス" ); printFile( oBmp->GetHbitmap() ); といった具合です ・・・ 画面とプリンターでは解像度が違うので そのままBitBltするととても小さなイメージになりますよ

funaltu
質問者

お礼

一応、途中のコードをご指摘のとおりに直したところ、 返し値が正常に返ってきましたが、未だに画像が印刷されません。 どうしたらよいのでしょうか? 以下、修正したコードです。 //描画を実行 int lnWidth = 20000; int lnHeight = 50000; HDC hMemDC = CreateCompatibleDC(pd.hDC); HBITMAP hBitmap = (HBITMAP)LoadImage( NULL, filename, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE ); HBITMAP Obj = (HBITMAP)SelectObject(hMemDC,hBitmap); int iRet = GetDeviceCaps(hMemDC,RASTERCAPS); // コピー iRet = BitBlt(pd.hDC,0,0,lnWidth,lnHeight,hMemDC,0,0,SRCCOPY);

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • プログラムを実行して不具合の出たプリンタを直したい

    よろしくお願いします。 『印刷をするプログラム』を書いて実行した結果、 PCからのスキャン、プリンタ本体での、スキャン、コピーが出来なくなりました。 チェックディスク、システムの復元、ドライバーの入れ替え、などをしたのですが直りません。 多分、自作プログラムの実行により『プリンタ』か、『PC』のプログラムに、なんらかの異常が出たと思うのですが、プログラムを直せば良いのか、リカバリするのか、修復する方法が見つかりません。 詳しい方、アドバイスをよろしくお願いします。 自作のメモ帳にコーディングしたソースです。 //印刷関数 int MyPrint(HWND hWnd) { int i; PRINTDLG pd; DOCINFO di; TEXTMETRIC tm; char *lpszBuf = TEXT("ここが印刷される"); memset(&pd, 0, sizeof(PRINTDLG)); //PRINTDLG構造体の定義 pd.lStructSize = sizeof(PRINTDLG); pd.hwndOwner = hWnd; pd.hDevMode = NULL; pd.hDevNames = NULL; pd.Flags = PD_USEDEVMODECOPIESANDCOLLATE | PD_RETURNDC | PD_NOPAGENUMS | PD_NOSELECTION | PD_HIDEPRINTTOFILE; pd.nMinPage = 1; pd.nMaxPage = 1; pd.nFromPage = 1; pd.nToPage = 1; pd.nCopies = 1; if(PrintDlg(&pd) == 0) return -1; memset(&di, 0, sizeof(DOCINFO)); //DOCINFO構造体の定義 di.cbSize = sizeof(DOCINFO); di.lpszDocName = TEXT("テスト"); StartDoc(pd.hDC, &di); //印刷ジョブ StartPage(pd.hDC); GetTextMetrics(pd.hDC, &tm); for(i = 0; i < 5; i++){ //< 50印刷部数 SetTextColor(pd.hDC, RGB(0, 0, 0)); TextOut(pd.hDC, 5, 5 + (tm.tmHeight * i + 20), lpszBuf, (int)strlen(lpszBuf)); /*for(i = 0; i < 5; i++){ SetTextColor(pd.hDC, RGB(255, 0, 0)); TextOut(pd.hDC, 5, 5 + (tm.tmHeight * i + 20), lpszBuf, (int)strlen(lpszBuf));*/ } EndPage(pd.hDC); EndDoc(pd.hDC); DeleteDC(pd.hDC); return 0; }

  • WinAPIでの画像高速切り替え表示プログラム1

    WinAPIを使用して、ビットマップ画像を8枚読み込み、それを連続高速表示するプログラムを作成しています。 今はSetTimerを使ってWM_TIMERを受け取ったときに画像をInvalidateRect(再描画)しています。 以下のソースで動作はするのですが、WM_TIMERは整数ミリ秒でしか設定できず、精度も悪く優先順位も遅いようなので他の方法を考えています。 画像8枚を6.25msecで切り替えて表示するというのをESCAPEするまで繰り返したいのですが...。 リフレッシュレートは160Hzにあげています。 QueryPerformanceFrequencyというものを使えばいいのかなと思っていますが、どこでどう使えばいいのか、それをどう受け取って再描画すればいいのかわかりません。 どなたかご教授お願いします。ソースファイルを書いていただけたら嬉しいです。 #include<windows.h> #define BMP_SUM8//画像の総数 #define TIMER_ID (100) // 作成するタイマの識別ID #define TIMER_ELAPSE (6) // WM_TIMERの発生間隔 LRESULT CALLBACK WindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam){ HDC hdc; PAINTSTRUCT ps; HBITMAP hBitmap; int i; const char *filename[BMP_SUM]={"gazou0.bmp", "gazou1.bmp", "gazou2.bmp", "gazou3.bmp", "gazou4.bmp", "gazou5.bmp", "gazou6.bmp", "gazou7.bmp"}; static HDC hMemDC[BMP_SUM]; static BITMAP bmp; static int bmp_index;//現在の画像番号 LONG lResult; switch(uMsg) { case WM_CREATE: hdc=GetDC(hWnd); for(i=0;i<BMP_SUM;i++){ hBitmap=(HBITMAP)LoadImage(0,filename[i],IMAGE_BITMAP,0,0,LR_LOADFROMFILE); hMemDC[i]=CreateCompatibleDC(hdc); SelectObject(hMemDC[i],hBitmap); } GetObject(hBitmap,sizeof(BITMAP),&bmp); DeleteObject(hBitmap); ReleaseDC(hWnd,hdc); return 0; case WM_TIMER: if( wParam != TIMER_ID ) { break; // 識別IDが一致しないタイマメッセージはDefWindowProc()に任せる } if(++bmp_index >= BMP_SUM) bmp_index=0; for(i = 0; i < BMP_SUM; i++){ InvalidateRect( hWnd, NULL, FALSE ); } return 0; case WM_DESTROY: for(i=0;i<BMP_SUM;i++) DeleteDC(hMemDC[i]); PostQuitMessage(0); return 0; case WM_PAINT: hdc=BeginPaint(hWnd,&ps); BitBlt(hdc,0,0,bmp.bmWidth,bmp.bmHeight,hMemDC[bmp_index],0,0,SRCCOPY); EndPaint(hWnd,&ps); return 0; case WM_KEYDOWN: switch((CHAR)wParam) { case VK_ESCAPE: for(i=0;i<BMP_SUM;i++) DeleteDC(hMemDC[i]); PostQuitMessage(0); //WM_QUITメッセージを出す return 0; } } return DefWindowProc(hWnd,uMsg,wParam,lParam); } 入りきらないので2つに分けます。 続きは「WinAPIでの画像高速切り替え表示プログラム2」を見てください。

  • BMPの保存

    プリントスクリーンをして、それをBMP形式で保存しようとしているのですが、保存後のファイルを開いてウィンドウを動かすと、それにつれ逐次、画像が更新されていきます。 この問題の原因がわかる方、助言をお願いします。 プログラムはC++で作成しています。 下にソースを載せています。 宜しくお願いします。 #include<windows.h> LRESULT CALLBACK WindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; static BITMAPINFO bmpInfo; static LPDWORD lpPixel; static HBITMAP hBitmap; static HDC hMemDC; HWND desktop; RECT rc; static int width,height; switch(uMsg) { case WM_CREATE: //スクリーンの情報を得る desktop=GetDesktopWindow(); GetWindowRect(desktop,&rc); width=rc.right; height=rc.bottom; //DIBの情報を設定する bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); bmpInfo.bmiHeader.biWidth=width; bmpInfo.bmiHeader.biHeight=height; bmpInfo.bmiHeader.biPlanes=1; bmpInfo.bmiHeader.biBitCount=32; bmpInfo.bmiHeader.biCompression=BI_RGB; //DIBSection作成 hdc=GetDC(hWnd); hBitmap=CreateDIBSection(hdc,&bmpInfo,DIB_RGB_COLORS,(void**)&lpPixel,NULL,0); hMemDC=CreateCompatibleDC(hdc); SelectObject(hMemDC,hBitmap); ReleaseDC(hWnd,hdc); //スクリーンをDIBSectionにコピー hdc=GetDC(desktop); BitBlt(hMemDC,0,0,width,height,hdc,0,0,SRCCOPY); ReleaseDC(desktop,hdc); return 0; case WM_DESTROY: //自らlpPixelを解放するべからず DeleteDC(hMemDC); DeleteObject(hBitmap); //BMPを削除した時、lpPixelも自動的に解放される PostQuitMessage(0); return 0; case WM_PAINT: hdc=BeginPaint(hWnd,&ps); //表画面へ転送 BitBlt(hdc,0,0,width,height,hMemDC,0,0,SRCCOPY); EndPaint(hWnd,&ps); return 0; } SaveBitmap((HWND)hWnd,"PrintScreen.BMP"); return DefWindowProc(hWnd,uMsg,wParam,lParam); } int WINAPI WinMain( HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR lpCmdLine,int nCmdShow) { WNDCLASS wc; MSG msg; wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WindowProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL,IDI_APPLICATION); wc.hCursor = LoadCursor(NULL,IDC_ARROW); wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = __FILE__; if(!RegisterClass(&wc)) return 0; HWND hWnd=CreateWindow( __FILE__,"スクリーンキャプチャ", WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT,CW_USEDEFAULT, CW_USEDEFAULT,CW_USEDEFAULT, NULL,NULL,hInstance,NULL); if(hWnd==NULL) return 0; BOOL bRet; while((bRet=GetMessage(&msg,NULL,0,0))!=0){ if(bRet==-1) break; DispatchMessage(&msg); } return (int)msg.wParam; }

  • PrintScreenしたあとに画像を保存する方法

    LRESULT CALLBACK WndProcScreenCapture(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { // MMTIME mm; // CommonClass Common; static int id,x,y; HDC hdc; PAINTSTRUCT ps; static HBRUSH hBrush; HWND desktop; RECT rc; static int width,height; static BITMAPINFO bmpInfo; static LPDWORD lpPixel; static HBITMAP hBitmap; static HDC hMemDC; FILE *fpt; int i,j; //clock_t start,end; switch (message) { case WM_CREATE: desktop=GetDesktopWindow();//デスクトップのハンドルを取得 GetWindowRect(desktop,&rc);//デスクトップのRECT情報を取得 width=rc.right; height=rc.bottom; //DIBの情報を設定する bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); bmpInfo.bmiHeader.biWidth=width; bmpInfo.bmiHeader.biHeight=height; bmpInfo.bmiHeader.biPlanes=1; bmpInfo.bmiHeader.biBitCount=32; bmpInfo.bmiHeader.biCompression=BI_RGB; //DIBSection作成 hdc=GetDC(hWnd); hBitmap=CreateDIBSection(hdc,&bmpInfo,DIB_RGB_COLORS,(void**)&lpPixel,NULL,0); hMemDC=CreateCompatibleDC(hdc); SelectObject(hMemDC,hBitmap); ReleaseDC(hWnd,hdc); fopen_s(&fpt,"20090715.raw","wb"); fwrite((void**)&lpPixel[0],sizeof(unsigned char),width*height,fpt); /* DIBSectionにグラデーション描画 */ for (i = 0;i < height;i++) { for (j = 0;j <width;j++) { #if 0 /* DIBピクセル列に直接アクセス */ lpPixel[i + j * 256] = (i << 16); lpPixel[i + (j + 32) * 256] = (i << 8); lpPixel[i + (j + 64) * 256] = i; lpPixel[i + (j + 96) * 256] = (i << 16) | (i << 8) | i; /* GDI経由で描画 */ SetPixel(hMemDC, i, j + 128, RGB(i, 0, 0)); SetPixel(hMemDC, i, j + 128 + 32, RGB(0, i, 0)); SetPixel(hMemDC, i, j + 128 + 64, RGB(0, 0, i)); SetPixel(hMemDC, i, j + 128 + 96, RGB(i, i, i)); #endif } } //fwrite(&(bmpInfo.bmiHeader),sizeof(unsigned char),40,fpt); //fwrite((void**)&lpPixel,sizeof(unsigned char),width*height,fpt); //fwrite(&(bmpInfo.bmiColors),sizeof(unsigned char),width*height,fpt); fclose(fpt); //スクリーンをDIBSectionにコピー hdc=GetDC(desktop); BitBlt(hMemDC,0,0,width,height,hdc,0,0,SRCCOPY); ReleaseDC(desktop,hdc); break; case WM_DESTROY: //自らlpPixelを解放するべからず DeleteDC(hMemDC); DeleteObject(hBitmap); //BMPを削除した時、lpPixelも自動的に解放される PostQuitMessage(0); break; case WM_PAINT: hdc=BeginPaint(hWnd,&ps); BitBlt(hdc,0,0,width,height,hMemDC,0,0,SRCCOPY); EndPaint(hWnd,&ps); break; case WM_CHAR: の様に書いて、windowにキャプチャ画像を表示することは できたのですが、 この画像の画像情報のピクセルのポインタはどれなのでしょうか? 画像をraw形式でもいいので保存したいのですが、 どうしたら、キャプチャした画像を ファイルとして保存 できますか? //fwrite((void**)&lpPixel,sizeof(unsigned char),width*height,fpt); ではうまくいきませんでした。

  • windowsAPI 画像の表示

    画像が表示できません。   表示は   LoadBitmap() と BitBlt() だと思うんですけど。。。   何回やってもできません。   LRESULT CALLBACK WindowProc ( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { HMENU hMenu, hSubMenu; MENUITEMINFO mii; HDC hdc,hBuffer; RECT rect; TEXTMETRIC tm; PTSTR pstr; PAINTSTRUCT ps; static HFONT hFont; static HDC hMemDC; static HBITMAP hBitmap,hPrevBitmap; static BITMAP bitmap; switch(uMsg) { case WM_DESTROY: PostQuitMessage(0); return 0; case WM_CLOSE: if(MessageBox(hWnd,TEXT("ゲームを終了しますか?"),TEXT("アスパラインフォメーション"),MB_YESNO | MB_ICONINFORMATION) == IDYES){ DestroyWindow(hWnd); } return 0; case WM_COMMAND: //有効なメニューが選択され、メニューの選択が終了した switch(LOWORD(wParam)) { case IDM_NEW: pstr = TEXT("新しくゲームを始めますか?"); if(MessageBox(hWnd , pstr , TEXT("アスパラインフォメーション") , MB_YESNO | MB_ICONINFORMATION) == IDYES){ gamesystem = 1; InvalidateRect(hWnd,NULL,TRUE); } break; case IDM_OPEN: pstr = TEXT("ゲームをロードしますか?"); if(MessageBox(hWnd , pstr , TEXT("アスパラインフォメーション") , MB_YESNO | MB_ICONINFORMATION) == IDYES){ } break; case IDM_CLOSE: pstr = TEXT("ゲームを終了しますか?"); if(MessageBox(hWnd , pstr , TEXT("アスパラインフォメーション") , MB_YESNO | MB_ICONINFORMATION) == IDYES){ DestroyWindow(hWnd); } break; default: return 0; } return 0; case WM_MENUSELECT: //メニュー項目が選択された switch (LOWORD(wParam)) { case IDM_NEW: pstr = TEXT("新しくゲームを開始します"); break; case IDM_OPEN: pstr = TEXT("ゲームをロードします"); break; case IDM_CLOSE: pstr = TEXT("ゲームを終了します"); break; default: pstr = TEXT("ポップアップメニューが選択されています"); break; } hdc = GetDC(hWnd); GetClientRect(hWnd , &rect); GetTextMetrics(hdc , &tm); Rectangle(hdc , 0 , rect.bottom - tm.tmHeight * 2, rect.right , rect.bottom); TextOut(hdc , 5 , rect.bottom - tm.tmHeight * 1.5 , pstr , lstrlen(pstr)); ReleaseDC(hWnd , hdc); return 0; case WM_CREATE: mii.cbSize = sizeof(MENUITEMINFO); mii.fMask = MIIM_TYPE | MIIM_ID; mii.fType = MFT_STRING; hMenu = CreateMenu(); hSubMenu = CreatePopupMenu(); mii.dwTypeData = TEXT("ニューゲーム(&N)"); mii.wID = IDM_NEW; InsertMenuItem(hSubMenu , 0 , TRUE , &mii); mii.dwTypeData = TEXT("ロード(&O)"); mii.wID = IDM_OPEN; InsertMenuItem(hSubMenu , 1 , TRUE , &mii); mii.dwTypeData = TEXT("終了(&X)"); mii.wID = IDM_CLOSE; InsertMenuItem(hSubMenu , 2 , TRUE , &mii); mii.fMask = MIIM_TYPE | MIIM_SUBMENU; mii.hSubMenu = hSubMenu; mii.dwTypeData = TEXT("ファイル(&F)"); InsertMenuItem(hMenu , 0 , TRUE , &mii); SetMenu(hWnd , hMenu); hFont = CreateFont( 40,0,0,0,750, FALSE,FALSE,FALSE, SHIFTJIS_CHARSET,OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, VARIABLE_PITCH | FF_ROMAN,NULL); hBitmap = LoadBitmap( ((LPCREATESTRUCT)lParam)->hInstance , TEXT("KYARA") ); return 0; case WM_KEYDOWN: InvalidateRect(hWnd,NULL,FALSE); gamesystem += 1; return 0; case WM_PAINT: hdc = BeginPaint(hWnd,&ps); hBuffer = CreateCompatibleDC(hdc); SelectObject(hBuffer , hBitmap); BitBlt(hdc , 100 , 100 , 34 , 32 , hBuffer , 70 , 80 , SRCCOPY); DeleteDC(hBuffer); if(gamesystem == 1){ ・・・・・・・・・・・・・・・・・   といった感じです。   間違えがあれば、ご指摘お願いします。   また、わかりやすいサンプルコードを載せていただけたら嬉しいです。

  • BitBltについて。

    どなたか経験のある方、わかる方居られましたら教えてください。 プリンタのデバイスコンテキストからメモリDCに描画してビットマップを作成したいと思っているのですが、プリンタDCからメモリDCへのBitBltがうまくいっていないのか、完成イメージが真っ黒になります。 hMemDC = CreateCompatibleDC(hPrinterDC); hBitmap = CreateCompatibleBitmap(hPrinterDC,lnWidth,lnHeight); Obj = (HBITMAP)SelectObject(hMemDC,hBitmap); iRet = GetDeviceCaps(hMemDC,RASTERCAPS); // iRet の戻り値は 28313(10進)でした。 // コピー iRet = BitBlt(hMemDC,0,0,lnWidth,lnHeight,hPrinterDC,0,0,SRCCOPY); // iRet の戻り値は 1 になってました。 本来は lnHeight の値が BitBlt の戻り値になるのかと思いますがうまくいきません。 hPrinterDC はもともと印刷用の関数で使用しているものなので、そこには問題が無いのではないかと自分では思っていますが、わかる方居られましたら教えていただけませんでしょうか?

  • デバイスコンテキストの宣言に関するエラー?について

    Run-Time Check Failure #3 - The variable 'hMemDC' is being used without being defined. というエラーが出ます。 自分としては、WM_CREATEの処理で、初期化を行っているつもりなのですが・・・ 力を貸して頂ければ有難いです。よろしくお願いします。 ちなみに、関係のありそうな部分だけ掲載しています。 この部分だけ残して、他の部分をコメントアウトしてコンパイルしても、同じエラーメッセージが出ました。 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; RECT rect; HDC hDC; PAINTSTRUCT ps; HDC hMemDC; HBITMAP hMemBmp; HDC hMjDC; HBITMAP hMjBmp; BITMAP MjBmp; /* POINT posMJ; int MJshot; POINT posMJshot;*/ switch (message) { case WM_CREATE: GetClientRect(hWnd, &rect); // クライアント領域の大きさをrectに格納 hDC = GetDC(hWnd); hMemDC = CreateCompatibleDC(hDC); // hDCと互換性をとるメモリデバイスコンテキストhMemDCを構築 hMemBmp = CreateCompatibleBitmap(hMemDC, rect.right, rect.bottom); hMjDC = CreateCompatibleDC(hMemDC); // hMemDCと互換性をとるメモリデバイスコンテキストhMjDCを構築 hMjBmp = (HBITMAP)LoadImage( // ビットマップイメージMYJET(リソース)をhMjBmpに設定 (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE), MAKEINTRESOURCE(IDB_MYJET), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR ); SetTimer(hWnd, 1, 10, NULL); // 100分の1秒毎にWM_TIMERメッセージを送るタイマー1をセット break; case WM_PAINT: hDC = BeginPaint(hWnd, &ps); // hDCにディスプレイのデバイスコンテキストのハンドルを格納 BitBlt( // hDCにバックバッファhMemDCを転送 hDC, 0, 0, rect.right, rect.bottom, hMemDC, 0, 0, SRCCOPY ); EndPaint(hWnd, &ps); break;

  • プリンタ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);

  • WinAPIでスクリーン画像を映し続けるプログラムその2

    タイマー1秒ごとに画面を更新させたいのですが、リージョンの範囲しか更新されないため、ウインドウを最上層に置いておくと、画面がかわりません。下記ソースはそれを確かめるため、タイマーで更新する画面を100×100pixlから1秒ごとに徐々に大きくしていったところ、やはりペイントが違う画面で覆った部分しかそのとおり更新されていませんでした。参考書だとこんな感じでできる気がするのですが、InvalidateRect( hwnd, NULL, TRUE );のところでウインドウ全体を更新しなければいけない範囲にするべきだと思うのですが、具体的な解決策がわかりません。 お力を貸していただけると助かります。 #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); void getScreenShot(HBITMAP hBmpShot, int iX, int iY, int iWidth, int iHeight) ; /*ビットマップハンドル*/ static HBITMAP _bmpShot = 0; int popo=100; int _iWidth=1024, _iHeight=400; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){ MSG msg; WNDCLASS wndclass; wndclass.style = CS_HREDRAW | CS_VREDRAW; /* ウインドウクラス設定 */ wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = "vcshot"; RegisterClass(&wndclass); /* メインウインドウ作成 */ HWND hwMain = CreateWindow("vcshot", "", WS_POPUP | WS_VISIBLE , 0,0, _iWidth, _iHeight, NULL, NULL, hInstance, NULL); ShowWindow(hwMain, iCmdShow); /* メッセージループ */ while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return (int)msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { switch (iMsg) { case WM_CREATE: { /*先に外側で作成してしまう方が得策かもしれない*/ HDC hDC = ::GetDC(0); _bmpShot = ::CreateCompatibleBitmap(hDC, _iWidth, _iHeight); ::ReleaseDC(0, hDC); /* スクリーンショット取得 */ getScreenShot(_bmpShot, 0, 0, _iWidth, _iHeight); SetTimer(hwnd , 1 , 1000 , NULL); return 0; } case WM_TIMER:{ popo=popo+20; getScreenShot(_bmpShot, 0, 0, popo, popo); InvalidateRect( hwnd, NULL, TRUE ); return 0;} case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hwnd, &ps); /* ビットマップが作成されていれば描画 */ if(_bmpShot != NULL) { BITMAP bmp; /*この関数でビットマップから、詳細を知る事が出来る*/ ::GetObject(_bmpShot, sizeof(BITMAP), &bmp); /*以下決まり文句*/ HDC _hdcShot = ::CreateCompatibleDC(0); ::SelectObject(_hdcShot, _bmpShot); BitBlt(hdc, 0, 0, _iWidth, _iHeight, _hdcShot, 0, 0, SRCCOPY); /*使い終えたら直に閉じる*/ ::DeleteDC(_hdcShot); } EndPaint(hwnd, &ps); return 0; } case WM_DESTROY : /* ビットマップが作成されていたら関連リソースを削除 */ if(_bmpShot != NULL) { /*SelectObject(_hdcShot, _bmpOld);*/ DeleteObject(_bmpShot); /*DeleteObject(_hdcShot);←よく見ると、デバイスコンテキストに対してDeleteObjectを使用しています。*/ } PostQuitMessage(0); return 0; } return DefWindowProc (hwnd, iMsg, wParam, lParam); } void getScreenShot(HBITMAP hBmpShot, int iX, int iY, int iWidth, int iHeight) { /* キャプチャサイズを保存 _iWidth = iWidth; _iHeight = iHeight; */ /* 画面のデバイスコンテキスト取得 */ HDC hdcScreen = GetDC(0); /* ビットマップ描画用デバイスコンテキスト作成 */ HDC _hdcShot = CreateCompatibleDC(hdcScreen); /* スクリーンショット保存用ビットマップ作成 */ /*_bmpShot = CreateCompatibleBitmap(hdcScreen, iWidth, iHeight);*/ /* デバイスコンテキストにビットマップを設定 */ /*_bmpOld = (HBITMAP)*/SelectObject(_hdcShot, hBmpShot); /* 画面上の領域をビットマップに描く */ BitBlt(_hdcShot, 0, 0, iWidth, iHeight, hdcScreen, 0, 0, SRCCOPY); /* 画面のデバイスコンテキスト解放 */ ReleaseDC(0, hdcScreen); /*使用したら直に閉じる*/ ::DeleteDC(_hdcShot); }

  • ビットマップ画像表示

    いつもお世話になっております。 VS2005でC++を用いてWindowsアプリケーションの作成をしています。 子ウィンドウにビットマップ画像(ファイル名:HELP.bmp)を 表示させようとプログラムを組んだのですが、 子ウィンドウを出してもビットマップ画像が表示されません。 以下のようなプログラムを追加しました。 --------------------------------- ///リソーススクリプト/////////////////////////////////  IDB_BITMAP1  BITMAP DISCARDABLE  "HELP.bmp" ///ヘッダースクリプト/////////////////////////////////  #define IDB_BITMAP1   3000 ///ソーススクリプト/////////////////////////////////// void ShowMyBMP(HWND hWnd, HDC hdc){   HDC hmdc;   HBITMAP hBitmap;   BITMAP bmp;   HINSTANCE hInst;   int BMP_W, BMP_H;   hInst = (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE);   hBitmap = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP1));  //インスタンスハンドル取得   GetObject(hBitmap, sizeof(BITMAP), &bmp);  //ビットマップの情報を得る   BMP_W = (int)bmp.bmWidth;  //画像の幅   BMP_H = (int)bmp.bmHeight;  //画像の高さ   hmdc = CreateCompatibleDC(hdc);  //メモリデバイスコンテキストハンドルを取得   SelectObject(hmdc, hBitmap);   BitBlt(hdc, 0, 0, BMP_W, BMP_H, hmdc, 0, 0, SRCCOPY);   StretchBlt(hdc, 0, BMP_H, BMP_W / 2, BMP_H / 2, hmdc, 0, 0, BMP_W, BMP_H, SRCCOPY);   DeleteDC(hmdc); //デバイスコンテキストハンドルを開放   DeleteObject(hBitmap);   return; } --------------------------------- ShowMyBMP関数は子ウィンドウを表示するときに実行されます。 全て載せられないので追加した部分のみプログラムを載せましたが、 この部分だけでも、プログラムの間違い等はありませんでしょうか。 ご教授お願いいたします。