Вызов виртуальной функции c ++ из WndProc завершается неудачно - PullRequest
0 голосов
/ 03 сентября 2011

Я разрабатываю программу, которая отображает графические окна, используя Windows API.Ниже приведена функция, которую я предоставил как WndProc при регистрации класса окна - это статическая функция внутри класса WindowsWindow.

#define BTK_DLL_FUNC __dllspec(dllexport)

class AbstractBackend
{
protected:
  bool FatalWarnings;

public:
  AbstractBackend (bool FatalWarnings=false);
  ~AbstractBackend ();

  virtual void StartMainLoop () = 0;
  virtual void QuitMainLoop () = 0;
};

class WindowsBackend : public Base::AbstractBackend
{
public:
  static HINSTANCE hinstance;
  static WindowsBackend* instance;

public:
  BTK_DLL_FUNC WindowsBackend ();
  BTK_DLL_FUNC ~WindowsBackend ();

  BTK_DLL_FUNC void StartMainLoop ();
  BTK_DLL_FUNC void QuitMainLoop ();
};


void WindowsBackend::StartMainLoop ()
{
  MSG Msg;
  while (GetMessage (&Msg, NULL, 0, 0) > 0)
  {
    TranslateMessage (&Msg);
    DispatchMessage (&Msg);
  }
}

void WindowsBackend::QuitMainLoop ()
{
  PostQuitMessage (0); /* Send a WM_QUIT message, to stop the main loop */
}

LRESULT CALLBACK WindowsWindow::WndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
  switch (msg)
  {
  case WM_CREATE:
    break;

  case WM_CLOSE:
    DestroyWindow (hwnd);
    break;

  case WM_DESTROY: /* The window was destroyed */
    {
      WindowsBackend::instance->QuitMainLoop (); /* This doesn't work! */
      break;
    }

  default:
    return DefWindowProc(hwnd, msg, wParam, lParam);
  }
  return 0;
}

Теперь вот часть, которую я не понимаю - QuitMainLoop не делаетне начинается и не возвращается (я попробовал отладчик, и он показал, что функция Quit не вызывается, а также что ни одна строка после этого вызова не выполняется).Практически моя программа застревает после этого вызова.

Но замена вызова пользовательской функции выхода на прямой вызов PostQuitMessage работает.

Любые объяснения и / или способобойти это (и иметь возможность вызывать виртуальную функцию) будет очень полезно.

Редактировать: Добавлен точный код

1 Ответ

1 голос
/ 03 сентября 2011

Поскольку вы не опубликовали полный код, который мы можем запустить, чтобы воспроизвести проблему, мы должны догадаться.

Единственный способ, с помощью которого я могу увидеть, что вызов на QuitMainLoop() завершился неудачей, это если WindowsBackend::instance каким-то образом поврежден. Вы уничтожили его по ошибке, прежде чем позвонить QuitMainLoop()? Возможно, было повреждение памяти?

Я бы посмотрел на это в представлении разборки в отладчике. Это должно сказать вам, что пошло не так, и вам нужно следовать подсказкам, чтобы выяснить, почему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...