内容目录
背景
因为自己用SDL写了一个协同软件,需要增加一个置顶功能,那么在系统菜单增加是最方便的。
效果图
代码逻辑
- 获取SDL window hwnd 句柄
- 获取系统菜单 HMENU hmenu = GetSystemMenu(hWnd, false);
- 处理SDL_SYSWMEVENT (前提要设置开启能获取SDL_SYSWMEVENT,默认关闭)
- 处理WM_SYSCOMMAND
代码片段
开启SDL 捕获系统消息
void WindowsUI::EnableSystemMsg()
{
SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE);
}
安装系统菜单
void WindowsUI::InstallSysmenu() { HWND hw = GetMyHwnd(); HMENU hmenu = GetSystemMenu(hw, false); ::AppendMenu(hmenu, 0, MENU_SET_WINDOW_TOP, L"置顶/取消至置顶"); }
处理SDL_EVENT并置顶
if (event.type == SDL_SYSWMEVENT) {
HandleSystemEvent(event);
continue;
}
置顶代码
void WindowsUI::HandleSystemEvent(const SDL_Event& ev)
{
if (ev.syswm.msg->msg.win.msg == WM_SYSCOMMAND) {
int wmId = LOWORD(ev.syswm.msg->msg.win.wParam);
HWND& hw = ev.syswm.msg->msg.win.hwnd;
if (wmId == MENU_SET_WINDOW_TOP) {
DWORD dwExStyle = ::GetWindowLong(hw, GWL_EXSTYLE);
if ((dwExStyle & WS_EX_TOPMOST) != 0)
{
//dwExStyle &= ~WS_EX_TOPMOST;
//SetWindowLong(hw, GWL_EXSTYLE, dwExStyle); 貌似没有起作用
SetWindowPos(hw, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
}
else {
SetWindowPos(hw, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
}
}
}
}
代码判断是否当前窗口有置顶属性,如果没有就置顶,如果置顶就取消置顶。
这里发现SDL_EVENT 里面WINDOWID 不是当前窗口的ID,因为标题栏也是window一个窗口,但SDL传递过才是当前窗口。
//dwExStyle &= ~WS_EX_TOPMOST;
//SetWindowLong(hw, GWL_EXSTYLE, dwExStyle); 貌似没有起作用