荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: Second (石开), 信区: Program
标  题: 应 用 进 程 实 现 对 其 他 应 用 程 序 的 调 用
发信站: 荔园晨风BBS站 (Wed Jun  6 07:22:41 2001), 转信

在 我 们 设 计 的 应 用 程 序 中, 很 可 能 会 用 到 其 他 应 用 程 序 来 完
成 某 一 特 定 功 能。 例 如, 当 我 们 为 了 便 于 数 据 的 传 输 而 对 诸
多 文 件 进 行 压 缩 和 解 压 缩 时, 一 种 作 法 是 我 们 自 己 设 计 一 个
这 样 的 压 缩/ 解 压 缩 程 序, 然 后 以 动 态 链 接 库(DLL) 或 者 函 数 库
的 形 式 由 主 应 用 程 序 调 用。 但 更 方 便 而 且 高 效 的 作 法 是 利 用
现 有 的 这 方 面 的 优 秀 软 件, 比 如ARJ.EXE, 并 以 进 程 的 形 式 调 用
它, 再 在 适 当 时 候 关 闭 它。 下 面 将 以 上 面 所 述 为 例, 具 体 介
绍 后 一 种 方 法 的 实 现 过 程。

在 需 要 调 用ARJ.EXE 进 行 压 缩/ 解 压 缩 的 类 中, 创 建 一 个 成 员 函
数, 不 妨 称 作CreateBat(), 其 作 用 是 生 成 一 个 批 处 理 文 件。 由 该
 批 处 理 文 件 调 用ARJ.EXE, 并 给 出 具 体 压 缩/ 解 压 缩 参 数。 之 后,
 再 利 用MS-DOS 的DIR 命 令 生 成 一 个 临 时 文 件, 以 作 为 压 缩/ 解 压
缩 工 作 完 成 的 标 志。
void CMyCompress:: CreateBat(CString BatPath,CString ArjPath,
CString BatName,CString ArjFileName,
CString TempPath,CString ExitFlag,BOOL out)
{
LPTSTR lpBuffer;
UINT uSize;
HANDLE hHeap;
uSize=(GetCurrentDirectory(0,NULL))*sizeof(TCHAR);
hHeap=GetProcessHeap();
lpBuffer=(LPSTR)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,uSize);
GetCurrentDirectory(uSize,lpBuffer);
//得知当前目录信息,以便根据需要变换目录
if (lpBuffer!=BatPath) //diferent dir
SetCurrentDirectory(BatPath);
CStdioFile f;
CFileException e;
if (!f.Open( BatName, CFile::modeCreate|CFile::modeWrite, &e))
//以BatName的内容创建一个批处理文件
{
AfxMessageBox("不能创建文件"+BatName);
return ;
}
char density[6];
sprintf(density,"%d",mTotalBytes);
---- //mTotalBytes 是 由 其 他 函 数 设 定 的 变 量, 用 于 记 录 用 于 拷 入
 或 拷 出 文 件 的 磁 盘 所 具 有 的 最 大 可 用 空 间
CString Density=density;
CString string;
if (out)//说明是生成做压缩工作的批处理文件
string="arj a -v"+Density;
else //说明是生成做解压缩工作的批处理文件
string="arj e -v"+Density;
string+=" ..\\"+ArjPath+"\\"+ArjFileName+" ";
if (out)
string=string+"..\\"+TempPath+"\\*.* -y -jm\n";
else
string=string+"..\\"+TempPath+"\\ -y -jm\n";
f.WriteString(string);
string="dir >"+ExitFlag+"\n";
f.WriteString(string);
f.Close();
SetCurrentDirectory(lpBuffer);//回复到原来的目录下
}
---- 该 函 数 执 行 后, 将 生 成 一 个 批 处 理 文 件, 内 容 大 致 是:
---- ARJ A -V1440 压 缩 后 文 件 的 路 径 名+ 文 件 名 被 压 缩 文 件 的 路
径 名+ 文 件 名 -Y -JM
---- DIR > 临 时 文 件 名
---- 或 者 是:
---- ARJ E -V1440 被 解 压 缩 文 件 的 路 径 名+ 文 件 名 解 压 缩 后 文 件
的 路 径 名+ 文 件 名 -Y -JM
---- DIR > 临 时 文 件 名
在 需 要 调 用ARJ.EXE 进 行 压 缩/ 解 压 缩 的 类 中, 再 创 建 一 个 成 员
函 数, 不 妨 称 作RunBat(), 其 作 用 是 创 建 和 执 行 进 程 来 运 行 上 述
 所 生 成 的 批 处 理 文 件, 并 在 适 当 时 候 撤 消 进 程。
void CMyCompress::RunBat(CString
BatPath,CString fileName,CString ExitFlag)
{
CString lpApplicationName=BatPath+"\\"+fileName;
// 进 程 执 行 的 应 用 程 序 的 完 全 路 径 名
STARTUPINFO StartupInfo;// 创 建 进 程 所 需 的 信 息 结 构 变 量
GetStartupInfo(&StartupInfo);
StartupInfo.lpReserved=NULL;
StartupInfo.lpDesktop=NULL;
StartupInfo.lpTitle=NULL;
StartupInfo.dwX=0;
StartupInfo.dwY=0;
StartupInfo.dwXSize=200;
StartupInfo.dwYSize=300;
StartupInfo.dwXCountChars=500;
StartupInfo.dwYCountChars=500;
StartupInfo.dwFlags=STARTF_USESHOWWINDOW;
StartupInfo.wShowWindow=SW_HIDE;
// 说 明 进 程 将 以 隐 藏 的 方 式 在 后 台 执 行
StartupInfo.cbReserved2=0;
StartupInfo.lpReserved2=NULL;
StartupInfo.hStdInput=stdin;
StartupInfo.hStdOutput=stdout;
StartupInfo.hStdError=stderr;
LPTSTR lpBuffer;
UINT uSize;
HANDLE hHeap;
uSize=(GetCurrentDirectory(0,NULL))*sizeof(TCHAR);
hHeap=GetProcessHeap();
lpBuffer=(LPSTR)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,uSize);
GetCurrentDirectory(uSize,lpBuffer);
// 得 知 当 前 目 录 信 息, 以 便 根 据 需 要 变 换 目 录
if (lpBuffer!=BatPath) //diferent dir
SetCurrentDirectory(BatPath);
// 创 建 进 程
if (CreateProcess(lpApplicationName,NULL,NULL,
NULL,FALSE,CREATE_DEFAULT_ERROR_MODE,
NULL,NULL,&StartupInfo,&pro_info))
{
MSG Message;
DeleteFile(ExitFlag);
SetTimer(1,100,NULL);// 设 置 计 时 器
Search=TRUE;
while(Search) {
if (::PeekMessage(&Message,NULL,0,0,PM_REMOVE)) {
::TranslateMessage(&Message);
::DispatchMessage(&Message);
}
}
// 进 程 结 束 前 后 的 处 理 工 作
DWORDExitCode;
if (!GetExitCodeProcess(pro_info.hProcess,&ExitCode))
AfxMessageBox("GetExitCodeProcess is Failed!");
if (!Te
rminateProcess(pro_info.hProcess,(UINT)ExitCode))
                    // 终 止 进 程
  AfxMessageBox("TerminateProcess is Failed!");
 if (!CloseHandle(pro_info.hProcess))
                   // 释 放 被 终 止 进 程 的 句 柄
  AfxMessageBox("CloseHandle is Failed!");
 KillTimer(1);// 撤 消 计 时 器
 }
 else AfxMessageBox("Process Is Not Created!");
 SetCurrentDirectory(lpBuffer);// 回 复 到 原 来 的 目 录 下
}
同 时 按 下Ctrl 和W 键 或 直 接 单 击 工 具 条 上 的ClassWizard 按 钮, 打 开
ClassWizard 对 话 框。 在 类 名(Class name) 列 表 框 中 选 择 需 要 调 用ARJ
.EXE 进 行 压 缩/ 解 压 缩 的 类, 在Object IDs 列 表 框 中 选 择 该 类 的 类
 名 后, 在 消 息(Messages) 列 表 框 中 选 择WM_TIMER 消 息 并 双 击 它, 这
 时ClassWizard 就 会 在 该 类 中 加 入 一 个OnTimer() 函 数。 该 函 数 将 以
 一 定 的 时 间 间 隔 检 查 压 缩/ 解 压 缩 程 序 是 否 已 经 执 行 完 毕,
即 检 查 作 为 标 志 的 临 时 文 件 是 否 已 经 存 在, 并 及 时 修 改 状 态
 变 量“Search”, 以 便 通 知RunBat() 函 数 结 束 进 程。
void CMyCompress::OnTimer(UINT nIDEvent)
{
 // TODO: Add your message handler code here and/or call default
 CFile file;
 CFileException Error;
 if (file.Open(ExitFlag,CFile::modeRead,&Error)) {
  Search=FALSE;
  file.Close();
 }
}

--
                            既然热爱生命
                            那么,
                            一切都在意料之中。

※ 来源:·荔园晨风BBS站 bbs.szu.edu.cn·[FROM: 192.168.28.190]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店