切换语句使用

时间:2009-04-04 23:25:35

标签: c++ c windows winapi

我应该使用这种形式的switch语句:

  switch(msg)
  {
    case WM_LBUTTONDOWN:
    {
           char szFileName[MAX_PATH];
           HINSTANCE hInstance = GetModuleHandle(NULL);
           GetModuleFileName(hInstance, (LPWCH)szFileName, MAX_PATH);
           MessageBox(hwnd, (LPCWSTR)szFileName, L"This program is:", MB_OK | MB_ICONINFORMATION);
    }
    break;

    case WM_CLOSE:
        DestroyWindow(hwnd);
    break;
    case WM_DESTROY:
        PostQuitMessage(0);
    break;
    default:
        return DefWindowProc(hwnd, msg, wParam, lParam);
  }
  return 0;

或为第一个案例常量制作函数?

10 个答案:

答案 0 :(得分:9)

如何拥有它没有任何问题,但调用函数可能是更简洁的代码,因此您可以保持函数的合理大小。

答案 1 :(得分:5)

另外,请查看message crackers

答案 2 :(得分:3)

当有20或50个窗口消息时你打算做什么? 也许是时候创建地图 - 关于功能(fuctors)的事件并调用它们? 或者开始使用规则 - 一条消息=一个函数调用

char szFileName[MAX_PATH];
HINSTANCE hInstance = GetModuleHandle(NULL);
GetModuleFileName(hInstance, (LPWCH)szFileName, MAX_PATH);
MessageBox(hwnd, (LPCWSTR)szFileName, L"This program is:", MB_OK | MB_ICONINFORMATION);

你能用对流(LPCWSTR)szFileName解释这个奇怪的技巧吗?为什么不使用数组wchar_t代替转换? - 长路径会遇到很大问题(path_length> MAX_PATH / sizeof(wchar_t))

一个推荐 - 避免使用一般的演员表和特别是C风格的演员表。

答案 3 :(得分:2)

如果你问是否应该将第一种情况下的代码转换为函数,那么肯定是。

答案 4 :(得分:1)

嗯,这将取决于您将拥有多少其他案例。

小到那么小,我会说它不值得让它成为一个函数,但是如果你的switch语句包含更多的情况,它会变得很难看,特别是如果很多情况下有很多像这样的行。将它放入函数中会将其清理干净并使代码看起来更好。

答案 5 :(得分:1)

我要说的最重要的事情之一就是一致性。如果为LBUTTONDOWN创建函数,则为所有内容创建函数。这种方式有一个可预测的模式,用于在物品破裂的地方找到它。

与手头的主题相关:

我个人觉得if / else if模式更好用,因为它消除了遗忘中断的问题:

if (msg == WM_LBUTTONDOWN) {
    // your code here
    return 0;
} else if (msg == WM_DESTROY) {
    PostQuitMessage(0);
    return;
} else if (msg == WM_KEYDOWN) {
    if (wp == VK_F1) {
        DoSomething();
        return;
    }
}
return DefWindowProc(hWnd, msg, wp, lp);

最终,这取决于你。

答案 6 :(得分:1)

我可能会为每条消息声明一张地图并使用仿函数:

typedef std::map<UINT, boost::function<int (HWND, WPARAM, LPARAM) > > messageFuncs_t;
messageFuncs_t messageFuncs;

然后,当创建窗口类时,只需为每条消息添加一个新函数:

messageFuncs[WM_LBUTTONDOWN] = &onMouseDownEvent;

...然后实现消息循环:

messageFuncs_t::iterator fun = messageFuncs.find(msg);
if(fun != messageFuncs.end())
    return (*fun)(hWnd, wparam, lparam);
else
    return DefWindowProc(hWnd, msg, wp, lp);

......或者无论有什么用。然后很容易添加新消息,并将每个消息的工作委托给一个函数。干净,简洁,有道理。

答案 7 :(得分:0)

您错过了第一个案例中断。除此之外,我肯定会将该代码放在一个单独的函数上。

答案 8 :(得分:0)

没关系,但我一般不喜欢混合风格和缩进。如果我需要括起一个案例,我可能会将它们全部括起来并保持缩进一致。

另外bb是对的,在这种情况下你应该使用wchar_t数组而不是char。

答案 9 :(得分:0)

我正在编写相当多的Win32消息破解程序,例如这些交换机。

我的经验法则是:将行为连接到交换机,将行为转换为单独的功能。这通常意味着交换机包含是否应该处理此命令的决定(例如,测试发送者ID),以及“完善”参数。

所以在那种特殊情况下,一个单独的功能。

最初的动机是我经常在其他情况下触发行为(例如“当没有指定文件名并且moon参数设置为full时调用对话框,显示SaveAs对话框立即“)。