花了近3天的时间算是帮我老妈完成了一个电脑入门的小软件,由于她只是想上网查资料(她不懂怎样输入网址),于是就是简单地想把她平时需要浏览的网址收集到一块,存入数据库,然后在程序开启时读到列表控件中来,程序关闭时再重新写回数据库。开始以为一天就可以搞定,谁知越做就越多东西学。
当然,首先就是怎样去自动打开网址,这就用到了ShellExecute或者ShellExecuteEx在本程序中只是想打开网页,所以用ShellExecute就已经足够了。
HINSTANCE ShellExecute(
HWND hwnd,
LPCTSTR lpOperation,
LPCTSTR lpFile,
LPCTSTR lpParameters,
LPCTSTR lpDirectory,
INT nShowCmd
);
返回值:成功时返回一个大于32的值,失败时返回一个小于32的值。
hwnd: 用于指定父窗口句柄。当函数调用过程出现错误时,它将作为Windows消息窗口的父窗口。如果这个操作没有与窗口相关联,那么这个参数可以设为NULL。
lpOperation:用于指定要进行的操作,常用的有edit, explore find open print,如果这个参数设为NULL,那么默认的操作为open。
lpFile: 执行指定动作的文件或对象,为了能让Shell识别,这里需指定一个全路径,需注意的是一个对象并不是能够执行所有的动作。如,并不是所有的文档都能执行打印这个动作。
lpParameters: 如果lpFile指定的是一个可执行文件,那么该参数是一个指向传递给应用程序的参数的字符串,该串的格式由初调用的动词决定,此参数指定命令行参数。如果lpFile指向的是一个文档文件,那么该值需设为NULL。
lpDirectory: 用于指定默认目录。
nShowCmd:则此参数指定程序窗口的初始显示方式。
以下为常用的调用方式
1) 打开一个文件、文件夹
ShellExecute(this->m_hWnd,“open”,"e://1.doc",NULL,NULL,SW_NORMAL);
2) 打开一个网页
ShellExecute(this->m_hWnd,"open","www.baidu.com",NULL,NULL,SW_NORMAL);
3) 打开一个可执行文件
只是单纯的打开 ShellExecute(this->m_hWnd,“open”,"e://1.exe",NULL,NULL,SW_NORMAL);
在MSDN对参数lpParameters的解释中说该参数可以传递给可执行文件,开始我一直搞不懂应该如何传递,最后在网资料在发现上此参数指定命令行参数。所以做了如下测试。
#include<iostream>
using namespace std;
int main(int argc,char **argv)
{
for(int i=1;i<argc;i++)
{
cout<<argv[i];
}
cout<<endl;
getchar();
return 0;
}
可执行文件路径:e:/1.exe
在主程序中进行调用:
CString Parameters="xu zhi hong";
ShellExecute(this->m_hWnd,NULL,"e://1.exe",Parameters,NULL,SW_NORMAL)
执行可以在cmd看到 xuzhihong。
这个参数也可以传进图形用户界面,API函数GetCommandLine返回命令行的整个字符串,给图形界面提供了命令行的接口,虽然也提供了 CommandLineToArgvW来将命令行转化为标准C的argc 、argv形式,但我觉得没C的好用,因此我写了一个模拟的函数。
void CDlgDlg::GetCommandLineAndToArgv(int &argc,CStringArray &argv)
{
argc=0; argv.RemoveAll(); //初始化
CString commandLine=::GetCommandLine();
CString argument;
int pos,strLen;
pos=commandLine.ReverseFind(' ');
while(pos!=-1)
{
strLen=commandLine.GetLength();
argument=commandLine.Right(strLen-pos-1);
if(!argument.IsEmpty())
{
argc++;
argv.InsertAt(0,argument);
}
commandLine=commandLine.Left(pos);
pos=commandLine.ReverseFind(' ');
}
pos=commandLine.Find('/"'); //过滤掉" ",因为如果ShellExecute等函数调用时路径会掉" "
while(pos!=-1)
{
commandLine.Delete(pos);
pos=commandLine.Find('/"');
}
argc++;
argv.InsertAt(0,commandLine);
}
ShellExecute的lpParameters传进图形界面的例子
程序1:接收方,在OnInitDialog函数中调用下面的函数
函数Test() {
int argc;CStringArray argv; CString str;
GetCommandLineAndToArgv(argc,argv);
for(int i=1;i<argc;i++)
{ str+=argv[i]+" ";}
MessageBox(str);
}
发送方::ShellExecute(this->m_hWnd,"open","e://dlg//debug//dlg.exe"," xu zhi hong"
,NULL,SW_SHOW);
这时会弹出显示 xu zhi hong 的对话框
原来在VC中有__argc和__argv来作提供原来标准C的两个传入参数,那么上面的Test()函数进行修改
并且GetCommandLineAndToArgv函数可以不要。
Test() {
CString str,temp;
for(int i=1;i<__argc;i++)
{
temp=__argv[i];
str+=temp+" ";
}
MessageBox(str);
}
运行结果一样。
4)发送邮件
如果将FileName参数设置为“mailto:”协议格式,那么该函数将启动默认邮件客户程序,如Microsoft Outlook(也包括Microsoft Outlook Express)或Netscape Messanger。若用户机器中安装了多个邮件客户程序,则该函数将根据Windows 9x/NT注册表中mailto协议处理程序的设置确定启动哪个邮件客户程序。
格式:mailto:用户账号@邮件服务器地址?subject=邮件主题&body=邮件正文。
若指定多个收件人地址,则收件人地址之间必须用分号或逗号分隔开, 若邮件正文包括多行文本,则必须在每行文本之间加入换行转义字符%0A
ShellExecute(NULL,"open","mailto:who@mail.neu.edu.cn?subject=hello&body=this is a test%0Ahello",NULL,NULL,SW_SHOWNORMAL);