2013-03-06 3 views
1

저는 현재 DirectX와 Win32 API를 기반으로 한 작은 렌더링 엔진을 개발하려고합니다. 현재 해결하려고하는 문제는 DirectX 코드에 영향을주는 Windows 메시지 (예 : DirectX 버퍼 크기 조정을 의미하는 WM_SIZE 메시지)를 처리하기 위해 내 코드를 올바르게 구성하는 방법입니다.DirectX로 Win32 메시지 처리를 올바르게 구성하는 방법?

창을 만들 때 전달되는 WndProc 함수에서 수행해야하지만 관심이있는 메시지를 "전송할 수있는 방법"을 모르겠습니다. 지금까지는 발견이 방법 :

//main.cpp 
Renderer* renderer; 

//some code 

//The window procedure 
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
    PAINTSTRUCT ps; 
    HDC hdc; 

    //We forward the message to the Renderer, which handles it or not 
    if(renderer->HandleMessage(hWnd,message,wParam,lParam){ 
     return 0; 
    } 

    //If the renderer does not handle the message, we do as usual 
    switch(message) 
    { 
     case WM_PAINT: 
      hdc = BeginPaint(hWnd, &ps); 
      EndPaint(hWnd, &ps); 
      break; 

     case WM_DESTROY: 
      PostQuitMessage(0); 
      break; 

     default: 
      return DefWindowProc(hWnd, message, wParam, lParam); 
    } 

    return 0; 
} 

나는이 방법으로이 문제는 전역 변수를 사용하는 것이 아니라고 그것이 내가 많이들을 수 있기 때문에 내가 익숙하지 전역 변수 (렌더러)에 의존한다는 것입니다 좋은 연습 (그리고 나는 그것이 내가 그것을 사용해야하는 경우인지 결정할 정도로 충분히 경험이 없다고 느낀다)

"앞으로"바람에 더 좋은 접근 방법이 있는지 알고 싶다. 글로벌 변수가 필요없는 메시지를 전달할 수 있습니다.

답변

3

먼저 WM_PAINT는 Direct3D 렌더링이 아닌 GDI 그림 용입니다. 일반적으로 D3D 앱은 가능할 때마다 프레임을 렌더링합니다.

두 번째로 SetWindowLongPtr을 사용하여 렌더러에 대한 포인터를 HWND와 연결된 내부 Windows 변수로 설정하면 GetWindowLongPtr으로 되돌아 갈 수 있습니다.

셋째,이 클래스를 래핑하는 Window 클래스가 있어야합니다.이 클래스는 직접 상호 작용하기보다는 렌더러에 알리기 위해 선택합니다.

편집 :

class Window { 
    HWND hwnd; 
    static ... WindowProc(...) { 
     if (auto p = GetWindowLongPtr(hwnd, GWLP_USERDATA)) 
      return reinterpret_cast<Window*>(p)->ProcessMessage(...); 
     else return DefWindowProc(...); 
    } 
    ... ProcessMessage(...) { 
     /* whatever you want */ 
     if (msg == WM_RESIZE) 
      OnResize(...); 
    } 
public: 
    Window() { 
     hwnd = CreateWindowEx(...); 
     SetWindowLongPtr(hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this)); 
    } 
    std::function<void(unsigned, unsigned)> OnResize; 
}; 

이때 processMessage를()의 구성원되고, 윈도우는 단지 외부 코드가이 특정 이벤트에 후크 있도록 콜백을 제공한다 : 여기서 일반 슈퍼 간단한 구조이다.

+0

고마워요. 나는'SetWindowLongPtr'과'GetWindowLongPtr'을 들여다 보았다. 만약 내가 맞으면,'SetWindowLongPtr'를 사용하여'GWLP_USERDATA' 속성에 내 Renderer에 대한 포인터를 저장 한 다음 getter를 사용하고 반환 된 값을 Renderer에 대한 포인터로 캐스팅하고 적절한 멤버 함수를 호출해야합니다 s)? 어쨌든, WNDCLASSEX 구조체의'lpfnWndProc'에 비 멤버 함수를 제공해야 할 필요가 있기 때문에 Window 클래스에서 이것을 어떻게 래핑 할 수 있는지 이해하지 못합니다 ... – JBL

+0

@JBL : 예, 맞습니다. . 비회원을 WNDPROC로 제공하지만 GWLP_USERDATA 포인터 슬롯을 사용하여 즉시 멤버 함수를 호출하는 클래스 포인터를 저장합니다. – Puppy

+0

팁 덕분에 작동합니다! – JBL

관련 문제