windows - At kalde en c ++ virtuel funktion fra WndProc mislykkes

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg udvikler et program, der viser grafiske vinduer ved hjælp af Windows API. Nedenfor er funktionen jeg leverede som WndProc ved registrering af vinduesklassen - det er en statisk funktion inde i klassen 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;
}


Nu er her den del, jeg ikke forstår - QuitMainLoop starter ikke, og den vender ikke tilbage (jeg prøvede debuggeren, og det viste, at Quit-funktionen ikke bliver kaldt, og også at enhver linje efter at kalde er ikke eksekveret). Så praktisk taget bliver mit program fast efter det pågældende opkald.


Men at erstatte opkaldet til den tilpassede afslutningsfunktion med et direkte opkald til PostQuitMessage fungerer.


Enhver forklaring og/eller måde at omgå dette (og være i stand til at kalde en virtuel funktion) ville være meget appriciated.


Rediger: Tilføjet den nøjagtige kode

Bedste reference


Da du ikke har indsendt fuld kode, som vi kan køre for at reproducere problemet, skal vi gætte.


Den eneste måde, jeg kan se for opkaldet til QuitMainLoop() at mislykkes, er, hvis WindowsBackend::instance på en eller anden måde er beskadiget. Har du ødelagt det ved en fejl, før du ringede til QuitMainLoop()? Har der måske været en hukommelseskorruption måske?


Jeg ville se på dette under disassembly visning i debugger. Det skal fortælle dig, hvad der er gået galt, og så skal du følge sporene for at finde ud af hvorfor.