// WindowStealth.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "resource.h"
#include <Mmsystem.h>
#include <shellapi.h>
#define WM_TRAYNOTIFY (WM_USER + 1)
#define IDC_TRAYICON (WM_USER + 2)
int ExitApp; // used to signal the monitor key thread to exit
HINSTANCE hInst;
LRESULT CALLBACK WindowStealth(HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK EnumWindowsProc(HWND hwnd,LPARAM hDlg);
TIMERPROC EnumWindowTime(HWND,UINT,UINT_PTR,DWORD);
BOOL HideWindow(HWND);
BOOL RevealWindow(HWND);
DWORD WINAPI HotKeyMon(HWND);
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
hInst = hInstance; // Store instance handle in our global variable
DialogBox(hInstance, (LPCTSTR)IDD_DIALOG1, NULL, (DLGPROC)WindowStealth);
return 0;
}
LRESULT CALLBACK WindowStealth(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
DWORD lpStartID;
HANDLE hdStart;
NOTIFYICONDATA tnd; // data struct needed for below calls for tray icon handling
switch (message)
{
case WM_INITDIALOG:
EnumWindows(EnumWindowsProc,(LPARAM) hDlg);
// here we set a timer to refresh the visible window listbox.
// An alternative method is to set a global windows hook for CreateProcess
SetTimer(hDlg,NULL,2500,(TIMERPROC)EnumWindowTime);
// here we launch our thread to monitor the toggling of the PAUSE key
// again, an alternative method is to set a global windows hook for keyboard msg
hdStart=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE )HotKeyMon,(LPVOID)hDlg,0,&lpStartID);
CheckDlgButton(hDlg,IDC_HOTKEY,BST_CHECKED);
// "TRAYICON" is an icon you have in your *.rc file.
tnd.cbSize = sizeof(NOTIFYICONDATA);
tnd.hWnd = hDlg;
tnd.uID = IDC_TRAYICON;
tnd.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
tnd.uCallbackMessage = WM_TRAYNOTIFY;
tnd.hIcon = (HICON)LoadImage(hInst,MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON, 16, 16, 0);
lstrcpyn(tnd.szTip, "WindowStealth", sizeof(tnd.szTip));
Shell_NotifyIcon(NIM_ADD, &tnd);
return TRUE;
case WM_TRAYNOTIFY:
//wParam = icon identifier
//lParam = notification message
if(wParam == IDC_TRAYICON)
switch(lParam)
{
case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_LBUTTONDBLCLK:
SetForegroundWindow(hDlg);
ShowWindow(hDlg,SW_SHOW);
break;
}
break;
case WM_SIZE:
if(wParam==SIZE_MINIMIZED)
{
ShowWindow(hDlg,SW_HIDE);
break;
}
break;
case WM_COMMAND:
if (LOWORD(wParam) == IDCANCEL)
{
ExitApp=1;
// remove icon from tray
tnd.cbSize = sizeof(NOTIFYICONDATA);
tnd.hWnd = hDlg;
tnd.uID = IDC_TRAYICON;
Shell_NotifyIcon(NIM_DELETE, &tnd);
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
else if(LOWORD(wParam) == IDHIDE)
{
HideWindow(hDlg);
}
else if(LOWORD(wParam) == IDREVEAL)
{
RevealWindow(hDlg);
}
break;
}
return FALSE;
}
// Upon receving the timer message, we refresh the visible window listbox
TIMERPROC EnumWindowTime(HWND hDlg,UINT uMsg,UINT_PTR idEvent,DWORD dwTime)
{
int index;
HWND hShowList;
char WindowName[128];
hShowList=GetDlgItem(hDlg,IDC_SHOWLIST);
// before we clear the listbox, let's save the current user selection
index=SendMessage(hShowList,LB_GETCURSEL,0,0);
SendMessage(hShowList,LB_GETTEXT,index,(LPARAM)WindowName);
SendMessage(GetDlgItem(hDlg,IDC_SHOWLIST),LB_RESETCONTENT,0,0);
EnumWindows(EnumWindowsProc,(LPARAM) hDlg);
// right after we refresh the listbox, we set the current selection back to the previous
// user selected one.
index=SendMessage(hShowList,LB_FINDSTRING,-1,(LPARAM)WindowName);
SendMessage(hShowList,LB_SETCURSEL,index,0);
return 0;
}
BOOL CALLBACK EnumWindowsProc(HWND hwnd,LPARAM hDlg)
{
char szbuff[128];
HWND hListBox;
hListBox=GetDlgItem((HWND)hDlg,IDC_SHOWLIST);
GetWindowText(hwnd,szbuff,sizeof(szbuff));
// some windows do not have a title, so we ignore the windows that doesn't have one
if(strlen(szbuff) <= 0)
return TRUE;
if (IsWindowVisible(hwnd) > 0 )
SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)szbuff);
return TRUE;
}
// This function hides the selected window
BOOL HideWindow(HWND hDlg)
{
int index;
HWND hWindow,hShowWindow,hHidenWindow;
char WindowName[128];
hShowWindow=GetDlgItem(hDlg,IDC_SHOWLIST);
hHidenWindow=GetDlgItem(hDlg,IDC_HIDELIST);
index=SendMessage(hShowWindow,LB_GETCURSEL,0,0);
if(index < 0)
{
MessageBox(NULL,"Please select a window !",NULL,MB_OK);
return FALSE;
}
SendMessage(hShowWindow,LB_GETTEXT,index,(LPARAM)WindowName);
hWindow=FindWindow(NULL,WindowName);
if(!hWindow)
{
MessageBox(NULL,"Window Not Found !",NULL,MB_OK);
return FALSE;
}
SendMessage(hHidenWindow,LB_ADDSTRING,0,(LPARAM)WindowName);
ShowWindow(hWindow,SW_HIDE);
return TRUE;
}
//This function reveals the selected window
BOOL RevealWindow(HWND hDlg)
{
int index;
HWND hWindow,hShowWindow,hHidenWindow;
char WindowName[128];
hShowWindow=GetDlgItem(hDlg,IDC_SHOWLIST);
hHidenWindow=GetDlgItem(hDlg,IDC_HIDELIST);
index=SendMessage(hHidenWindow,LB_GETCURSEL,0,0);
if(index < 0)
{
MessageBox(NULL,"Please select a window !",NULL,MB_OK);
return FALSE;
}
SendMessage(hHidenWindow,LB_GETTEXT,index,(LPARAM)WindowName);
hWindow=FindWindow(NULL,WindowName);
if(!hWindow)
{
MessageBox(NULL,"Window Not Found !",NULL,MB_OK);
return FALSE;
}
SendMessage(hHidenWindow,LB_DELETESTRING,index,0);
ShowWindow(hWindow,SW_SHOWNA);
return TRUE;
}
DWORD WINAPI HotKeyMon(HWND hDlg)
{
HWND hShowWindow,hHidenWindow,hMostRecent=NULL;
char szbuff[1024];
hShowWindow=GetDlgItem(hDlg,IDC_SHOWLIST);
hHidenWindow=GetDlgItem(hDlg,IDC_HIDELIST);
while(ExitApp != 1)
{
if (GetAsyncKeyState(VK_PAUSE)) // if PAUSE is down or was down since the last call
{
if(hMostRecent==NULL)
{
if(IsDlgButtonChecked(hDlg,IDC_HOTKEY)==BST_CHECKED)
{
hMostRecent=GetForegroundWindow(); //get the handle to the top window
ShowWindow(hMostRecent,SW_HIDE);
GetWindowText(hMostRecent,szbuff,sizeof(szbuff));
SendMessage(hHidenWindow,LB_ADDSTRING,0,(LPARAM)szbuff);
}
}
else
{
if(IsDlgButtonChecked(hDlg,IDC_HOTKEY)==BST_CHECKED)
{
ShowWindow(hMostRecent,SW_SHOW);
SetForegroundWindow(hMostRecent);
hMostRecent=NULL;
SendMessage(hHidenWindow,LB_DELETESTRING,SendMessage(hHidenWindow,LB_FINDSTRING,-1,(LPARAM)szbuff),0);
}
}
}
Sleep(500); //let's throttle the polling process
}
return TRUE;
}