问题是,当在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();
}