前些天搞了个×××面的后台应用程序,以前从来没有接触过,网上查找资料,都是零零散散的,比较少全面一点的介绍。这里把自己的创建过程大概记录一下,给自己留个底儿。
1.如何创建×××面后台应用
一般可以选择用控制台方式隐藏窗口,或者用对话框模式隐藏窗口,我这里用的是对话框模式。
在VC6.0上新建一个对话框应用程序CMfcNoDialogAppApp,其实只是借了个它的外壳。CMfcNoDialogAppDlg的OnPaint()方法中做个处理,代码如下:
- void CMfcNoDialogAppDlg::OnPaint()
- {
- // if (IsIconic())
- // {
- // CPaintDC dc(this); // device context for painting
- //
- // SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
- //
- // // Center icon in client rectangle
- // int cxIcon = GetSystemMetrics(SM_CXICON);
- // int cyIcon = GetSystemMetrics(SM_CYICON);
- // CRect rect;
- // GetClientRect(&rect);
- // int x = (rect.Width() - cxIcon + 1) / 2;
- // int y = (rect.Height() - cyIcon + 1) / 2;
- //
- // // Draw the icon
- // dc.DrawIcon(x, y, m_hIcon);
- // }
- m_hThread = (HANDLE)_beginthreadex(NULL,
- 0,
- ThreadEntry,
- this,
- 0,
- &m_hThreadID);
- static int i = 2;
- if (i <= 2)
- {
- ShowWindow(SW_HIDE);
- i--;
- }
- else
- {
- CDialog::OnPaint();
- }
- }
如上代码中被注释掉的是程序自动生成的有关窗口绘制的内容,在下面创建一个自己需要的线程,用来实现自己的功能。
后面用了一个方法内静态变量
static int i = 2;
if (i <= 2)
{
ShowWindow(SW_HIDE);
i--;
}
else
{
CDialog::OnPaint();
}
设置为i<=2时,窗口将不显示。
这样一个简单的后台应用就出来了,运行之后,在进程管理中可以看到它的进程,并且在任务管理的应用程序栏中没有图标,在任务栏也没有图标。有一点不太好的是,直接双击运行这个应用程序,会闪一下他的窗口。
2.后台应用的启动和关闭
启动可以直接调用API方法CreateProcess,如下:
- PROCESS_INFORMATION pi;
- STARTUPINFO si;
- memset(&si,0,sizeof(si));
- si.cb=sizeof(si);
- si.wShowWindow=SW_SHOW;
- si.dwFlags=STARTF_USESHOWWINDOW;
- bool ret = CreateProcess("E:\\testandlearn\\MfcNoDialogApp\\Debug\\MfcNoDialogApp.exe",
- NULL,
- NULL, // process security attributes
- FALSE, // primary thread security attributes
- NULL, // handles are inherited
- NULL, // creation flags
- NULL, // use parent\'s environment
- NULL, // use parent\'s current directory
- &si, // startupinfo pointer
- &pi); // receives process_information
进程启动成功后,pi.hProcess就是他的进程句柄。
关闭进程:
关掉进程不能使用ExitProcess,这个是用来停掉自己的。应该使用TerminateProcess,但是他需要一个参数,ExitCode。可以通过GetExitCodeProcess方法获取。关闭进程的代码如下:
- DWORD lpExitCode ;
- GetExitCodeProcess(hProcess,&lpExitCode);//获取退出码
- TerminateProcess( hProcess, lpExitCode);//关掉进程
- CloseHandle( hThread );//关掉进程的主线程句柄
- CloseHandle( hProcess );//关掉进程句柄
这样就可以完全控制一个后台进程的生死了。
TerminateProcess是没有任何提示的强制干掉一个进程,所以调用前要确保他的工作已经完成,内存已经释放。