Windows API ペンを作るタイミング

このQ&Aのポイント
  • ゲームプログラミングにおいて、Windows APIを使用してペンを作成するタイミングについて教えてください。
  • テキストのサンプルプログラムでは、WM_CREATEの中でペンを生成し、WM_PAINT内で使用していますが、自分のプログラムではPaint関数を使用しています。ペンを生成するのはどのタイミングが一般的であり、どのようにすれば良いのか教えてください。
  • また、描画処理を1つの関数にまとめるべきなのか、それともPaint関数内でペンを生成・削除するべきなのかも教えてください。
回答を見る
  • ベストアンサー

Windows API ペンを作るタイミング

ゲームのプログラミングをしています。 テキストのサンプルプログラムではペンやブラシをWM_CREATEの中で hPen[1] = CreatePen(PS_SOLID, 2, RGB(50,70,0));    :    : のような感じで生成して WM_PAINT内でSelectObject(hdc, hPen[i]); として使っているのですが 自分のプログラムはPaintという関数を使っています。 その場合Paint(~)にそれらの配列を渡す形で良いのでしょうか? 一応今はそれで動いてます。 ただ描画の処理は1つの関数にまとめると書いてあったので Paint内で生成&削除をした方がよいのかとも思いまして・・・ どっちが一般的なのか、どういう場合はどうすればいいのかっていうのが 経験がなくて全然わからないので教えて欲しいです。 一応落ち物ゲームやシューティングゲームを想定してます。

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

  • ベストアンサー
  • haniriito
  • ベストアンサー率57% (12/21)
回答No.1

こんにちは。なかなかコメントがつかないようなので・・・。 ご質問の件ですが、いまのWindowsでは基本的にどちらでも構いません。 Windows3.x時代は、ペンなどのGDIリソースが貴重なものだということでできるだけWM_PAINT内で生成して関数から出る前に削除することが推奨されていた時代もあったようですが、いまは異なるペンを数千~数万個の単位で作りっぱなしにするのでなければ、一旦作ったペンを削除せずに何度でも使ってもよいと思います。 特に、高速シューティング系のゲームなら毎回ペンを作る時間もそれなりに時間がかかるので(とはいっても最近の超高速マシンなら気にするほどでもないか・・・)、繰り返し使うペンは作りっぱなしで何度も使い回した方が(気持ちだけでも)高速化できるのではないでしょうか。

cern5100
質問者

お礼

すみません遅くなりました。 回答ありがとうございます。 どちらでもよいですか。ならとりあえずは今のままでやってみます。 いろいろ経験していく中で臨機応変にやり方を変えていけるようになればと思います。 ありがとうございました。

関連するQ&A

  • Rectangleで、リソースが解放されない

    只今 Borland C コンパイラ 5.5.1 においてプログラムを書いているのですが、(C言語) 仕様なのかどうなのか、ある処理でウィンドウのサイズを ぐりぐり動かしつづけるとリソースが減っていって フリーズしていしまいます。使用しているWindowsは98SEです。 そのプログラムは、ウィンドウプロシージャにおいて、 case WM_PAINT:  hdc = BeginPaint(hWnd,&ps);    hPen = CreatePen(PS_SOLID, 0, RGB(255,0,0));  hOldPen = (HPEN)SelectObject(hdc, hPen);  hBrush = CreateSolidBrush(RGB(0,255,0));  Rectangle(hdc, 10,10,100,100);  DeleteObject(hPen);  SelectObject(hdc, hOldPen);  DeleteObject(hBrush);  DeleteObject(hOldPen);    EndPaint(hWnd,&ps);  break; という風に、Rectangle関数で画面に四角形を描画しているのですが、どうも上記の処理を何度も行うことにより リソースが解放されずに大量に消費されてしまいます。 C言語においてはまだ少しわかるほどのレベルで、 殆どの関数の意味を今だに理解していなくプログラムの 文法になにかしらの間違いがあるかもしれませんが、 ご指摘いただければ幸いです。

  • 重なり z-index

    HWND hrs;//プロト hrs = CreateWindow( ... というのがあって  wsprintf(mojibuf,"色付けが実行された");  SetWindowText(hrs,cbuf);  hDC = BeginPaint(hWnd, &ps);  hPen = CreatePen(PS_SOLID, 1, RGB(0, 0, 255));//枠色  SelectObject(hDC, hPen);  hBrush = CreateSolidBrush(RGB(0, 255, 0));//中色  SelectObject(hDC, hBrush);  Rectangle(hDC, 10, 90, 150, 100);  DeleteObject(hBrush);  EndPaint(hWnd, &ps); これで、hWnd に文字と四角を表示しました。 表示位置を重なるようにしたら、ソースの後に書いた方の 四角が文字に隠れてしまいました。 四角を文字の上になるようにして、重なった部分の文字は 四角で消されるようにするにはどうしたらいいんですか?

  • 【WinAPI】 四角形の色を選択して描画

    環境:VisualStudio2005、WinXP 目的:閉じた図形の内部の色を指定の色で塗りつぶしたい 現在 // 四角形を描画(Polygonバージョン) int x1 = 0, y1 = 0, x2 = 100, y2 = 100; POINT p[ 4 ]; p[ 0 ].x = x1, p[ 0 ].y = y1; p[ 1 ].x = x2, p[ 1 ].y = y1; p[ 2 ].x = x2, p[ 2 ].y = y2; p[ 3 ].x = x1, p[ 3 ].y = y2; Polygon( hdc, p, 4 ); や // 四角形を描画(Rectangleバージョン) Rectangle( x1, y1, x2, y2 ); などで四角形を描画するプログラムを作っています。 そしてこれに色を指定したいのですが、枠の部分に関しては HPEN hPen = CreatePen( PS_SOLID, 1/*線の厚さ*/, RGB(255,0,0) ); SelectObject( hdc , hPen ); // この後に四角形を描画 を指定することで色が変わりました。 しかし四角形の内側の部分の色に関しての色の指定方法が分かりません。 SelectObject(hdc , GetStockObject( GRAY_BRUSH ) ); でGRAY_BRUSH、BLACK_BLUSHなど数種類の指定ができるというのを調べましたが、 これだと好きな色を指定できません。 閉じた図形の内部の色を好きな色で塗りつぶす方法は無いのでしょうか・・?

  • Windowsプログラミング 画面描画 ちらつき

    SetDIBitsToDevice関数を使って画面に描画をした後、LineTo関数やEllipse関数を使って その画面上に線や丸を表示させる処理をしているのですが、描画処理を一度にできていないためか ちらつきが発生してしまいます。 調べてみるとビットマップのマルチバッファリングなどが解決策にあるのですが、 私は一次元配列で画素値を格納していてビットマップに情報は保持していないため よく解決策で使われているBITBLTが使えない状態です。 裏画面に描画しておいて、最終的に描画は一度だけにするという考えは分かるんですが、 これをSetDIBitsToDevice関数を用いてちらつきが発生しないようにできるんでしょうか? プログラムとしては画像の上に線と円をひたすら描画していくようなイメージをしています。 アドバイスお願いします! case WM_PAINT: hDC=BeginPaint(hParent,&ps); SetDIBitsToDevice( ps.hdc, 0, 0,// コピー先x,y座標 pimg -> bih.biWidth,// DIBの幅 pimg -> bih.biHeight,// DIBの高さ 0, 0,// DIBの座標 0,// 走査線 pimg -> bih.biHeight,/ 走査線数 pimg -> lpBmpData, (BITMAPINFO *)&( pimg -> bih),// BITMAPINFOにキャスト DIB_RGB_COLORS ); for(int i=0; i<number-1; i++){ if(i==0){  hPen1 = CreatePen(PS_SOLID, 1, RGB(255,0,0));  electObject(hDC,hPen1);  MoveToEx(hDC,Xs,Ys,NULL);  Ellipse(hDC,Xs-2,Ys-2,Xs+2,Ys+2); }else{  LineTo(hDC,Xe,Ye);  Ellipse(hDC,Xs-2,Ys-2,Xs+2,Ys+2); } }

  • ダブルバッファの作り方

    画面に描画するBCC5.5 のCプログラムがあります。画面がちらつくので、ダブルバッファにしたいのですが、具体的に、どの関数を呼んで実装したらよいのかわかりません。WEB検索をしますと結構情報がヒットしますが、解決に至ってませんので、よろしくお願いします。 具体的にやったことは、現在動いているプログラムの case WM_PAINT:  hdc=BeginPaint(hWnd,&ps);  paint(hdc); // 自作の描画プログラム本体  ReleaseDC(hWnd,hdc);  EndPaint(hWnd,&ps);  break; の部分を、「画面サイズのビットマップイメージhBitmapをつくり、そこにpaint関数で描き込み、最終画面を一気に出力する」というつもりで以下のプログラムに書き換えたのですが、表示すらしなくなってしまいました。何が悪いのかお教えください。 case WM_PAINT:  GetClientRect(hWnd,&rt);   h = (int)rt.bottom;   w = (int)rt.right;  hBuffer = CreateCompatibleDC(NULL);  hBitmap = CreateCompatibleBitmap(hBuffer, w, h);  SelectObject(hBuffer, hBitmap);  paint(hBuffer);  hdc=BeginPaint(hWnd,&ps);   BitBlt(hdc, 0,0,w,h, hBuffer,0,0, SRCCOPY);  ReleaseDC(hWnd,hdc);  EndPaint(hWnd,&ps);  DeleteDC(hBuffer);  DeleteObject(hBitmap);  break;

  • SelectObjectについて

    SelectObject関数で例えば、 hbrush=SelectObject(hdc,CreatesolidBrush(RGB(0,0,0,)); Rectangle(hdc,0,0,100,100); SelectObject(hdc,hbrush); でやる場合、なぜ、SelectObject(hdc,hbrush);で前の色に戻るはずなのに 戻らないのでしょうか?この意味はあるのでしょうか? 環境はVC++2005です。

  • ファイルを開く。(API・C言語)

    case WM_RBUTTONUP: GetOpenFileName(&ofn); SetWindowText(hWnd , strFile); return 0; ↑のソースは、ウィンドウを右クリックした後、ファイル名をタイトルバーに表示させるものなのですが、この、strFileを、ウィンドウの画面上に表示させるのに、 SelectObject(hdc , hFont); SetBkColor(hdc , RGB(255 , 255 , 255)); TextOut(hdc , 40, 10, strFile, lstrlen(strFile)); で表示させてみようとしたところ、エラーが発生し、できませんでした。どうやるのでしょうか。ちなみに、strFileはstatic TCHAR型です。 また、ウィンドウから読み込んだテキストファイルを、ある文字列がどれだけあるか、などを数え、その後、その数を表示させたりもさせるプログラムを作っています。それで分からなかったのが、読み込んだファイルはTCHAR型ですよね。それをどうやってchar型に直すかです。 宜しくお願い致します。

  • フォントの指定 猫でもわかるwindowsプログラミングより

    猫でもわかるwindowsプログラミングの本で勉強している学生なんですが、第2章の2.4フォントの指定のところでプログラムを打ち込んでコンパイルしたのですがなぜか識別子が見つかりませんというエラーがでてコンパイルできません。どなたかわかる方お願いします。 一応プログラム(CALLBACK関数と論理フォント作成の関数のみ)↓ //ウィンドウプロシージャ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp){ static HFONT hFont1, hFont2, hFont3; PAINTSTRUCT ps; HDC hdc; char *szName1 = "○○"; char *szName2 = "▲▲"; switch (msg) { case WM_CREATE: hFont1 = MyCreateFont(40, SHIFTJIS_CHARSET, "HG行書体"); hFont2 = MyCreateFont(40, ANSI_CHARSET, "Fraktur JS"); hFont3 = MyCreateFont(40, SHIFTJIS_CHARSET, "MS 明朝"); break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); SelectObject(hdc, hFont1); TextOut(hdc, 0, 0, (LPCTSTR)szName1, (int)strlen(szName1)); SelectObject(hdc, hFont2); TextOut(hdc, 0, 60, (LPCTSTR)szName2, (int)strlen(szName2)); SelectObject(hdc, hFont3); TextOut(hdc, 0, 120, (LPCTSTR)szName1, (int)strlen(szName1)); EndPaint(hWnd, &ps); break; case WM_DESTROY: DeleteObject(hFont1); DeleteObject(hFont2); DeleteObject(hFont3); PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, msg, wp, lp)); } return 0; } //論理フォントの作成 HFONT MyCreateFont(int nHeight, DWORD dwCharSet, LPCTSTR lpName){ return(CreateFont(nHeight, 0, 0, 0, FW_DONTCARE. FALSE, FALSE, FALSE, dwCharSet, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, lpName)); } エラー内容↓ MyCreateFontの識別子が見つかりません。 論理フォントの関数のFALSEの値が構文エラーで参照できない。

  • Win32APIを使って入力されたキーによって表示する画像を変えるプログラムについて

    Win32APIを使って入力されたキーによって表示する画像を変えるプログラムを今、VisualSutudio2005のVC++で作っている最中なのですが、 上手く画像が表示されず困っています。具体的には、キーボードからキーが入力されたらTranslateMessage関数でWM_CHARメッセージを送って、その値(wParam)をWM_CHARメッセージ内でTCHAR型の変数に代入し、InvalidateRect関数を使ってWM_PAINTメッセージを送って、再描画処理を行ってその中で、if(tchar == 'a') { hbitmap = (HBITMAP)LoadImage(NULL,BMP,IMAGE_BITMAP,0,0,LR_LOADFROMFILE); SelectObject(hMemdc,hbitmap); GetObject(hbitmap,sizeof(BITMAP),&bitmap); BitBlt(painthdc,0,0,350,467,hMemdc,0,0,SRCCOPY); } という処理をしてaが入力されたら読み込んだ画像を表示!という形にしたいのですが、実際ウィンドウには表示されなくて悩んでいます。わかりにくくて誠に申し訳ありませんが、どなたかどうかご教授願えないでしょうか。何卒よろしくお願い致します。

  • 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)));

専門家に質問してみよう