在 Windows 95/98 時代,按下 Ctrl+Alt+Del 會彈出「關閉程式」對話方塊,列出所有執行中的應用程式。若想讓自己的程式隱形(不被一般使用者輕易結束),有兩種經典做法。
Win9x 判斷是否顯示於工作清單的依據之一是「主視窗是否有標題」。若 Application->Title 為空字串,系統就不會將其列入。最佳時機是在 WinMain 初始化階段:
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {
try {
Application->Title = ""; // 關鍵:設為空字串
Application->Initialize();
Application->CreateForm(__classid(TForm1), &Form1);
Application->Run();
} catch (Exception &e) {
Application->ShowException(&e);
}
return 0;
}
缺點:工作列按鈕也會變成空白,視覺上明顯異常。
呼叫未公開的 Kernel32.dll::RegisterServiceProcess 將目前進程標記為服務型(RSP_SIMPLE_SERVICE = 1),即可從工作清單消失,且不影響視窗標題。
// 標頭檔
typedef DWORD (__stdcall *PRegFunc)(DWORD, DWORD);
class TForm1 : public TForm {
HINSTANCE hKernelLib;
PRegFunc RegisterServiceProcess;
public:
__fastcall TForm1(TComponent* Owner);
__fastcall ~TForm1();
};
// 實作檔
#define RSP_SIMPLE_SERVICE 1
#define RSP_UNREGISTER_SERVICE 0
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) {
hKernelLib = LoadLibrary("kernel32.dll");
if (hKernelLib) {
RegisterServiceProcess = (PRegFunc)GetProcAddress(hKernelLib, "RegisterServiceProcess");
if (RegisterServiceProcess)
RegisterServiceProcess(GetCurrentProcessId(), RSP_SIMPLE_SERVICE);
}
}
__fastcall TForm1::~TForm1() {
if (hKernelLib && RegisterServiceProcess) {
RegisterServiceProcess(GetCurrentProcessId(), RSP_UNREGISTER_SERVICE);
FreeLibrary(hKernelLib);
}
}
注意: 此 API 僅存在於 Win9x 核心,Windows NT/2000/XP 並無此函數,若在 NT 系列呼叫會失敗。現代開發請改用正規的 Windows Service 架構。