1实验步骤.docx
- 文档编号:10613283
- 上传时间:2023-02-21
- 格式:DOCX
- 页数:20
- 大小:414.36KB
1实验步骤.docx
《1实验步骤.docx》由会员分享,可在线阅读,更多相关《1实验步骤.docx(20页珍藏版)》请在冰豆网上搜索。
1实验步骤
实验一 使用EVC编程实现“进程列举并管理”
1.实验目的:
1.熟悉WINCE嵌入式系统应用程序集成开发工具EVC4.0(EmbeddedVisualC++4.0);
2.熟悉ToolHelp中在实现”进程列举并管理”用到的API使用方法;
3.掌握EVC4.0开发嵌入式应用程序的基本方法;
4.掌握进程创建和终止的基本方法。
2.实验任务:
1.使用CreateProcess函数创建一个进程;
2.编程实现“进程列举并管理”
●使用EVC代码编辑器,编程实现得到CE系统运行的任务列表的方法;
●使用EVC代码编辑器,编程实现得到任务的主窗体标题和句柄的方法;
●使用EVC代码编辑器,编程实现激活进程和终止进程的方法;
●在对话框窗口,添加控件并设置属性,编程实现进程列表控件的初始化和按钮单击事件的代码。
3.实验步骤:
1)使用CreateProcess函数创建一个进程
1.使用EVC向导(File->New)新建一个项目,在Projects选项卡选择“WCEPocketPC2003MFCAppWizard(exe)”项,在右侧的Projcecname和Location输入栏中分别输入项目的名称和项目的存储路径,如图1所示,这里项目名称设为CreateProcess。
图1新建项目对话框
输入项目名和路径后,单击OK按钮,进入如图2所示的向导界面的第一步。
在该界面中的应用程序类型中选择Dialogbased(对话框类型),单击Next按钮,进入向导的第2步。
在该界面中输入应用程序的标题,我们直接按照默认操作完成向导即可。
图2向导界面1
2.设置工具栏如下图3所示
图3工具栏(用于设置工程名\SDK\编译类型\目标机器)
3.编写“调用可执行文件”函数。
我们可以自主为CreateProcessDialog类添加 私有函数,用来调用可执行文件,具体操作如下:
a.)函数的创建。
首先在工作区(WorkSpace)点击“ClassView”标签,选中CCreateProcessDlg类,右击,在弹出的快捷菜单中选择AddMemberFunction…项,打开AddMemberFunction对话框。
然后在该对话框中的
FunctionType输入栏中输入bool类型,在FunctionDeclaration输入栏中输入WinExec(LPCTSTRFileName),在Access框中选择Private类型,如图4所示。
在完成以上操作后,只需要单击OK按钮,便完成了此函数的创建。
图4AddMemberFunction对话框
b.)函数的实现。
该函数的具体实现如下,添加到CreateProcessDlg.cpp中:
/*
*函数描述:
调用可执行文件
*入口参数:
FileName:
字符串,用于指定可执行文件名
*出口参数:
(无)
*返回值:
true:
代表调用成功;false:
代表调用失败
*/
boolCCreateProcessDlg:
:
WinExec(LPCTSTRFileName)
{
PROCESS_INFORMATIONprocessInfo;//进程相关信息
if(!
CreateProcess(FileName,NULL,NULL,NULL,NULL
CREATE_NEW_CONSOLE
NULL,NULL,NULL,&processInfo))
{
returnfalse;
}
CloseHandle(processInfo.hThread);
CloseHandle(processInfo.hProcess);
returntrue;
}
4.首先在工作区(WorkSpace)点“ResourceView”标签,双击打开对话框窗体(IDD_CREATEPROCESS_DIALOG),在窗体上添加一个按钮,其ID设为IDC_BTNEXEC,标题(Caption)设为”Open”,如图5。
图5添加”Open”按钮后的对话框窗体
在对话框窗体上直接双击按钮,EVC便会自动创建它的单击方法声明。
其中”Open”按钮的单击事件实现代码如下:
voidCCreateProcessDlg:
:
OnBtnexec()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
//打开时钟程序
WinExec(_T("clock"));
}
5.击工具栏上的图标
,编译生成可执行文件,此时模拟器被激活。
点击图标
,运行CreateProcess.exe,可以看到程序在模拟器中运行如图6。
图6打开时钟小程序
2)编程实现“进程列举并管理”
1.使用EVC向导(File->New)新建一个项目,在Projects选项卡选择“WCEPocketPC2003MFCAppWizard(exe)”项,在右侧的Projcecname和Location输入栏中分别输入项目的名称和项目的存储路径,这里项目名称设为TaskList。
输入项目名和路径后,单击OK按钮,进入向导界面的第一步。
在该界面中的应用程序类型中选择Dialogbased(对话框类型),单击Next按钮,进入向导的第2步。
在该界面中输入应用程序的标题,我们直接按照默认操作完成向导即可。
2.设置工具栏如下图7所示
图7工具栏(用于设置工程名\SDK\编译类型\目标机器)
3.定义本例中所用到的常量、结构体及变量
在工程工作区(WorkSpace)打开头文件TaskListDlg.h(在fileView标签中),在“classCTaskListDlg:
publicCdialog”添加如下代码:
//定义用到的常量
#defineTITLE_SIZE64//标题字符串的大小
#definePROCESS_SIZEMAX_PATH//进程名字符串的大小
#defineMAX_TASKS25//最大进程数
//定义进程信息结构
typedefstruct_TASK_LIST{
DWORDdwProcessId;//进程标识
DWORDcntThreads;//此进程中的线程数
HWNDhwnd;//进程主窗口句柄
TCHARProcessName[PROCESS_SIZE];//进程Exe文件名
TCHARWindowTitle[TITLE_SIZE];//主窗口标题名
}TASK_LIST,*PTASK_LIST;
//定义进程信息列表结构
typedefstruct_TASK_LIST_ENUM{
PTASK_LISTtlist;//进程信息列表
DWORDnumtasks;//进程数
}TASK_LIST_ENUM,*PTASK_LIST_ENUM;
有了上面的定义后,便可以定义类CtaskListDlg的私有成员变量(g_tlist)了,在头文件TaskListDlg.h中,添加代码如下:
private:
//定义存储进程信息结构体数组
TASK_LISTg_tlist[MAX_TASKS];
4.添加需要用到的头文件,具体操作为:
打开StdAfx.h文件,添加如下代码:
#include
然后打开projectsettings(项目属性设置)窗口,切换到Link选项卡下,设置连接的库文件toolhelp.lib,也就是在Object/librarymodules输入栏中输入toolhelp.lib,如下图8所示。
图8 设置连接库文件窗口
5.为CtaskListDlg类添加静态函数GetTaskListCE,用于得到CE系统运行的任务列表,它的访问权限为Public。
a)首先,在头文件TaskListDlg.h中,加入GetTaskListCE函数的声明如下:
staticDWORDGetTaskListCE(PTASK_LISTpList);
●然后,将下面的代码添加到原文件TaskListDlg.cpp中。
GetTaskListCE函数的具体实现代码如下:
/*
*函数介绍:
得到CE系统中运行的任务列表
*入口参数:
(无)
*出口参数:
pList:
存储得到任务列表信息
*返回值:
返回得到的任务数
*/
DWORDCTaskListDlg:
:
GetTaskListCE(PTASK_LISTpList){
HINSTANCEhKernel=NULL;
HINSTANCEhProcessSnap=NULL;
PROCESSENTRY32pe32={0};
DWORDdwTaskCount=0;
//状态toolhelp.dll动态连接库
hKernel=LoadLibrary(_T("toolhelp.dll"));
if(!
hKernel){
:
:
MessageBox(NULL,L"Toolhelp.dll加载失败",L"进程列举",MB_OK);
return0;
}
//创建进程映射
hProcessSnap=(HINSTANCE)CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
//如果失败,就退出
if(hProcessSnap==(HANDLE)-1)
return0;
dwTaskCount=0;
//设置保存进程相关内容的变量的结构大小
pe32.dwSize=sizeof(PROCESSENTRY32);
//获取第一个进程,并将此进程信息写入进程结构的变量pe32中
if(Process32First(hProcessSnap,&pe32)){
do{
LPTSTRpCurChar;
if(_tcsstr(pe32.szExeFile,L"\\"))
pCurChar=_tcsrchr(pe32.szExeFile,'\\');
else
pCurChar=pe32.szExeFile;
lstrcpy(pList->ProcessName,pCurChar);
pList->dwProcessId=pe32.th32ProcessID;
pList->cntThreads=tThreads;
++dwTaskCount;//进程数目加1
++pList;//移到下一个结构内存块
}
while(Process32Next(hProcessSnap,&pe32));//移至下一个进程
}
else
dwTaskCount=0;//
CloseHandle(hProcessSnap);
returndwTaskCount;
}
6.为CtaskListDlg类添加静态函数GetWindowTitles,用于得到任务的主窗体标题和句柄,它的访问权限为Public。
a)首先,在头文件TaskListDlg.h中,加入GetWindowTitles函数的声明如下:
staticvoidGetWindowTitles(PTASK_LIST_ENUMpe);
staticBOOLCALLBACKEnumWindowsProc(HWNDhwnd,DWORDlParam);
说明:
在GetWindowTitles函数里,我们使用了EnumWindows函数来列举窗体,EnumWindows利用回调函数(EnumWindowsProc)作为输入参数。
在这里也将EnumWindowsProc函数定义为静态函数,访问权限设为Protected。
●然后,将下面的代码添加到原文件TaskListDlg.cpp中。
GetWindowTitles函数的具体实现代码如下:
/*
*函数介绍:
回调函数,被EnumWindows调用
*入口参数:
hwnd:
窗体句柄
*lParam:
进程信息列表指针
*出口参数:
lParam:
进程信息列表指针
*返回值:
True代表成功,False代表失败
*/
BOOLCALLBACKCTaskListDlg:
:
EnumWindowsProc(HWNDhwnd,DWORDlParam){
DWORDpid=0;
DWORDi;
TCHARbuf[TITLE_SIZE];
PTASK_LIST_ENUMte=(PTASK_LIST_ENUM)lParam;
PTASK_LISTtlist=te->tlist;
DWORDnumTasks=te->numtasks;
//根据窗口句柄,得到进程标识
if(!
GetWindowThreadProcessId(hwnd,&pid)){
returnTRUE;
}
//查找进程标识和列表中相同的进程标识
for(i=0;i if(tlist[i].dwProcessId==pid){ if(: : IsWindowVisible(hwnd)){ tlist[i].hwnd=hwnd; intnCnt=: : GetWindowText(hwnd,buf,TITLE_SIZE); buf[nCnt]='\0'; if(nCnt){ lstrcpy(tlist[i].WindowTitle,buf); } } break; } } //继续列举窗体 returnTRUE; } /* *函数介绍: 得到任务的主窗体标题和句柄 *入口参数: te: 进程信息列表指针 *出口参数: te: 进程信息列表指针 *返回值: (无) */ voidCTaskListDlg: : GetWindowTitles(PTASK_LIST_ENUMte){ //列举系统所有窗体 EnumWindows((WNDENUMPROC)EnumWindowsProc,(LPARAM)te); } 7.为CtaskListDlg类添加两个私有方法ActivateProcess和KillProcess,分别用于激活进程和终止进程,它们的访问权限为Private。 a)首先,在头文件TaskListDlg.h中,加入ActivateProcess和KillProcess函数的声明如下: private: boolActivateProcess(PTASK_LISTtlist); boolKillProcess(PTASK_LISTtlist); ●然后,将下面的代码添加到原文件TaskListDlg.cpp中。 ActivateProcess和KillProcess函数的具体实现代码如下: /* *函数介绍: 激活进程方法 *入口参数: tlist: 进程信息 *出口参数: (无) *返回值: True: 成功;False: 失败 */ boolCTaskListDlg: : ActivateProcess(PTASK_LISTtlist) { //判断是否存在主窗口,如存在就激活它 if(tlist->hwnd&&tlist->WindowTitle) { : : SetForegroundWindow(tlist->hwnd); : : SetActiveWindow(tlist->hwnd); returnTRUE; } else { returnFALSE; } } /* *函数介绍: 终止进程方法 *入口参数: tlist: 进程信息 *出口参数: (无) *返回值: True: 成功;False: 失败 */ boolCTaskListDlg: : KillProcess(PTASK_LISTtlist) { HANDLEhProcess; //如果没有主窗体,则用TerminateProcess终止进程 if(! tlist->hwnd) { //根据进程标识,返回进程句柄 hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,tlist->dwProcessId); //成功的话,终止进程 if(hProcess) { if(! TerminateProcess(hProcess,1)) { CloseHandle(hProcess); returnFALSE; } CloseHandle(hProcess); returnTRUE; } else { returnFALSE; } } //有主窗体,发送主窗口关闭消息,终止线程 else { : : PostMessage(tlist->hwnd,WM_CLOSE,0,0); returnTRUE; } } 8.设置对话框窗体控件。 在工程工作区(WorkSpace)找到对话框窗体,如下图9,双击打开,在右侧编辑区显示如图10。 图9 对话框窗体位置 图10对话框窗体控件和控件工具栏(控件工具栏可在菜单Tool|Customize可以打开) ●在对话框窗体删除”Statictext”控件 ●添加”ListControl”控件(窗体中的列表框用于显示系统中的进程信息列表),在控件上右键单击打开”ListControlProperties”对话框,在”General”选项卡将其ID属性设置为IDC_LISTPROCESS;在”Styles”选项卡将其View属性设为Report样式,并且选中SingleSelection属性,最后调整进程列表框的大小以适应窗体的位置。 ●除了在窗体放置进程列表框外,还需要在窗体上放置三个按钮: 第一个按钮的标题(Caption)设为”Active”,其ID设为IDC_BTNACTIVE,用于激活已选中的进程; 第二个按钮的标题(Caption)设为”Terminate”,其ID设为IDC_BTNTERMINATE,用于终止已选中的进程; 第三个按钮的标题(Caption)设为”Refresh”,其ID设为IDC_BTNREFRESH,用于获得最新的系统进程列表信息; 添加控件后如图11所示。 图11列举进程并管理实例样式 9.初始化进程列表控件并设置进程列表标题 在CtaskListDlg类的OnInitDialog()方法中添加初始化进程列表控件的代码,也就是在方法的末尾returnTRUE语句之前添加如下代码: //设置进程列表框标题 CListCtrl*pListCtrl=(CListCtrl*)GetDlgItem(IDC_LISTPROCESS); CRectrt; pListCtrl->GetClientRect(&rt); pListCtrl->InsertColumn(0,_T("Name"),LVCFMT_LEFT,rt.Width()*0.35); pListCtrl->InsertColumn(1,_T("Caption"),LVCFMT_LEFT,rt.Width()*0.35); pListCtrl->InsertColumn(2,_T("CntThr"),LVCFMT_LEFT,rt.Width()*0.30); 10.添加”Active”、”Terminate”、”Refresh”三个按钮的单击事件实现代码。 在对话框窗体上直接双击按钮,EVC便会自动创建它的单击方法声明。 其中”Active”按钮的单击事件实现代码如下: /* *函数介绍: 激活进程按钮单击事件 *入口参数: (无) *出口参数: (无) *返回值: (无) */ voidCTaskListDlg: : OnBtnactive() { CListCtrl*pListCtrl=(CListCtrl*)GetDlgItem(IDC_LISTPROCESS); POSITIONpos=pListCtrl->GetFirstSelectedItemPosition(); if(pos) { intnItemIndex=pListCtrl->GetNextSelectedItem(pos); //激活进程 ActivateProcess(&g_tlist[nItemIndex]); } } ”Terminate”按钮的单击事件实现代码如下: /* *函数介绍: 终止进程按钮单击事件 *入口参数: (无) *出口参数: (无) *返回值: (无) */ voidCTaskListDlg: : OnBtnterminate() { CListCtrl*pListCtrl=(CListCtrl*)GetDlgItem(IDC_LISTPROCESS); POSITIONpos=pListCtrl->GetFirstSelectedItemPosition(); if(pos) { intnItemIndex=pListCtrl->GetNextSelectedItem(pos); //终止进程 KillProcess(&g_tlist[nItemIndex]); } //刷新进程列表 SendMessage(WM_COMMAND,(WPARAM)IDC_BTNREFRESH,0); } ”Refresh”按钮的单击事件实现代码如下: /* *函数介绍: 刷新按钮单击事件 *入口参数: (无) *出口参数: (无) *返回值: (无) */ voidCTaskListDlg: : OnBtnrefresh() { TASK_LIST_ENUMprocessList;//进程列表信息 TCHARnumBuf[10];//存储进程中的线程数 memset(&g_tlist,0,sizeof(TASK_LIST)*MAX_TASKS); //得到进程列表信息 DWORDnNumTasks=GetTaskListCE(g_tlist); processList.numtasks=nNumTasks; processList.tlist=g_tlist; //更新进程列表信息,获取主窗口句柄和标题 GetWindowTitles(&processList); CListCtrl*pList
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实验 步骤