# Windows Forms game loop

There is a very good game loop in the link which is tailored for windows forms. I need it in c++/cli so I converted the code as below. Here is my main loop.

using namespace System;
using namespace System::Windows::Forms;

HWND g_theAppHandle = nullptr;

bool IsApplicationIdle()
{
MSG msg;
return PeekMessage(&msg, g_theAppHandle, 0, 0, 0) == 0;
}

void OnIdle(System::Object ^sender, System::EventArgs ^e)
{
while (IsApplicationIdle())
{
if (PunkEd::ABTCLI::g_initSuccess)
{
PunkEd::ABTCLI::Frame(0.0f);
}
}
}

int CALLBACK WinMain(
_In_ HINSTANCE hInstance,
_In_ HINSTANCE hPrevInstance,
_In_ LPSTR     lpCmdLine,
_In_ int       nCmdShow
)
{
_CrtMemState memstate;
_CrtMemCheckpoint(&memstate);

PunkEd::PunkEdMain^ theApp = gcnew PunkEd::PunkEdMain;
g_theAppHandle = (HWND)theApp->Handle.ToPointer();

Application::Idle += gcnew System::EventHandler(&OnIdle);
Application::Run(theApp);

_CrtMemDumpAllObjectsSince(&memstate);
return 0;
}


This loop triggers PunkEd::ABTCLI::Frame(0.0f); every time the application is idle. And Frame(float deltaTime); function triggers everyting related to game. Like render and physics. However my rendering window is a panel. And I override its mouse move callback as below.

private: System::Void panel1_MouseMove(System::Object^  sender, System::Windows::Forms::MouseEventArgs^  e) {
Debug::WriteLine(e->Location);

glm::vec3 cp = glm::vec3(e->Location.X, e->Location.Y, 0);
glm::mat4 view = g_camera->GetViewMatrix();
glm::mat4 project = g_camera->m_projection;
glm::unProject(cp, view, project, glm::vec4(0.0f, 0.0f, (float)panel1->Width, (float)panel1->Height));

cp.x -= panel1->Width / 2.0f;
cp.y -= panel1->Height / 2.0f;

g_cursor->m_node->m_translation = cp.xzy;
}


This function updates my curser's position in the game. However my render function is get called after I stop moving the mouse. How can I overcome this stuation such that my curser position gets update and renders immediatly after I moved mouse.

• If you're doing this in C++/CLI it seems like you could very possibly just use the more natural Win32 version of the loop. Also, I don't understand your question entirely; you mean that with your mouse-move hook in your panel, the render function only gets called after you're done moving the mouse, not during? And you want it to be called while you move the mouse as well? – Josh Sep 6 '16 at 20:14
• I couldn't think of using win32 version. I'll try it immediately. For the second part. Yes the stuation is as you said so. – Cihan Sep 6 '16 at 20:17

The scenario you are seeing likely occurs because mouse movements are Windows events (WM_MOUSEMOVE), and by hooking them in the panel and doing a bunch of work during one, you keep the event queue full longer than usual (this is partly because WM_MOUSEMOVE is a bit special, and if the mouse is moving you'll basically get one event every time GetMessage is called on your behalf).
While the event queue is "full" of these events, you won't receive OnIdle callbacks and your game won't "remain idle" for the purposes of OnApplicationIdle. Since you only render when the game is idle, you thus defer rendering noticeably while moving the mouse.
When you don't do anything for mouse-move events, they process out quick enough that you don't notice (that Debug::WriteLine is going to be particularly slow).