0

问题是在 TForm 组件(边框、标题 ..)上单击任何鼠标按钮时 OpenGL 动画停止。只要松开鼠标按钮,动画就会继续。

// Drawing Scene 
 void TMainForm::DrawGLScene()
{
    glClearColor(1,1,1,1);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    DrawFigure();
    SwapBuffers(hDC);
}

// Catching WM_PAINT 
LRESULT CALLBACK NewWindowProcPanel3D(HWND hWnd, UINT msg, WPARAM w, LPARAM l)
{
    switch (msg)
    {
        case WM_ERASEBKGND :
        {
            return 1;
        }
        case WM_PAINT :
        {
            MainForm->DrawGLScene();
        }
        default: return CallWindowProc((FARPROC)MainForm->OldWindowProcPanel3D,
            hWnd, msg, w, l);
    }
    return 0;
}

// Creating OldWindowProcPanel3D -
 void __fastcall TMainForm::FormCreate(TObject *Sender)
{
    OldWindowProcPanel3D = (WNDPROC)SetWindowLong(Panel3D->Handle,
        GWL_WNDPROC, (long)NewWindowProcPanel3D);
}

// --------- *.h :
class TMainForm : public TForm
{
    private:
       HDC hDC;
    public:
        WNDPROC OldWindowProcPanel3D;
}

// Generation event WM_PAINT 
 void TMainForm::UpdateScene()
{
    InvalidateRect(Panel3D->Handle, NULL, false);
}

// Animation code ( turn on 'animation' if RadioButton is chosen) 
 void __fastcall TMainForm::RadioGroupClick(TObject *Sender)
{
    if (RadioGroup->ItemIndex == 0)
       animation = false;
    else if (RadioGroup->ItemIndex == 1)
        animation = true;
     if (animation)
    {
        while (animation)
       {
            Application->ProcessMessages();
            UpdateScene();
        }
    }
}

在更改表单大小时如何不停止动画,任何有用的链接?

4

1 回答 1

0

那是因为您的主消息循环被阻止并且在窗口被拖动/调整大小时正在运行辅助消息循环。当菜单处于活动状态、显示模式对话框等时也会发生同样的事情。对此您无能为力,这就是 Windows 的操作方式。

顺便说一句,假设Panel3D is aTPanel or similar VCL control, you should subclass itsWindowProc property instead ofSetWindowsLong() , since theTWinControl::Handle` 属性不是持久的。

你需要完全摆脱你的使用Application->ProcessMessages()。除非绝对必要,否则永远不要直接调用它。

试试这个:

class TMainForm : public TForm
{
private:
    HDC hDC;
    bool animation;
    TWndMethod OldWindowProcPanel3D;
    void DrawGLScene();
    void __fastcall NewWindowProcPanel3D(TMessage &Message);
public:
    __fastcall TMainForm(TComponent *Owner);
};

// Creating OldWindowProcPanel3D -
__fastcall TMainForm::TMainForm(TComponent *Owner)
    : TForm(Owner)
{
    OldWindowProcPanel3D = Panel3D->WindowProc;
    Panel3D->WindowProc = &NewWindowProcPanel3D;
}

// Drawing Scene 
void TMainForm::DrawGLScene()
{
    glClearColor(1,1,1,1);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    DrawFigure();
    SwapBuffers(hDC);
}

// Catching WM_PAINT 
void __fastcall TMainForm::NewWindowProcPanel3D(TMessage &Message)
{
    switch (Message.Msg)
    {
        case WM_ERASEBKGND :
        {
            Message.Result = 1;
            break;
        }

        case WM_PAINT :
        {
            DrawGLScene();
            if (animation)
                UpdateScene();
            break;
        }

        default:
        {
            OldWindowProcPanel3D(Message);
            break;
        }
    }
}

// Generation event WM_PAINT 
void TMainForm::UpdateScene()
{
    Panel3D->Invalidate();
}

// Animation code ( turn on 'animation' if RadioButton is chosen) 
void __fastcall TMainForm::RadioGroupClick(TObject *Sender)
{
    if (RadioGroup->ItemIndex == 0)
        animation = false;
    else if (RadioGroup->ItemIndex == 1)
        animation = true;

    if (animation)
        UpdateScene();
}
于 2013-08-20T01:19:58.927 回答