2013-08-08 3 views
0

Проблема заключается в том, что анимация OpenGL прекращается, когда на кнопку TFORM нажимается кнопка мыши (граница, подпись). Как только кнопка мыши отпущена, анимация продолжается.Анимация с компонентом VCL (WM_PAINT)

// 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(); 
     } 
    } 
} 

Что нужно сделать, чтобы не останавливать анимацию при изменении размеров формы, каких-либо полезных ссылок?

ответ

0

Это связано с тем, что ваш основной цикл сообщений заблокирован, а цикл вторичного сообщения запущен во время перетаскивания/изменения размера окна. То же самое происходит, когда меню активны, отображаются модальные диалоги и т. Д. Вы ничего не можете с этим поделать, это просто то, как работает Windows.

BTV, предполагая 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(); 
} 
Смежные вопросы