我正在将c++与win32和gdi +一起用于图形。
当我初始化WM_CREATE外部的按钮时,特别是在WM_TIMER消息中,在绘制一帧之后,我无法再绘制其他任何东西。
这是一段代码:
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。 starting是实例化为true的全局 bool(boolean) 值。
我在此WM_TIMER消息中完成了所有绘图。如果仅注释创建按钮的两行,则一切正常。有了它们,它只会画出此WM_TIMER中剩余的内容,而不会画出下一个。所有其他绘制代码都对hdcBuf或g完成,然后将hdcBuf BitBlt'd到hdc上。
我尝试在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;
最佳答案
您在每个计时器调用上至少创建/获取3个Device Context实例,并且您从未删除/释放它们(至少在您发布的示例中),因此毫不奇怪地,您将破坏整个GDI系统。
对于每个GetDC()调用,应调用ReleaseDC(),
对于每个CreateCompatibleDC()调用,都应调用DeleteObject()。
关于c++ - 如何在Win32中的WM_CREATE消息外部创建按钮?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13544253/