如何在 Win32 菜单中使用 SDL
Posted
技术标签:
【中文标题】如何在 Win32 菜单中使用 SDL【英文标题】:How to use SDL with Win32 Menus 【发布时间】:2017-12-11 02:38:58 【问题描述】:这是我已经研究了很长一段时间的 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;
当我这样做时,不会调用回调。 任何帮助表示赞赏。 谢谢!
【问题讨论】:
显示minimal reproducible example.. 【参考方案1】:您将退出 HMENU 指定为您为退出创建的项目的 ID,这与“案例 2:”不匹配。
摆脱“HMENU退出”拨打电话:
AppendMenu(file, MF_STRING, 2, _T("Exit"));
我建议您分配一些常量名称(#define 或 enum)并在 AppendMenu 和 case 语句中使用该标识符。
【讨论】:
不行,还是不行。当我点击它时什么都不做。【参考方案2】:普通菜单项具有数字 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;
【讨论】:
以上是关于如何在 Win32 菜单中使用 SDL的主要内容,如果未能解决你的问题,请参考以下文章
SDL2:如何同时拥有 SDL2 菜单和 OpenGL 上下文?