-- 作者:卷积内核
-- 发布时间:4/8/2008 11:27:00 AM
-- VC如何关闭其他的应用程序
问题 有的程序员希望能够从自己的应用程序中启动其他的应用程序,并在操作完成后关闭应用程序。例如: 从应用程序中启动 Windows 应用程序 Write,作记录或者写备忘录,然后关闭此应用程序。有时,还希望 能够忽略应用程序 Write 的消息框,消息框是用来询问用户是否保存文件的改变。 如何使用 Windows 9x API 函数尽量简单地实现这两个功能呢? 方法 列出当前正在运行的任务以及如何激活选中的任务。要实现的功能类似, 但在应用程序程序中要激活的和关闭的任务一般是一定的。不过为了使本节的例子程序更具有普遍性,仍然 由用户来选择要关闭的应用程序,并决定使用的关闭方法。 为了实现这些功能,需要使用 Windows API 函数 PostMessage。 步骤 按照下列步骤实现一个例子程序。运行此例子程序,从菜单 Tasks 中选择菜单项 Terminate Tasks, 将弹出一个对话框,显示当前运行的窗口。选择一个窗口并点击按钮 Close App 或按钮 Quit App,对话 框将关闭,选中的窗口也将关闭。 启动 Windows 应用程序 WordPad,并键入一些文本,测试两个按钮的功能,会发现例子程序有时询问 是否存储已改变的文本,而有时不询问。 实现例子程序的具体步骤如下: 1.在 Visual C++ 中,利用 AppWizard 创建新的项目文件,并命名此项目文件为 LD33.MAK. 2.进入 AppStudio 并创建新的对话框。添加一个列表框,改变按钮 OK 的标题为 Close,删除 Cancel 按钮。将对话框的标题改为 Terminate Task。 3.在对话框中添两个按钮,标题分别为 Close App 和 Quit App。 4.进入 ClassWizard 为此对话框生成新的对话框类,类名为 CTerminateTaskDlg。从对象列表中选 择 CTerminateTaskDlg,从消息列表中选择消息 WM_INITDIALOG。点击按钮 Add Function,在方法 OnInitDialog 中输入下列代码: BOOL CTerminateTaskDlg::OnInitDialog() { CDialog::OnInitDialog(); CListBox * list=(CListBox *)GetDlgItem(IDC_LIST1); list->ResetContent(); FARPROC EnumProcInstance=MakeProcInstance( (FARPROC)EnumWindowsProc,AfxGetInstanceHandle()); EnumWindows((WNDENUMPROC)EnumProcInstance,(LPARAM)list); FreeProcInstance(EnumProcInstance); CenterWindow(); return TRUE; // return TRUE unless you set the focus to a control } 5.在文件 TerminateTaskDlg.cpp 中,方法 OnInitDialog 的前面,添加下列代码: static BOOL CALLBACK EnumWindowsProc(HWND hwnd,LPARAM lParam) { CListBox * list=(CListBox *)lParam; char buf[256]; GetWindowText(hwnd,buf,256); if(strlen(buf)) { int idx=list->AddString(buf); list->SetItemData(idx,(DWORD)hwnd); } return TRUE; } 6.从对象列表中选择 ID_BUTTON1,从消息列表中选择消息 BN_CLICKED,命名方法为 OnCloseApp,并在此方法中添加下列代码: void CTerminateTaskDlg::OnCloseApp() { CListBox * list=(CListBox *)GetDlgItem(IDC_LIST1); int idx=list->GetCurSel(); if(idx==LB_ERR) { MessageBox("You must select a window to active!", "Error",MB_OK|MB_APPLMODAL); return; } HWND hWnd=(HWND)list->GetItemData(idx); ::PostMessage(hWnd,WM_CLOSE,0,0L); EndDialog(IDOK); } 7.从对象列表中选择 ID_BUTTON2,从消息列表中选择消息 BN_CLICKED,命名方法为 OnQuitApp,并在此方法中添加下列代码: void CTerminateTaskDlg::OnQuitApp() { CListBox * list=(CListBox *)GetDlgItem(IDC_LIST1); int idx=list->GetCurSel(); if(idx==LB_ERR) { MessageBox("You must select a window to active!", "Error",MB_OK|MB_APPLMODAL); return; } HWND hWnd=(HWND)list->GetItemData(idx); ::PostMessage(hWnd,WM_QUIT,0,0L); EndDialog(IDOK); } 8.在菜单 Tasks 中添加新的菜单项 Terminate Tasks,ID 命名为 ID_TERMINATE_TASK。 9.在 ClassWizard 中.从下拉列表中选择对象 CMainFrame,从对象列表中选择 ID_TERMINATE_TASK,选择消息 COMMAND,点击按钮 Add Function,在方法 OnTerminateTask 中输入下列代码: void CMainFrame::OnTerminateTask() { CTerminateTaskDlg dlg; dlg.DoModal(); } 10.在文件 MAINFRM.CPP 的顶部添加下列行: #include "TerminateTaskDlg.h" 11.编译并运行此例子程序。 用法 使用 API 函数 EnumWindows 及回调函数 EnumWindowsProc 来列出窗 口,也将 Windows 句柄存放在列表框附加数据部分。 当用户从对话框中选择了按钮 Close App 后,选中的列表项及句柄将被取回。使用此句柄传送标识 符为 WM_CLOSE 的消息给窗口,表示窗口应被关闭。使用消息 WM_CLOSE 关闭窗口,将不会提示用户保 存已改变的文本。 当用户从对话框中选择了按钮 Quit App 后,选中的列表项及句柄将被取回。使用此句柄传送标识符 为 WM_QUIT 的消息给窗口,表示窗口应被关闭。使用消息 WM_CLOSE 关闭窗口,将会提示用户保存已改 变的文本,并允许用户撤消关闭窗口的请示。
|