这个系列文章更多是针对初学者,宗旨是帮助初学者解决常见的应用开发问题。让文章有质量其实不是一件容易的事,至少得边研究边写作——写入门的也是,希望我的努力能对得起读者。后面的内容我会继续更新。
怎样提高解决问题的能力
------------------------------------------------------------------------------------------------------
解决问题的过程其实就是挑战自我的过程。你解决了你当前遇到的问题,你即超越了原来的你。 解决问题,超越自我的过程可能是痛苦的过程,但是成功时带来的喜悦和成就会带给你更多的满足。所以不要怕遇到问题。
那么当我们遇到问题时,怎样解决它?其实概括的说就两种方法,一个是从深度方面,一个是从广度方面。深度有助你看到问题的本质,广度有助你换另一种思维。比如仿生学,借助生物系统的结构和性质提供新的设计思想和原理。
也行你会遇到像熊力老师遇到那些莫名其妙的问题(见《Windows用户态程序高效排错》),我们大多数在工作中很少会遇到有非常挑战性的难题。我 们遇到的大多数问题其实只要稍微深入一下就能解决。作为刚做技术的初学者,总结和积累每一个遇到的问题的解决思路,把这些思路转化成能力,将会让你受益匪 浅。所以一遇到问题就问人并不是好习惯,也许你收获了一点知识,但你没有收获解决问题的能力。
解决问题不光靠知识,还要靠能力。关于知识和能力论述很有意思:“所谓知识能力,是指知识、智能、技能和实践及创新能力等。知识是人的认识能力的体现和结果,智能是知识转化为智慧的能力,技能是智慧在实际工作中的一种应用能力,实践及创新能力是以知识、智能、技能为基础的改造世界(对象)的能力。”
------------------------------------------------------------------------------------------------------
编写控制面板程序
------------------------------------------------------------------------------------------------------
控制面板应用程序是一个以cpl为后缀的文件(把项目生成的dll文件后缀改为cpl,或者从VS中修改配置直接生产cpl文件)。cpl文件中的 回调函数CPlApplet为ctlpnl.exe进程进入你的cpl的入口点(需要导出,不管你在def文件里面,还是在函数前制定dllexport 属性),一个cpl可以支持多个applets,见下面的代码中的注释。
LONG CPlApplet(
HWND hwndCPl, //Handle to the main window of the controlling application.
UINT msg, //Message being sent to the Control Panel application.
LPARAM lParam1,
LPARAM lParam2
);
msg有:
CPL_INIT
初始化,控制面板应用程序此时做一些全局的初始化工作,如内存分配。
CPL_GETCOUNT
获取控制面板应用程序支持的dialog boxes个数。
CPL_NEWINQUIRE
查询控制面板应用程序的dialog boxes的信息,信息包含在lParam2参数中,使用(LPNEWCPLINFO) lParam2获得指针。
typedef struct tagNEWCPLINFO {
DWORD dwSize;
DWORD dwFlags;
DWORD dwHelpContext;
LONG lData;
HICON hIcon; //Handle to the icon that represents the dialog box.
TCHAR szName[32]; //The name is intended to be displayed below the icon.
TCHAR szInfo[64]; //The description is intended to be displayed when the icon for the dialogbox is selected.
TCHAR szHelpFile[128]; //忽略。要想使用帮助,处理WM_NOTIFY消息,然后取
得“lppsn = (LPPSHNOTIFY) lParam;”判断是否等于PSN_HELP,如果是即可调出帮助文档。
} NEWCPLINFO;
CPL_IDNAME
获得控制面板应用程序的名称,通过设置注册表键值[HKEY_LOCAL_MACHINE\ControlPanel\
0 Personal
1 (default value) System
2 Connections
CPL_DBLCLK
当用户双击控制面板上的icon时,系统会发送这个消息给你的控制面部应用程序,此时你可以弹出一个dialog box。处理完这个消息之后返回0表示你成功处理这个消息了(其它消息也一样),非0表示其它。
CPL_STOP
关闭控制面部应用程序之前那一刻发送这个消息给你的控制面板应用程序。
CPL_EXIT
释放DLL文件之前那一刻发送这个消息给你的控制面板应用程序。
////////////////////////////////////////////////////////
// This is the entry point called by ctlpnl.exe
//
////////////////////////////////////////////////////////
extern "C"
__declspec(dllexport)
LONG WINAPI CPlApplet(HWND hwndCPL, UINT uMsg, LONG lParam1, LONG lParam2)
{
static int iInitCount = 0;
int iApplet;
switch (uMsg)
{
// First message sent. It is sent only once to
// allow the dll to initialize it's applet(s)
case CPL_INIT:
if (!iInitCount)
{
if (!InitApplet(hwndCPL))
return FALSE;
}
iInitCount++;
return TRUE;
// Second message sent. Return the count of applets supported
// by this dll
case CPL_GETCOUNT:
// Return the number of applets we support
return (LONG)((sizeof(SystemApplets))/(sizeof(SystemApplets[0])));
// Third message sent. Sent once for each applet supported by this dll.
// The lParam1 contains the number that indicates which applet this is
// for, from 0 to 1 less than the count of applets.
// lParam2 is a NEWCPLINFO that should be filled with information about
// this applet before returning
case CPL_NEWINQUIRE:
{
LPNEWCPLINFO lpNewCPlInfo;
lpNewCPlInfo = (LPNEWCPLINFO)lParam2;
iApplet = (int)lParam1;
lpNewCPlInfo->dwSize = (DWORD)sizeof(NEWCPLINFO);
lpNewCPlInfo->dwFlags = 0;
lpNewCPlInfo->dwHelpContext = 0;
lpNewCPlInfo->lData = SystemApplets[iApplet].icon;
lpNewCPlInfo->hIcon =
LoadIcon(g_hInstance,
(LPCTSTR)MAKEINTRESOURCE(SystemApplets[iApplet].icon));
lpNewCPlInfo->szHelpFile[0] = '\0';
LoadString(g_hInstance,SystemApplets[iApplet].namestring,
lpNewCPlInfo->szName,32);
LoadString(g_hInstance,SystemApplets[iApplet].descstring,
lpNewCPlInfo->szInfo,64);
}
break;
// This is sent whenever the user clicks an icon in Settings for one of
// the applets supported by this dll. lParam1 contains the number indicating
// which applet. Return 0 if applet successfully launched, non-zero otherwise
case CPL_DBLCLK:
iApplet = (UINT)lParam1;
if (!CreatePropertySheet(hwndCPL,iApplet))
return 1;
break;
// Sent once per applet, before CPL_EXIT
case CPL_STOP:
break;
// Sent once before the dll is unloaded
case CPL_EXIT:
iInitCount--;
if (!iInitCount)
TermApplet();
break;
default:
break;
}
return 0;
}
更详细的代码请见例子\Samples\PocketPC\CPP\win32\myBackLight,或者点这里下载。
关于任何调试cpl代码,请参照下面的文章。
------------------------------------------------------------------------------------------------------
智能设备安装包制作过程
------------------------------------------------------------------------------------------------------
首先新建一个Win32项目,想把一个EXE文件打包,DLL文件、或者空文件(比如仅仅想修改目标设备的注册表)打包过程都是一样的:
现在在原来的项目上添加一个智能设备CAB项目:
文件系统中选择需要将你的EXE或者DLL文件放到目标设备的哪个文件夹上。如果需要在目标设备“Program Files”文件夹上再新建个文件夹,则在“Program Files”上右击添加文件夹: ![]()
这里我们想把项目生成的EXE程序放到Windows文件夹上,则删除“Program Files文件夹”,新建个“Windows文件夹”,并在上面添加项目输出:
我们现在不光要把EXE文件添加到目标设备,还要修改目标设备的注册表,现在先切换到注册表试图:
可以新建,可以导入(导入现有的REG文件,一般是从模拟器中的注册表保存得到的):
我常习惯直接修改CAB的项目配置文件,此处注意这个文件只支持ASCII码,当里面有汉字时(当你的机器名是中文时,或者前面的添加注册表键值时可能造成),编译时会出错,提示Unicode转换ASCII码错误:
这里就是从注册表试图中添加的配置信息:
OK,下面点击生成吧。在开发中,如果我们想看DLL运行时的效果时,常常需要这样制作CAB包。 ![]()
下面介绍的是如何在“程序”中添加快捷方式:
将\windows\start
menu\programs下的一个快捷方式拷贝到PC上修改成:21#MyApplication.exe,修改完毕后,保存,并把此快捷方式改名,拷
贝到手机的\windows\start
menu(“开始”菜单)\programs(程序)目录下。将MyApplication.exe拷贝到Windows目录下,此时你就会发现
Program下有你的应用程序了。这些操作可以使用上面介绍的CAB包实现。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/21255398/viewspace-606467/ ,如需转载,请注明出处,否则将追究法律责任。