如何在Win32菜单中使用SDL

时间:2017-12-11 02:38:59

标签: c++ windows winapi sdl

这是一个GameBoy模拟器,我已经工作了很长一段时间。它最初只适用于MacOS,但我最近一直在使用Windows端口。我正在使用SDL进行窗口创建和渲染。我想要做的是使用Win32 API(CreateMenu,AppendMenu等)创建一个普通的Windows菜单栏。到目前为止,我可以让窗口中存在菜单栏,但我正在尝试使用CALLBACK WndProc()添加回调,因此菜单知道您正在点击一个选项。这不是那么成功。有谁知道怎么做?

这是WinMain入口点:

/***************** INSTANCES *******************/
static Core::GameBoy* mGameBoy_Instance;
static FrontEnd::SDLContext* mSDL_Instance;
/***********************************************/
INT WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, INT nCmdShow)
{
    // Load options
    Core::Settings settings;
    Util::CreateSettingsFromFile(OPTIONS_FILE_PATH, settings);
    settings.skip_bootrom = true;
    // Create the system instance
    mGameBoy_Instance = new Core::GameBoy(settings, WIN_WIDTH, WIN_HEIGHT);
    // Initalize Render Context
    const char* windowTitle = mGameBoy_Instance->GetCurrentROM()->GetRomName();
    mSDL_Instance = new FrontEnd::SDLContext(WIN_WIDTH, WIN_HEIGHT, WIN_SCALE, windowTitle);

    // Initialize menubar
    SDL_SysWMinfo sysInfo;
    SDL_VERSION(&sysInfo.version);
    SDL_GetWindowWMInfo(mSDL_Instance->GetWindow(), &sysInfo);
    HWND hwnd = sysInfo.info.win.window;

    /*********************************/
    HMENU menubar = CreateMenu();
    /*********************************/
    HMENU file = CreateMenu();
    HMENU exit = CreateMenu();
    /*********************************/
    AppendMenu(menubar, MF_POPUP, (UINT_PTR)file, "File");
    AppendMenu(file, MF_STRING, (UINT_PTR)exit, "Exit");
    SetMenu(hwnd, menubar);

    // start sdl thread and main loop
}

这是回调函数代码:

LRESULT CALLBACK WndProc(_In_ HWND hwnd, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam)
{
    switch (uMsg) {
    case WM_COMMAND:
    {
        switch (LOWORD(wParam)) {
        case 2: // Should be the Exit button in the order of the menu
            SendMessage(hwnd, WM_CLOSE, 0, 0);
            break;
        }
        return 0;
    }
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;

    default:
        return DefWindowProcW(hwnd, uMsg, wParam, lParam);
    }

    return NULL;
}

当我这样做时,不会调用回调。 任何帮助表示赞赏。 谢谢!

2 个答案:

答案 0 :(得分:1)

您正在指定退出HMENU作为您为退出创建的项目的ID,这与“案例2:”不匹配。

摆脱“HMENU退出”拨打电话:

AppendMenu(file, MF_STRING, 2, _T("Exit"));

我建议您指定一些常量名称(#define或enum),并在AppendMenu和case语句中使用该标识符。

答案 1 :(得分:0)

普通菜单项有数字ID,而不是HMENU句柄。 Submenus should be created with CreatePopupMenu,而不是CreateMenu

#define ID_EXIT 50

...

  HMENU menubar = CreateMenu();
  HMENU filemenu = CreatePopupMenu();
  AppendMenu(filemenu, MF_STRING, ID_EXIT, "Exit");
  AppendMenu(menubar, MF_POPUP, (UINT_PTR) filemenu, "File");
  SetMenu(hwnd, menubar);

...

  case WM_COMMAND:
        switch (LOWORD(wParam)) {
          case ID_EXIT:
            SendMessage(hwnd, WM_CLOSE, 0, 0);
            break;
        }
    break;