C++ Switch语句的使用

C++ Switch语句的使用,c++,c,windows,winapi,C++,C,Windows,Winapi,我是否应该使用这种形式的switch语句: switch(msg) { case WM_LBUTTONDOWN: { char szFileName[MAX_PATH]; HINSTANCE hInstance = GetModuleHandle(NULL); GetModuleFileName(hInstance, (LPWCH)szFileName, MAX_PATH); Mess

我是否应该使用这种形式的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;

或者为第一个案例设置一个函数常量?

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

如何使用它没有问题,但调用函数可能更干净,这样可以保持函数的合理大小。

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

好吧,这将取决于你还有多少其他案例


像那个样小的东西,我会说它不值得让它成为一个函数,但若您的switch语句包含更多的case,它就会变得丑陋,特别是当很多case都有多行这样的代码时。把它放到函数中会使它更干净,使代码看起来更漂亮。

我想说的最重要的事情之一是一致性。如果您为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);

最后,这真的取决于你。

当你收到20或50条窗口消息时,你会怎么做?
也许是在函数(函数)上创建映射事件并调用它们的时候了?
或者开始使用规则-一条消息=一次函数调用。


你能用Convertation(LPCWSTR)szFileName解释一下这个奇怪的把戏吗。为什么不使用数组wchar\t来代替强制转换长路径(路径长度>最大路径/sizeof(wchar\u t))会有很大的问题


一个建议-避免在一般情况下使用强制类型转换,在特殊情况下使用C样式强制类型转换。

这很好,但我通常不喜欢混合样式和缩进。如果我需要用括号括起一个案例,我可能会把它们都括起来,并保持缩进的一致性


同样,bb是正确的,在这种情况下,您应该使用wchar\u t数组而不是char。

另外,请看一看

我可能会声明一个映射,并对每条消息使用函子:

typedef std::map<UINT, boost::function<int (HWND, WPARAM, LPARAM) > > messageFuncs_t;
messageFuncs_t messageFuncs;
。。。然后实现消息循环,如下所示:

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

。。。或者任何有用的东西。然后添加新消息就很容易了,每个消息的工作都委托给一个函数。干净、简洁、有意义。

我正在编写相当多的Win32消息破解程序,比如这些开关

我的经验法则是:将行为连接到开关中,将行为连接到单独的函数中。这通常意味着开关包含是否应处理此命令的决定(例如,测试发送者ID)和“预类型化”参数

所以在那个特殊的情况下,一个单独的函数


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

中断在结束括号之后。如果您的案例变大,开关/外壳(有时)可能更有效。我记得当我编写6510仿真器时,操作码解码器一开始是一个IF语句(我很年轻)。很慢。使用case语句生成了一个跳转表,而且速度更快!来自CodeComplete的Steve Mcconnell从两个方面测试了这一点,有时case语句更快,有时if-else构造更快。有时没有区别。所以,在出现性能问题之前不要担心,然后重新配置、更改和配置。他确实有一个休息,但这是在大括号之外。使它难以阅读。此外,缩进会影响可读性。可读性是创建函数的另一个好处,前提是他能想出一个好的函数名。中断是在Brian发布他的解决方案之后设置的。我倾向于将中断放在右括号之后。不知道为什么,也许是作为一个“无论你做什么,别忘了打破”的提醒(对我自己)。不要将char(szFileName)强制转换到WCHARs(在那里你把它传递到MessageBox)。这会导致不好的事情发生!同意@jeff,请将szFileName声明为“WCHAR szFileName[MAX_PATH];”如果你想麻烦地找到消息,没有理由做第二次查找(操作符[])来调用它。另外,您在boost::function中使用了指向函数的指针语法,这是不必要的(即使使用实际的函数指针),我很确定这不会起作用。我很快就把它拼凑起来了,没有费心查阅文档。我会修复它。或者C++等价的:ATL的CWELL类。您窗口的cpp文件看起来非常干净。
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);