#include "stdafx.h"
#include "resource.h"
#include "RegisterdMessages.h"
#define ARRAY_SIZE 1024
#pragma data_seg (".SHARED")
HHOOK g_hPreviousMouseHook = 0;
HHOOK g_hPreviousWinProcHook = 0;
HINSTANCE g_hInstance = 0;
HWND g_hMinimizedWindowList[ARRAY_SIZE] = {0};
int g_iMinimizedWindowCount = 0;
#pragma data_seg()
#pragma comment(linker,"/SECTION:.SHARED,RWS")
bool TrayMe(HWND hWnd)
{
bool bReturn = false;
try
{
if(g_iMinimizedWindowCount >= ARRAY_SIZE)
{
MessageBox(NULL,_T("Can not Tray application. \n\t Reached the Tray limit."),_T("Tray Me !"),0);
return bReturn;
}
TCHAR szModuleFileName[ARRAY_SIZE] = {0};
HMODULE hModule = (HMODULE) OpenProcess(0,FALSE,GetWindowThreadProcessId(hWnd,0));
GetModuleFileName(hModule,szModuleFileName,ARRAY_SIZE);
OutputDebugString(szModuleFileName);
TCHAR szCaption[128] = {0};
//HICON hIcon = (HICON) SendMessage(pMouseHooksStruct->hwnd,WM_GETICON,ICON_SMALL,0);
SHFILEINFO shFileInfo;
shFileInfo.hIcon = NULL;
SHGetFileInfo(szModuleFileName,FILE_ATTRIBUTE_NORMAL,&shFileInfo,sizeof(SHFILEINFO),SHGFI_ICON | SHGFI_USEFILEATTRIBUTES | SHGFI_SMALLICON);
if(!shFileInfo.hIcon)
OutputDebugString(_T("NULL Icon handle."));
NOTIFYICONDATA objNotifyIcon;
objNotifyIcon.cbSize = sizeof(NOTIFYICONDATA);
objNotifyIcon.hWnd = hWnd;
objNotifyIcon.uID = 1;
objNotifyIcon.uCallbackMessage = WM_NOTIFY_CALLBACK_MESSAGE;
objNotifyIcon.hIcon = (shFileInfo.hIcon == NULL) ? LoadIcon(NULL,IDI_QUESTION) : shFileInfo.hIcon;
objNotifyIcon.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
GetWindowText(hWnd,szCaption,127);
wcscpy_s(objNotifyIcon.szTip,127,szCaption);
Shell_NotifyIcon(NIM_ADD,&objNotifyIcon);
ShowWindow(hWnd,SW_HIDE);
g_hMinimizedWindowList[g_iMinimizedWindowCount++] = hWnd;
bReturn = true;
}
catch(...)
{
OutputDebugString(_T("Caught Exception in TrayMe !"));
bReturn = false;
}
return bReturn;
}
bool UnTrayApplication(HWND hWnd)
{
bool bReturn = false;
try
{
::ShowWindow(hWnd,SW_SHOW);
::SetForegroundWindow(hWnd);
NOTIFYICONDATA objNotifyIcon;
objNotifyIcon.cbSize = sizeof(NOTIFYICONDATA);
objNotifyIcon.hWnd = hWnd;
objNotifyIcon.uID = 1;
Shell_NotifyIcon(NIM_DELETE,&objNotifyIcon);
for(int i = 0; i < g_iMinimizedWindowCount; i++)
if(hWnd == g_hMinimizedWindowList[i])
{
g_hMinimizedWindowList[i] = g_hMinimizedWindowList[--g_iMinimizedWindowCount];
g_hMinimizedWindowList[g_iMinimizedWindowCount] = 0;
break;
}
bReturn = true;
}
catch(...)
{
OutputDebugString(_T("Caught Exception in UnTrayMe !"));
bReturn = false;
}
return bReturn;
}
bool UnTrayMe(TCHAR *szWindowTitle)
{
bool bReturn = false;
HWND hWnd = NULL;
try
{
for(int i = 0;i < g_iMinimizedWindowCount;i++)
{
TCHAR szWinTitle[ARRAY_SIZE] = {0};
GetWindowText(g_hMinimizedWindowList[i],szWinTitle,ARRAY_SIZE - 1);
if(_wcsicmp(szWindowTitle,szWinTitle) == 0)
{
hWnd = g_hMinimizedWindowList[i];
break;
}
}
if(NULL == hWnd)
return FALSE;
::ShowWindow(hWnd,SW_SHOW);
::SetForegroundWindow(hWnd);
NOTIFYICONDATA objNotifyIcon;
objNotifyIcon.cbSize = sizeof(NOTIFYICONDATA);
objNotifyIcon.hWnd = hWnd;
objNotifyIcon.uID = 1;
Shell_NotifyIcon(NIM_DELETE,&objNotifyIcon);
for(int i = 0; i < g_iMinimizedWindowCount; i++)
if(hWnd == g_hMinimizedWindowList[i])
{
g_hMinimizedWindowList[i] = g_hMinimizedWindowList[--g_iMinimizedWindowCount];
g_hMinimizedWindowList[g_iMinimizedWindowCount] = 0;
break;
}
bReturn = true;
}
catch(...)
{
OutputDebugString(_T("Caught Exception in UnTrayMe !"));
bReturn = false;
}
return bReturn;
}
void UnTrayAll()
{
//bool bReturn = false;
try
{
while(g_iMinimizedWindowCount)
UnTrayApplication(g_hMinimizedWindowList[0]);
//bReturn = true;
}
catch(...)
{
MessageBox(NULL,_T("Failed to untray few applications."),_T("Tray Me !"),MB_ICONERROR);
OutputDebugString(_T("Exception Caught In UnTrayAll."));
//bReturn = false;
}
//return bReturn;
}
LRESULT CALLBACK MouseHookProcedure(int nCode, WPARAM wParam,LPARAM lParam)
{
if(0 > nCode)
return CallNextHookEx(g_hPreviousMouseHook,nCode,wParam,lParam);
//OutputDebugString(_T("Mouse Hooked Event...\n"));
MOUSEHOOKSTRUCT *pMouseHooksStruct = (MOUSEHOOKSTRUCT *) lParam;
switch(wParam)
{
case WM_NCRBUTTONUP:
if(HTMINBUTTON == pMouseHooksStruct->wHitTestCode)
{
OutputDebugString(_T("Mouse Clicked on Min Button...\n"));
HMENU hPopupMenu = ::CreatePopupMenu();
::AppendMenu(hPopupMenu,MF_STRING,501,_T("&Try Me !"));
SetForegroundWindow(pMouseHooksStruct->hwnd);
int iSelectedMenuId = ::TrackPopupMenu(hPopupMenu,TPM_LEFTALIGN | TPM_TOPALIGN | TPM_LEFTBUTTON | TPM_RETURNCMD ,pMouseHooksStruct->pt.x,pMouseHooksStruct->pt.y,0,pMouseHooksStruct->hwnd,NULL);
//PostMessage(WM_NULL,NULL,NULL);
switch(iSelectedMenuId)
{
case 501:
TrayMe(pMouseHooksStruct->hwnd);
break;
}
DestroyMenu(hPopupMenu);
return -1;
}
break;
}
return CallNextHookEx(g_hPreviousMouseHook,nCode,wParam,lParam);
}
LRESULT CALLBACK WinProcHookProcedure(int nCode, WPARAM wParam, LPARAM lParam)
{
if(0 > nCode)
return CallNextHookEx(g_hPreviousWinProcHook ,nCode,wParam,lParam);
CWPSTRUCT *pwsStruct = (CWPSTRUCT *) lParam;
if(WM_NOTIFY_CALLBACK_MESSAGE == pwsStruct->message)
{
if(WM_LBUTTONDBLCLK == pwsStruct->lParam)
{
OutputDebugString(_T("WM_NOTIFY_CALLBACK_MESSAGE WM_LBUTTONDBLCLK Fired.\n"));
UnTrayApplication(pwsStruct->hwnd);
}
return -1;
}
return CallNextHookEx(g_hPreviousWinProcHook ,nCode,wParam,lParam);
}
bool InstallWinProcHook(void)
{
bool bReturn = false;
try
{
OutputDebugString(_T("WinProc Event Hooked.\n"));
if(NULL == g_hInstance)
OutputDebugString(_T("NULL g_hInstance\n"));
g_hPreviousWinProcHook = SetWindowsHookEx(WH_CALLWNDPROC,&WinProcHookProcedure,g_hInstance,0);
if(NULL == g_hPreviousWinProcHook)
{
TCHAR szErrorMsg[ARRAY_SIZE] = {0};
wsprintf(szErrorMsg,_T("Failed to Hook WinProc Event.\nLast Error :%d\n"),GetLastError());
OutputDebugString(szErrorMsg);
bReturn = false;
}
else
{
OutputDebugString(_T("WinProc Event Hooked.\n"));
bReturn = true;
}
}
catch(...)
{
bReturn = false;
}
return bReturn;
}
bool UnInstallWinProcHook()
{
bool bReturn = false;
try
{
OutputDebugString(_T("WinProc Event UnHooked.\n"));
if(UnhookWindowsHookEx(g_hPreviousWinProcHook) == FALSE)
{
TCHAR szError[ARRAY_SIZE] = {0};
wsprintf(szError,_T("Last Error : %d"),GetLastError());
OutputDebugString(_T("Failed to UnHook WinProc Event.\n"));
OutputDebugString(szError);
bReturn = false;
}
else
{
OutputDebugString(_T("WinProc Event UnHooked.\n"));
bReturn = true;
}
}
catch(...)
{
bReturn = false;
}
return bReturn;
}
bool InstallMouseHook()
{
bool bReturn = false;
try
{
OutputDebugString(_T("Mouse Event Hooked.\n"));
g_hPreviousMouseHook = SetWindowsHookEx(WH_MOUSE,&MouseHookProcedure,g_hInstance,0);
if(NULL == g_hPreviousMouseHook)
{
TCHAR szError[ARRAY_SIZE] = {0};
wsprintf(szError,_T("Last Error : %d"),GetLastError());
OutputDebugString(_T("Failed to Hook Mouse Event.\n"));
OutputDebugString(szError);
bReturn = false;
}
else
{
OutputDebugString(_T("Mouse Event Hooked.\n"));
bReturn = true;
}
}
catch(...)
{
bReturn = false;
}
return bReturn;
}
bool UnInstallMouseHook()
{
bool bReturn = false;
try
{
OutputDebugString(_T("Mouse Event UnHooked.\n"));
if(UnhookWindowsHookEx(g_hPreviousMouseHook) == FALSE)
{
TCHAR szError[ARRAY_SIZE] = {0};
wsprintf(szError,_T("Last Error : %d"),GetLastError());
OutputDebugString(_T("Failed to UnHook Mouse Event.\n"));
OutputDebugString(szError);
bReturn = false;
}
else
{
OutputDebugString(_T("Mouse Event UnHooked.\n"));
bReturn = true;
}
}
catch(...)
{
bReturn = false;
}
return bReturn;
}
void GetMinimizedWinodwList(TCHAR szWindowCaptions[ARRAY_SIZE][100])
{
for(int i=0;i<g_iMinimizedWindowCount;i++)
{
TCHAR szWndCaption[ARRAY_SIZE] = {0};
::GetWindowText(g_hMinimizedWindowList[i], szWndCaption,ARRAY_SIZE - 1);
if(NULL != szWindowCaptions[i])
{
wcscpy(szWindowCaptions[i],szWndCaption);
}
}
}