我正在将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/

10-11 18:08