#include "winbase.h--"
#include "winuser.h--"
#include "advapi.h--"
#include "shellapi.h--"
#include "string32.h--"

#define DeskIconID      13
#define WM_NotifyIcon   WM_USER+10
#define MI_Minimize     1
#define MI_AboutMsg     2
#define MI_ExitApp      3
#define DI_Icon         100
#define DI_Input        110
#define DI_Browse       113
#define DI_About        120
#define EM_MinimizeAll  0x19F

char Title = "Свернуть все";
char P_RegPath = "Software\\Microsoft\\Windows\\CurrentVersion\\Run";
char P_RegParam = "Minimizer";

struct MSG Msg;
struct NOTIFYICONDATA nid;
struct BROWSEINFO bi;
DWORD RegValueSize, RegValueType;
HANDLE HInst, RegKey, DeskIcon, MainWin, Menu;
LPSTR P_RegValue, P_SourceFileName;
LPVOID pidl;


INT SHBFF_Callback( DWORD wnd, msg, wpar, lpar)
{
  return 0;
}


LRESULT SetupDlgProc( HWND dlg; DWORD msg, wpar, lpar)
{
  switch (msg) {
    CASE WM_INITDIALOG:
      SendDlgItemMessage( dlg, DI_Icon, STM_SETIMAGE, IMAGE_ICON, DeskIcon);
      GetWindowsDirectory( P_RegValue, 255);
      SetDlgItemText( dlg, DI_Input, P_RegValue);
      break;
    CASE WM_CLOSE: EndDialog( dlg, IDCANCEL); break;
    CASE WM_COMMAND: switch (wpar) {
      CASE IDCANCEL:
      CASE IDOK:
        GetDlgItemText( dlg, DI_Input, P_RegValue, 255);
        EndDialog( dlg, wpar);
        break;
      CASE DI_About:
        DialogBoxParam( HInst, "ABOUTDLG", dlg, #AboutDlgProc, 0);
        break;
      CASE DI_Browse:
        SHGetSpecialFolderLocation( dlg, CSIDL_DESKTOP, #pidl);
        bi.hwndOwner = dlg;
        bi.pidlRoot = pidl;
        bi.pszDisplayName = P_RegValue;
        bi.lpszTitle = "Выберите каталог для установки программы Minimizer";
        bi.ulFlags = BIF_RETURNONLYFSDIRS;
        bi.lpfn = #SHBFF_Callback;
        pidl = SHBrowseForFolder( #bi);
        IF (pidl != 0)
        {
          SHGetPathFromIDList( pidl, P_RegValue);
          SetDlgItemText( dlg, DI_Input, P_RegValue);
        }
    }
  }
  return 0;
}


LRESULT AboutDlgProc( HWND dlg; DWORD msg, wpar, lpar)
{
  SWITCH (msg) {
    CASE WM_INITDIALOG: SendDlgItemMessage( dlg, DI_Icon, STM_SETIMAGE, IMAGE_ICON, DeskIcon); BREAK;
    CASE WM_COMMAND:
    CASE WM_CLOSE: EndDialog( dlg, IDCANCEL); BREAK;
  }
  return 0;
}


LRESULT MinimizeAll()
  HWND AppBar;
{
  // Как будто из контекстого меню панели задач выбрали "Свернуть все"
  AppBar = FindWindowEx( 0, 0, "Shell_TrayWnd", 0);
  SendMessage( AppBar, WM_COMMAND, EM_MinimizeAll, 0);
  return(0);
}


LRESULT Uninstall()
{
  IF (MessageBox( 0, "Вы уверены, что хотите удалить Minimizer со своего компьютера?",
                  #Title, MB_ICONWARNING|MB_YESNO) == IDYES)
  {
    // Удаляем запись из реестра
    RegOpenKey( HKEY_CURRENT_USER, #P_RegPath, #RegKey);
    RegDeleteValue( RegKey, #P_RegParam);
    RegCloseKey( RegKey);
    // Удаляем свой EXE-шник
    strcpy( P_RegValue, "start.exe /m /w command.com /c del ");
    GetModuleFileName( 0, P_SourceFileName, 64);
    strcat( P_RegValue, P_SourceFileName);
    WinExec( P_RegValue, SW_HIDE);
    PostQuitMessage(0);
  }
  return(0);
}


LRESULT WndProc( HWND wnd; UINT msg, wPar, lPar)
  dword res;
{
  res = 0;
  switch (msg) {
  CASE WM_DESTROY: PostQuitMessage(0); break;
  CASE WM_COMMAND: SWITCH (wPar) {
       // Команды менюшки
       CASE MI_Minimize: res = MinimizeAll(); BREAK;
       CASE MI_AboutMsg: DialogBoxParam( HInst, "ABOUTDLG", 0, #AboutDlgProc, 0); BREAK;
       CASE MI_ExitApp: res = Uninstall(); BREAK;
       default: DefWindowProc( wnd, msg, wPar, lPar);
       } break;
  CASE WM_NotifyIcon: IF (wPar == DeskIconID) SWITCH (lPar) {
       // События мышки
       CASE WM_LBUTTONDOWN: res = MinimizeAll(); BREAK;
       CASE WM_RBUTTONUP: res = TrackPopupMenu( Menu, TPM_RIGHTALIGN,
            GetSystemMetrics( SM_CXSCREEN)-48, GetSystemMetrics( SM_CYSCREEN),
            0, MainWin, 0); BREAK;
       default: res = DefWindowProc( wnd, msg, wPar, lPar);
       } BREAK;
  default: res = DefWindowProc( wnd, msg, wPar, lPar);
  }
  return(res);
}


void main()
{
  // Загружаем иконку, размещаем строки
  HInst = GetModuleHandle( NULL);
  DeskIcon = ExtractIcon( HInst, "shell32.dll", 34);
  P_RegValue = LocalAlloc( LPTR, 256);
  P_SourceFileName = LocalAlloc( LPTR, 256);
  // Проверяем наличие параметра RUN
  if (strstr( GetCommandLine(), "/RUN") == 0)
  {
    // Проверяем запись в реестре
    RegOpenKey( HKEY_CURRENT_USER, #P_RegPath, #RegKey);
    RegQueryValueEx( RegKey, #P_RegParam, 0, #RegValueType, P_RegValue, #RegValueSize);
    if (RegValueSize == 0)
    {
      // Предлагаем юзеру установить программу
      if (DialogBoxParam( HInst, "SETUPDLG", 0, #SetupDlgProc, 0) == IDOK)
      {
        // Копируем свой EXE-файл
        GetModuleFileName( HInst, P_SourceFileName, 255);
        strchrr( P_SourceFileName, '\\');
        strcat( P_RegValue, EAX);
        CopyFile( P_SourceFileName, P_RegValue, FALSE);
        // Заносим запись в реестр
        strcat( P_RegValue, " /RUN");
        RegSetValueEx( RegKey, #P_RegParam, 0, 1, P_RegValue, strlen( P_RegValue));
        // Запускаем себя с параметром RUN
        WinExec( P_RegValue, SW_SHOWNORMAL);
      }
    }
    ELSE MessageBox( 0, "Minimizer уже установлен на вашем компьютере.",
                     #Title, MB_ICONWARNING|MB_OK);
    RegCloseKey( RegKey);
  }
  else
  {
    // Создаем левое окошко
    MainWin = CreateWindowEx( 0, "BUTTON", 0, 0, 0, 0, 0, 0, 0, 0, GetModuleHandle(0), 0);
    SetWindowLong( MainWin, GWL_WNDPROC, #WndProc);
    // Вставляем иконку в трэй
    nid.cbSize = sizeof( NOTIFYICONDATA);
    nid.hWnd = MainWin;
    nid.uID = DeskIconID;
    nid.uFlags = NIF_ICON|NIF_MESSAGE|NIF_TIP;
    nid.uCallbackMessage = WM_NotifyIcon;
    nid.hIcon = DeskIcon;
    strcpy( #nid.szTip, #Title);
    Shell_NotifyIcon( NIM_ADD, #nid);
    // Создаем менюшку
    Menu = CreatePopupMenu();
    AppendMenu( Menu, MF_STRING|MF_ENABLED, MI_Minimize, #Title);
    AppendMenu( Menu, MF_STRING|MF_ENABLED, MI_AboutMsg, "О программе");
    AppendMenu( Menu, MF_SEPARATOR, 0, 0);
    AppendMenu( Menu, MF_STRING|MF_ENABLED, MI_ExitApp, "Закрыть...");
    SetMenuDefaultItem( Menu, MI_Minimize, 0);
    // Цикл обработки сообщений
    WHILE (GetMessage( #Msg, 0, 0, 0) > 0)
    {
      TranslateMessage( #Msg);
      DispatchMessage( #Msg);
    }
    // Удаляем иконку из трэ
    Shell_NotifyIcon( NIM_DELETE, #nid);
    // Все уничтожаем
    DestroyMenu( Menu);
    DestroyWindow( MainWin);
  }
  DestroyIcon( DeskIcon);
  LocalFree( P_RegValue);
  LocalFree( P_SourceFileName);
}


