グラフィックにはwin32とgdi+でc++を使用しています。
WM_CREATEの外部、特にWM_TIMERメッセージでボタンを初期化すると、1つのフレームが描画された後、他に何も描画できなくなります。コードの抜粋は次のとおりです。
case WM_TIMER:
RECT client;
GetClientRect(hWnd, &client);
client.bottom-=100; //The bottom hundred pixels are static after I draw the first frame, so I never update them
if(starting==true)
{
starting=false;
hdc = GetDC(hWnd);
hdcBuf = CreateCompatibleDC(hdc);
hdcMem = CreateCompatibleDC(hdcBuf);
hbmBackBM = CreateCompatibleBitmap(hdc, client.right, client.bottom );
hbmOldBackBM = (HBITMAP)SelectObject(hdcBuf, hbmBackBM);
Graphics temp(hdc);
SolidBrush yelloworange(Color(250,225,65));
temp.FillRectangle(&yelloworange,0,client.bottom,client.right,100); //Fill the bottom with yellow
buttons[0]=CreateWindow("button","makereg", WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, 100, 630, 60, 20, hWnd, HMENU(IDB_MAKEREG), NULL, NULL);
//buttons[1]=CreateWindow("button","destroyreg", WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, 100, 670, 80, 20, hWnd, HMENU(IDB_MAKEREG+1), NULL, NULL);
}
Graphics g(hdcBuf);
最初の部分はダブルバッファリング用であり、インスタンス化する変数はグローバルです。WM_DESTROYのHDCとHBITMAPを削除します。startは、trueとしてインスタンス化されるグローバルブール値です。このWM_TIMERメッセージですべての描画を行います。ボタンが作成された2行だけをコメントアウトすると、すべてが正常に実行されます。それらを使用すると、このWM_TIMERに残っているものだけが描画され、次のWM_TIMERには描画されません。他のすべての描画コードはhdcBufまたはgに対して実行され、hdcBufはhdcにBitBltされます。
WM_CREATEでボタンを作成し、それをWM_TIMERで表示しようとしましたが、同じ問題が発生しました。WM_CREATEでウィンドウを作成して表示することはできません。そうしないと、下の100ピクセルを黄色で塗りつぶしたときにウィンドウが描画されてしまうためです。
コードの残りの部分をクラッシュさせることなく、WM_CREATEの外側とWM_PAINTの外側にボタンを作成して表示する方法はありますか?
編集:WM_TIMERで動作を停止するコードの一部を次に示します。
if(mousex!=uptomousex && mousey!=uptomousey && lbuttondown==true) // this code draws a rectangle between the point where the user begins holding the left mousebutton, and where the mouse is right now.
{
if(uptomousex-mousex>0 && uptomousey-mousey>0)
g.DrawRectangle(&(p[0]), mousex, mousey, uptomousex-mousex, uptomousey-mousey);
else if(uptomousex-mousex<0 && uptomousey-mousey>0)
g.DrawRectangle((&p[0]), uptomousex, mousey, mousex-uptomousex, uptomousey-mousey);
else if(uptomousex-mousex>0 && uptomousey-mousey<0)
g.DrawRectangle((&p[0]), mousex, uptomousey, uptomousex-mousex, mousey-uptomousey);
else if(uptomousex-mousex<0 && uptomousey-mousey<0)
g.DrawRectangle(&(p[0]), uptomousex, uptomousey, mousex-uptomousex, mousey-uptomousey);
}
いくつかのグローバル変数:
bool lbuttondown=false;
float mousex=0;
float mousey=0;
float uptomousex=0;
float uptomousey=0;
WndProcの他の場所...
case WM_LBUTTONDOWN:
lbuttondown=true;
mousex=(float)GET_X_LPARAM(lParam);
mousey=(float)GET_Y_LPARAM(lParam);
uptomousex=mousex;
uptomousey=mousey;
break;
case WM_MOUSEMOVE:
if(mousex!=GET_X_LPARAM(lParam) && mousey!=GET_Y_LPARAM(lParam))
{
uptomousex=(float)GET_X_LPARAM(lParam);
uptomousey=(float)GET_Y_LPARAM(lParam);
}
break;