制作一个不在任务栏及任务列表中显示的幽灵程序

259 篇文章 4 订阅

制作一个不在任务栏及任务列表中显示的幽灵程序

网上已经有许多地方提到了如何将在任务栏隐藏应用程序,使用的方法都是将Application的属性变为WS_EX_TOOLWINDOW。即在WinMain函数中加入如下代码:

DWORD dwExStyle = GetWindowLong(Application->Handle, GWL_EXSTYLE);

dwExStyle |= WS_EX_TOOLWINDOW;
SetWindowLong(Application->Handle, GWL_EXSTYLE, dwExStyle);
Application->Initialize();
Application->CreateForm(__classid(TForm1), &Form1);
Application->ShowMainForm = false;
ShowWindow(Application->Handle, SW_HIDE);
Application->Run();
这样做之后,应用程序就不会在任务栏显示了,但在WIN9X的任务列表中仍能看到。要想在任务列表也将自己的程序隐藏就要借用kernel32.DLL中的RegisterServiceProcess这个函数了。由于要从DLL加载函数,我们先在头文件中加入:
typedef DWORD (__stdcall *pRegFunction)(DWORD, DWORD);
在主Form的类定义中加入两个私有属性:
HINSTANCE hKernelLib;
pRegFunction RegisterServiceProcess;
用于记录从DLL加入的函数信息。
然后在主Form的构造代码中加入如下代码:
hKernelLib = LoadLibrary("kernel32.dll");
if(hKernelLib)
{
RegisterServiceProcess =
(pRegFunction)GetProcAddress(hKernelLib,
"RegisterServiceProcess");
if(RegisterServiceProcess)
RegisterServiceProcess(GetCurrentProcessId(),RSP_SIMPLE_SERVICE);
}
这段代码主要是把当前进程变为一个系统服务,从而在任务列表中把程序隐藏起来,相应的在构析代码中加入
if(hKernelLib)
{
if(RegisterServiceProcess)
RegisterServiceProcess(GetCurrentProcessId(),
RSP_UNREGISTER_SERVICE);
FreeLibrary(hKernelLib);
}
这样处理之后,程序就不在任务列表中出现了,但仍可用EnumWindows函数查出来。

 

 

 

如何让基于对话框的程序运行时隐藏界面

有些时候需要不让对话框在运行时显示出来,ShowWindow的方法会有闪动现象,我认为最好的方法是用create.具体过程如下:

 假设建立一个VC.NET工程GetTime,首先在CGetTimeApp类中添加一个成员变量:CGetTimeD
lg *dlg;
然后在InitInstance()中将原来的:

    int nResponse = dlg.DoModal();
    if (nResponse == IDOK)
    {
       // TODO: Place code here to handle when the dialog is
       //  dismissed with OK
    }
    else if (nResponse == IDCANCEL)
    {
       // TODO: Place code here to handle when the dialog is
       //  dismissed with Cancel
    }
以及return FALSE;全部删除掉,改为:     dlg=new CGetTimeDlg;
    m_pMainWnd = dlg;
    return dlg->Create(IDD_GETTIME_DIALOG);
  
最后别忘了在ExitInstance()中加上一句:delete dlg;好了,这下把本程序的对话框
变成了一个无模式对话框。不过既然是无模式对话框,就不能再用OnOK(),OnCancel()来退
出了,要用DestroyWindow()

  另外将对话框的属性设置为不可见
  
由于在上面的代码中没有将对话框设为可见,所以运行时就实现了隐藏,而且在Window
s
任务栏上也没有显示。

 

让程序只运行一个实例的简单实用的方法

//首先在InitInstance()函数中创建一个同步对象,如果(GetLastError()返回ERROR_ALREADY_EXISTS

表明存在
//
一个应用实例了,返回false取消
//
创建同步对象

//By cryfish
 hMutexOneInstantance=CreateMutex(NULL,TRUE,_T("PreventSecondInstance"));
 if(GetLastError()==ERROR_ALREADY_EXISTS)
  bFound=TRUE;
 if(hMutexOneInstantance)
  ReleaseMutex(hMutexOneInstantance);
 if (bFound==TRUE)
 { ::AfxMessageBox("You have Run one");
 return false;
 }

 

 

VC++实现程序在启动时隐藏

 

最近经常见论坛上有人问,程序在启动时如何隐藏。以下是我总结的一些方法,欢迎大家讨论,找出更好的方法。  

对于这类问题,大家最容易想到的可能就是在PreCreateWindow中添加cs.style &=~WS_VISIBLE;这是不可行的。程序仍可使用ShowWindow()将窗体显示出来.  

  1.基于对话框的程序

  我在论坛上看到有人说在OnInitDialog()中加上ShowWindow(SW_HIDE)对话框便不出现了,其实是不可行的。至于原因,我认为是系统是在OnInitDialog()后调用ShowWindow(SW_SHOW)让对话框显示的.可以添加下面代码:

  CXXDlg::OnInitDialog()

  {

   ...

   Sleep(5000);

   return TRUE;

  }

  可以发现5秒后对话框才显示出来.至于在何时调用的我也不清楚,但是我们可以在OnPaint()中加上ShowWindow(SW_HIDE),来达到隐藏的目的.不过使用的这种方法,会有一点闪烁.另外一种方法就是在OnInitDialog()中使用SetWindowPlacement()  

  GetWindowPlacement(&m_wp); //恢复时用

  ModifyStyleEx(WS_EX_APPWINDOW,WS_EX_TOOLWINDOW);//从任务栏中去掉.  

  WINDOWPLACEMENT wp;

  wp.length=sizeof(WINDOWPLACEMENT);

  wp.flags=WPF_RESTORETOMAXIMIZED;

  wp.showCmd=SW_HIDE;

  SetWindowPlacement(wp);  

  还有一种更简单的方法:OnInitDialog()中调用下面代码.

  SetWindowPos(&wndTop,0,0,0,0,NULL);  

  2.基于单文档的程序  

   我们一般采用的方法就是将InitInstance()中的:

  CXXApp::InitInstance()

  {

   //m_pMainWnd->ShowWindow(SW_SHOW);

  }

  但是这样窗体还会有闪烁。

因为MFC还要在ActiveFrame显示框架,所以我们还需要添加下面代码:

  void CMainFrame::ActivateFrame(int nCmdShow)

  {

   nCmdShow=SW_HIDE;

   CFrameWnd::ActivateFrame(nCmdShow);

  }

  或者:

  int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)

  {

   AfxGetApp()->m_nCmdShow=SW_HIDE;

  }

  顺便说一下,上面通过ModifyStyleEx(WS_EX_APPWINDOW,WS_EX_TOOLWINDOW)的方法来实现从任务栏去掉按钮,这样当显示时还要切换显示的模式,其实还可以通过调用TaskbarList组件直接删除和添加:

  ITaskbarList的定义在shobjidl.h(vs.net)中。

  也可以手动定义:

  DECLARE_INTERFACE_(ITaskbarList,IUnknown)

  {

   STDMETHOD(QueryInterface)(THIS_ REFIID riid,LPVOID* ppvObj) PURE;

   STDMETHOD_(ULONG,AddRef)(THIS) PURE;

   STDMETHOD_(ULONG,Release)(THIS) PURE;

   STDMETHOD(ActivateTab)(HWND) PURE;

   STDMETHOD(AddTab)(HWND) PURE;

   STDMETHOD(DeleteTab)(HWND) PURE;

   STDMETHOD(HrInit)(void) PURE;

  };

  BOOL CMy2App::InitInstance()

  {

   CoInitialize(0);

   ITaskbarList *pObj;

   CoCreateInstance(CLSID_TaskbarList,NULL,CLSCTX_INPROC_SERVER,IID_ITaskbarList,(void**)&pObj);

   pObj->DeleteTab(m_pMainWnd->m_hWnd); //从任务栏上删除

   //pObj->AddTab(m_pMainWnd->m_hWnd); //添加  

   pObj->Release();

   CoUninitialize();

  }  

  所以我们还可以用将窗体最小化,并从任备栏上删除按钮的方法来实现隐藏.

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值