使用VCL组件的动画(WM_PAINT)



问题是,当在TForm组件上单击任何鼠标按钮(border,caption..)时,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();
        }
    }
}

要做什么才能在改变形状大小时不停止动画,任何有用的链接?

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

BTW,假设Panel3D is a TPanel or similar VCL control, you should subclass its WindowProc property instead of SetWindowsLong(), since the TWinControl::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();
}

相关内容

  • 没有找到相关文章