2013-03-06 77 views
1

我目前正在尝试开发基于DirectX和Win32 API的小型渲染引擎。我目前试图解决的问题是如何正确组织我的代码来处理影响DirectX代码的Windows消息(例如,WM_SIZE消息,这意味着调整DirectX缓冲区的大小)。如何使用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; 
} 

我有这种方法的问题是,它依赖于一个全局变量(渲染),这是我,因为我听到了很多感觉不舒服与使用全局变量是不良好的做法(我觉得我没有足够的经验来决定是否应该使用它)

我想知道是否有更好的方法来“向前”风ow消息而不需要全局变量。

回答

3

首先,WM_PAINT用于GDI绘画,而不是Direct3D呈现。通常,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)?无论如何,我真的不知道如何将它包装在Window类中,因为我仍然需要在WNDCLASSEX结构中为'lpfnWndProc'提供一个非成员函数...... – JBL 2013-03-06 19:19:05

+0

@JBL:是的,没错。您提供了一个非成员作为WNDPROC,但是使用GWLP_USERDATA指针槽来存储一个类指针,该指针立即在其上调用成员函数。 – Puppy 2013-03-06 20:58:44

+0

它的工作原理,感谢提示! – JBL 2013-03-06 22:19:46