我有一个标准的 win32 窗口,我使用D2D1
. 一切都响应迅速并且运行顺利。我的问题如下:创建窗口后,它调用WM_PAINT
一次然后“卡住”等待任何用户输入(例如鼠标移动或单击窗口区域)。当它接收到输入时,它运行没有任何进一步的问题。虽然这并不一定会使程序无法运行,但它似乎非常不专业并且......丑陋。哦,我所说的“卡住”的意思是后台进程仍然运行没有问题,所以循环按预期运行 - 但是,由于WM_PAINT
某种原因没有调用。
这是当前代码:
头文件:
#define PROGRAM_FPS 30
#define GWINDOW_STYLE (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_CLIPCHILDREN | WS_CLIPSIBLINGS)
class Application
{
public:
Application();
~Application();
// Register the window class and call methods for instantiating drawing resources
HRESULT Initialize();
// Process and dispatch messages
void RunMessageLoop();
static inline void SafeRelease(IUnknown * _X)
{
if(_X != NULL)
_X->Release();
};
HRESULT SetFullscreen(bool);
private:
// Time (ms) between frames of the application
// Initiation: m_AppFPS_Div( (DWORD)1000.0 / (DWORD)PROGRAM_FPS )
const DWORD m_AppFPS_Div;
// Initialize device-independent resources.
HRESULT CreateDeviceIndependentResources();
// Initialize device-dependent resources.
HRESULT CreateDeviceResources();
// Release device-dependent resource.
void DiscardDeviceResources();
// Draw content.
HRESULT OnRender();
HRESULT LoadBitmapFromFile(
ID2D1RenderTarget*,
PCWSTR,
UINT,
UINT,
ID2D1Bitmap **
);
// The windows procedure.
static LRESULT CALLBACK WndProc(
HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam
);
HWND m_hwnd;
ID2D1Factory * m_pDirect2dFactory;
ID2D1HwndRenderTarget * m_pRenderTarget;
IWICImagingFactory *m_pIWICFactory;
ID2D1SolidColorBrush * m_pWhiteBrush;
ID2D1SolidColorBrush * m_pGrayBrush;
ID2D1LinearGradientBrush * m_pLinearGradientBrush;
ID2D1Bitmap *m_LoadingPicture;
};
.cpp 文件的一部分
void Application::RunMessageLoop()
{
HACCEL hAccelTable = LoadAccelerators(hInst, MAKEINTRESOURCE(IDC_WIN32APP));
DWORD screen_last_refresh = 0;
MSG msg;
for(bool applicationRunning = true; applicationRunning;)
{
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if(msg.message == WM_QUIT)
{
applicationRunning = false;
}
if(!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
/*** HERE I RUN VARIOUS BACKGROUND PROCESSES ***/
while((GetTickCount() - screen_last_refresh) < m_AppFPS_Div)
Sleep(2);
InvalidateRect(msg.hwnd, NULL, false);
screen_last_refresh = GetTickCount();
}
}
LRESULT CALLBACK Application::WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
LRESULT result = 0;
if (message == WM_CREATE)
{
LPCREATESTRUCT pcs = (LPCREATESTRUCT)lParam;
Application *pApp = (Application *)pcs->lpCreateParams;
::SetWindowLongPtrW(hwnd, GWLP_USERDATA, PtrToUlong(pApp) );
InvalidateRect(hwnd, NULL, false);
result = 1;
}
else
{
Application *pApp = reinterpret_cast<Application *>(static_cast<LONG_PTR>(
::GetWindowLongPtrW(
hwnd,
GWLP_USERDATA
)));
bool wasHandled = false;
if (pApp)
{
switch (message)
{
case WM_SIZE:
{
UINT width = LOWORD(lParam);
UINT height = HIWORD(lParam);
pApp->OnResize(width, height);
}
result = 0;
wasHandled = true;
break;
case WM_DISPLAYCHANGE:
{
InvalidateRect(hwnd, NULL, FALSE);
}
result = 0;
wasHandled = true;
break;
case WM_PAINT:
{
pApp->OnRender();
ValidateRect(hwnd, NULL);
}
result = 0;
wasHandled = true;
break;
case WM_DESTROY:
{
PostQuitMessage(0);
}
result = 1;
wasHandled = true;
break;
}
}
if (!wasHandled)
{
result = DefWindowProc(hwnd, message, wParam, lParam);
}
}
return result;
}
HRESULT Application::OnRender()
{
HRESULT hr = S_OK;
hr = CreateDeviceResources();
if (SUCCEEDED(hr))
{
m_pRenderTarget->BeginDraw();
m_pRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity());
/** HERE I HANDLE THE OPENING ANIMATION **/
hr = m_pRenderTarget->EndDraw();
}
if (hr == D2DERR_RECREATE_TARGET)
{
hr = S_OK;
DiscardDeviceResources();
}
return hr;
}
因此,我在 2 台计算机(均使用 Win 8.1)上使用 VS 2012 Ultimate 和 VS 2013 Professional 对其进行了测试,来回运行调试测试,剥离程序的某些部分,搜索 MDSN、Google 和 StackExchange - 无济于事。当我处理WM_COMMAND
子窗口时,也会发生这种冻结。当我尝试实现 GDI+ 时也没有这样的问题,但事实证明它非常无效,因此切换到 DirectX。除此之外,该程序运行完美。我希望我已经提供了足够的信息。