C++ Switch语句的使用
我是否应该使用这种形式的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(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);