下一个目标是添加菜单,这样就能加入about信息。有可能的话进一步做一个自定义操作键的设置框,还可以把联网相关操作也做进去。另外顺便把图标和光标一并弄了。
之前由于我的见识有限,以为菜单要学MFC才能弄。另外对如何把所有文件打包成一个exe也有些疑惑。其实只要看完windows编程关于“资源”的章节,就知道这些都能靠IDE的资源脚本轻松实现。
十几年过去了,vs2008和教材上传授的古老方法略有变化:
1,图标
现在的系统支持更大的图标。可以在添加完图标资源后,再添加新的图标类型并删去其他类型,这样系统会在需要图标时都使用这种,不用每种规格大小都做一个了。
注意右方颜色栏可以很方便的取到透明色。
用各种图片编辑软件调整好图案大小,用画图copy进vs就行了。
2,鼠标光标
添加采取同样方式,一定要记得在建windows窗口时load。
注意工具栏上有个“设置作用点工具”,这个必然就是用来指定鼠标的点击点的了。
3,菜单
制作也挺方便,添加菜单资源,然后在可视化界面下编辑好编译下就可以用了,注意编译完貌似没办法再次取出来可视化编辑,想修改就只能手工改脚本文件了。
(2013.8.12注:不可能没办法二次可视化编辑的,IDE里留心找找就知道怎么弄了)
做对话框就没那么容易了。
虽然也可以直接添加资源,然后将各种控件拖进去完事,但是要获取控件里的信息、甚至要对控件进行一些自定义设置,就要对windows的窗口机制有更深的理解。
一开始我试着在百度上搜过一些如何自定义控件之类的信息,但是大部分都是讲派生MFC类的,没有基本的认识根本看不懂。而且要在win32程序中夹杂使用MFC真是很麻烦,头文件重复包含问题一时较难解决。
反复的看《windows程序设计》第九章子窗口控件以及第十一章对话框后,我发现不依赖MFC仅使用win32 API是完全可以达到目的的。
对话框上的各种子控件产生的消息,会发到对话框过程函数处理,然后在对话框过程函数里,也可以对子控件发送消息来影响和控制子控件的表现。
这个大概就是核心思想了。
具体我们想实现的操作,各种教材里的例子不可能面面俱到,所以需要在MSDN库里查阅相关资料。
比如我想实现以前在游戏模拟器中看到的那种自定义操作键时,点一下输入框,字母就消失,然后只允许输入一个字母的功能。
一开始我以为要对EDIT控件进行修改,就是要用到窗口子类、SetWindowLong什么的。
后来,发现edit控件的消息里头,有EM_SETLIMITTEXT,可以对文本字数进行限制,这样问题似乎就简单了许多。
不管怎样,先试下到底能不能在DlgProc里接收到EDIT发来的消息,并发送消息控制EDIT。
简单的在对话框上加两个edit。试着实现点击edit,则文本自动显示为“A”。
一开始DlgProc是这样写的:
int CALLBACK DlgProc( HWND hDlg,UINT message, WPARAM wParam,LPARAM lParam) { switch( message) { case WM_INITDIALOG: return TRUE; case WM_COMMAND: switch( LOWORD(wParam)) { case IDC_EDIT1: if( HIWORD(wParam) == EN_SETFOCUS) { SendMessage(GetDlgItem(hDlg,IDC_EDIT1),WM_SETTEXT,NULL,(LPARAM)"A"); //return TRUE; } //break; case IDOK: case IDCANCEL: EndDialog(hDlg,0); return TRUE; } break; } return FALSE; }
这样就闹了个天大的笑话,实际会发现每次点击edit1后对话框都会退出。
“如果case语句后面没有break语句,程序将继续执行下一条case语句。虽然有时候需要这样做,但通常是错误。如果需要让程序继续向下执行,请用注释来指出您并非忘记了使用break语句。”
——《21天学通C++》 113页
也不能怪谭哥的书没讲出这重要的一点吧,也许是我没注意看。总之还是要多实践,才能打牢基础。
另外注意:
“当对话框过程处理一条消息时,它会返回TRUE,而当它不处理一条消息时,返回FALSE。”
——《windows程序设计》 392页
所以这里还要添加一个return。
去掉两个注释符就是正确的代码。
还有个问题需要说下。
对switch(message)做一些规范化处理,加上所有break及default。
发现在最后加上default:return TRUE;break;后,对话框绘制会出问题,改为return FALSE就正常了。
这个我暂时怀疑是return TRUE会导致一些DlgProc未处理的消息无法传递到上级过程,导致异常。
接下来正式开始做对话框控件功能,以实现自定义操作键。