2011-10-15 3 views
0

좋아, 그럼 내가 아주 기본적인 애니메이션 물건을 (만약 당신이 애니메이션이라 부를 수 있다면) 창문에서 시험해보고 있었다. 텍스트가없는 TextOut (텍스트의 좌표) 매개 변수가 엉망입니다. 기본적으로, 그것은 마치 두 곳의 다른 장소에서 "안녕하세요"를 인쇄 할 것입니다. 그런 다음 아무 일도 일어나지 않는 것 같았습니다. 문제는 InvalidateRect에 대한 이전 호출의 텍스트가 화면에서 지워지지 않고 텍스트가 화면에 그려지는 것입니다. 또한 간단한 증분 계열 값 (예 : 1,2,3,4,5 등)을 TextOut에 매개 변수로 넣을 때 그런 문제는 없습니다. 먼저C++의 간단한 애니메이션

#include <Windows.h> 

LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam); 
struct point 
{ 
    double x; 
    double y; 
    double t; 
}; 


point obj={30,30,1}; 

int WINAPI wWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPWSTR cmdLine,int cmdShow) 
{ 
    WNDCLASSEX windowsClass={0}; 



    windowsClass.hCursor=LoadCursor(NULL,IDC_ARROW); 
    windowsClass.cbSize=sizeof(WNDCLASSEX); 
    windowsClass.hInstance=hInstance; 
    windowsClass.lpfnWndProc=WndProc; 
    windowsClass.cbClsExtra=NULL; 
    windowsClass.style=CS_HREDRAW | CS_VREDRAW; 
    windowsClass.hIcon=LoadIcon(NULL,IDI_APPLICATION); 
    windowsClass.hbrBackground=(HBRUSH)GetStockObject(NULL_BRUSH); 
    windowsClass.lpszClassName="Devjeet's Window"; 

    if(!RegisterClassExA(&windowsClass)) 
     return -1; 
    HWND hWnd = CreateWindowExA(NULL,"Devjeet's Window","Animation V1 By Devjeet",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,400,400,NULL,NULL,hInstance,NULL); 

    if(!hWnd) 
     return -1; 
    ShowWindow(hWnd,cmdShow); 


    MSG msg={0}; 

    while(msg.message!=WM_QUIT) 
    { 
     if(PeekMessage(&msg,0,0,0,PM_REMOVE)) 
     { 
      TranslateMessage(&msg); 
      DispatchMessage(&msg); 
     } 
    } 
    return static_cast<int>(msg.wParam); 
} 

LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) 
{ 
    HDC hDC; 
    PAINTSTRUCT paintStruct; 

    switch(message) 
    { 

    case WM_PAINT: 
     hDC=BeginPaint(hWnd,&paintStruct); 

     TextOut(hDC,(int)(obj.x),(int)(obj.y),"Hello",sizeof("Hello")); 
     obj.y=(double)(30*obj.t+(obj.t*obj.t*9.8/2)); 
     obj.x=(double)(30*obj.t+(obj.t*obj.t*9.8/2)); 
     obj.t+=.8; 


     EndPaint(hWnd,&paintStruct); 
     if(obj.y>100.0) 
     { 
      obj.x=30.0; 
      obj.y=30.0; 
      obj.t=1.0; 
     } 

     Sleep(800); 
     InvalidateRect(hWnd,NULL,TRUE); 
     break; 
    case WM_DESTROY: 
     PostQuitMessage(NULL); 
     break; 
    default: 
     return DefWindowProc(hWnd,message,wParam,lParam); 
     break; 
    } 
    return 0; 
} 
+0

무엇이 당신의 질문입니까? – sth

+0

내 질문이 왜 이런 일입니까? 방정식에 문제가 있습니까? 아니면 모르는 창에 대한 것이 있습니까? – devjeetroy

+1

@devjeetroy : 귀하의 질문 제목은 귀하의 질문과 어떤 관련이 있습니까? – Mat

답변

1

: 결코, 이제까지 당신의 WM_PAINT의 투수에서 Sleep를 호출하지 않습니다. UI를 잠급니다.

Windows에서 간단한 애니메이션을 수행하는 데 권장되는 방법은 SetTimer을 사용하고 WM_TIMER 메시지를 처리하는 것입니다. WM_TIMER 처리기는 스프라이트가 있어야하는 곳에서 작동하며 InvalidateRect을 호출합니다. 전체 창을 무효화하거나 이동 된 스프라이트의 이전 위치와 새 위치 만 무효화 할 수 있습니다.

InvalidateRect에 대한 응답으로 Windows에서 WM_PAINT 메시지를 보내면 창을 다시 칠할 수 있습니다.

오래된 배경을 지우지 않는 이유는 다음과 같습니다. NULL_BRUSH을 창 배경으로 지정 했으므로, 기본값핸들러 (Windows에서 창 콘텐츠를 지우는 곳)는 아무런 효과가 없습니다. WM_ERASEBKGND을 처리해야하며 (예 : FillRect과 같이 창을 지우려면) WM_PAINT 핸들러에서 해당 부분을 처리해야합니다.

아, 단순한 위치 증가가 작동하는 이유는 아마도 (정확하게 호출 한 경우) TextOut이 주어진 텍스트의 경계 상자 배경을 지울 것입니다. 이것은 아마도 텍스트보다 몇 픽셀 크기가 크기 때문에 멀리있는 픽셀 일 경우 이전 텍스트가 지워집니다.

관련 문제