#define STRICT
#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>
#include "resource.h"
#include "afxres.h"
#include "wizdemo.h"

// Структура, в которой хранятся параметры
typedef struct 
{
  int  nBold;
  int  nItalic;
  int  nUnderline;
  int  nUseTabs;
  char szKeyWord[80];
} OPTIONS;

OPTIONS opt;

// Массив описаний страниц блокнота Wizard
PROPSHEETPAGE   psheetPage[3];

// Заголовок блокнота Wizard
PROPSHEETHEADER psheetHeader;

HINSTANCE hInst;
char szAppName[]  = "WizardApp";
char szAppTitle[] = "Wizard Demo";

// -----------------------------------------------------
// Функция WinMain
// -----------------------------------------------------
int APIENTRY 
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
        LPSTR lpCmdLine, int nCmdShow)
{
  WNDCLASSEX wc;
  HWND hWnd;
  MSG msg;
  
  hInst = hInstance;

  // Преверяем, не было ли это приложение запущено ранее
  hWnd = FindWindow(szAppName, NULL);
  if(hWnd)
  {
    if(IsIconic(hWnd))
	  ShowWindow(hWnd, SW_RESTORE);
	SetForegroundWindow(hWnd);
    return FALSE;
  }

  // Регистрируем класс окна
  memset(&wc, 0, sizeof(wc));
  wc.cbSize = sizeof(WNDCLASSEX);
  wc.hIconSm = LoadImage(hInst,
    MAKEINTRESOURCE(IDI_APPICONSM), IMAGE_ICON, 16, 16, 0);
  wc.style = 0;
  wc.lpfnWndProc = (WNDPROC)WndProc;
  wc.cbClsExtra  = 0;
  wc.cbWndExtra  = 0;
  wc.hInstance = hInst;
  wc.hIcon = LoadImage(hInst,
    MAKEINTRESOURCE(IDI_APPICON), IMAGE_ICON, 32, 32, 0);
  wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
  wc.lpszMenuName = MAKEINTRESOURCE(IDR_APPMENU);
  wc.lpszClassName = szAppName;
  if(!RegisterClassEx(&wc))
    if(!RegisterClass((LPWNDCLASS)&wc.style))
	  return FALSE;
    
  // Создаем главное окно приложения
  hWnd = CreateWindow(szAppName, szAppTitle, WS_OVERLAPPEDWINDOW,
   	 CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInst, NULL);
  if(!hWnd) return(FALSE);

  // Отображаем окно и запускаем цикл обработки сообщений
  ShowWindow(hWnd, nCmdShow);
  UpdateWindow(hWnd);
  while(GetMessage(&msg, NULL, 0, 0))
  {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }
  return msg.wParam;
}

// -----------------------------------------------------
// Функция WndProc
// -----------------------------------------------------
LRESULT WINAPI
WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
  switch(msg)
  {
    HANDLE_MSG(hWnd, WM_CREATE,     WndProc_OnCreate);
    HANDLE_MSG(hWnd, WM_DESTROY,    WndProc_OnDestroy);
    HANDLE_MSG(hWnd, WM_COMMAND,    WndProc_OnCommand);

	default:
      return(DefWindowProc(hWnd, msg, wParam, lParam));
  }
}

// -----------------------------------------------------
// Функция WndProc_OnCreate
// -----------------------------------------------------
BOOL WndProc_OnCreate(HWND hWnd, LPCREATESTRUCT lpCreateStruct)
{
  // Инициализируем библиотеку стандартных органов управления
  InitCommonControls();

  // Инициализируем параметры
  opt.nBold =
  opt.nItalic =
  opt.nUnderline =
  opt.nUseTabs = 0;
  strcpy(opt.szKeyWord, "Undef");

  return TRUE;
}

// -----------------------------------------------------
// Функция WndProc_OnDestroy
// -----------------------------------------------------
#pragma warning(disable: 4098)
void WndProc_OnDestroy(HWND hWnd)
{
  PostQuitMessage(0);
  return 0L;
}

// -----------------------------------------------------
// Функция WndProc_OnCommand
// -----------------------------------------------------
#pragma warning(disable: 4098)
void WndProc_OnCommand(HWND hWnd, int id, 
  HWND hwndCtl, UINT codeNotify)
{
  switch (id)
  {
	case ID_FILE_EXIT:  
	  PostQuitMessage(0); // завершаем работу приложения
	  return 0L;
	  break;
	  
  	case ID_HELP_ABOUT:
      MessageBox(hWnd, 
        "Wizard Demo Application, v.1.0\n"
        "(C) Alexandr Frolov, 1995\n"
        "Email: frolov@glas.apc.org",
        szAppTitle, MB_OK | MB_ICONINFORMATION);
	  return 0L;
	  break;

	case ID_FILE_OPTIONS:  
    {
      // Инициализируем страницы блокнота Wizard
      psheetPage[0].dwSize = sizeof(PROPSHEETPAGE);
      psheetPage[0].hInstance = hInst;
      psheetPage[0].pszIcon = MAKEINTRESOURCE(IDI_EFFECTS);
      psheetPage[0].dwFlags = PSP_USETITLE | PSP_USEICONID;
      psheetPage[0].pszTemplate = 
        MAKEINTRESOURCE(IDD_DIALOG1);
      psheetPage[0].pfnDlgProc = DlgProc1;
      psheetPage[0].pszTitle = "Set Effects";
      psheetPage[0].lParam = 0;

      psheetPage[1].dwSize = sizeof(PROPSHEETPAGE);
      psheetPage[1].hInstance = hInst;
      psheetPage[1].pszIcon = MAKEINTRESOURCE(IDI_TAB);
      psheetPage[1].dwFlags = PSP_USETITLE | PSP_USEICONID;
      psheetPage[1].pszTemplate = 
        MAKEINTRESOURCE(IDD_DIALOG2);
      psheetPage[1].pfnDlgProc = DlgProc2;
      psheetPage[1].pszTitle = "Using Tabs";
      psheetPage[1].lParam = 0;

      psheetPage[2].dwSize = sizeof(PROPSHEETPAGE);
      psheetPage[2].hInstance = hInst;
      psheetPage[2].pszIcon = MAKEINTRESOURCE(IDI_KEYWORD);
      psheetPage[2].dwFlags = PSP_USETITLE | PSP_USEICONID;
      psheetPage[2].pszTemplate = 
        MAKEINTRESOURCE(IDD_DIALOG3);
      psheetPage[2].pfnDlgProc = DlgProc3;
      psheetPage[2].pszTitle = "Keyword";
      psheetPage[2].lParam = 0;

      // Инициализируем заголовок блокнота Wizard
      psheetHeader.dwSize = sizeof(PROPSHEETHEADER);
      psheetHeader.hInstance = hInst;
      psheetHeader.pszIcon = NULL;
      psheetHeader.dwFlags = PSH_PROPSHEETPAGE | PSH_WIZARD;
      psheetHeader.hwndParent = hWnd;
      psheetHeader.pszCaption = "Wizard Demo Sample";
      psheetHeader.nPages = 
        sizeof(psheetPage) / sizeof(PROPSHEETPAGE);
      psheetHeader.ppsp = (LPCPROPSHEETPAGE)&psheetPage;
      
      // Создаем и отображаем блокнот Wizard
      PropertySheet(&psheetHeader);

      return 0L;
	  break;
    }

  	default:
	  break;
  }
  return FORWARD_WM_COMMAND(hWnd, id, hwndCtl, 
    codeNotify, DefWindowProc);
}

// -----------------------------------------------------
// Функция DlgProc1
// для первой страницы блокнота
// -----------------------------------------------------
BOOL APIENTRY
DlgProc1(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
  switch(msg)
  {
    HANDLE_MSG(hdlg, WM_INITDIALOG, DlgProc1_OnInitDialog);
    HANDLE_MSG(hdlg, WM_NOTIFY,     DlgProc1_OnNotify);
	default:
      break;
  }
  return FALSE;
}

// -----------------------------------------------------
// Функция DlgProc1_OnInitDialog
// Вызывается при инициализации первой страницы
// -----------------------------------------------------
BOOL DlgProc1_OnInitDialog(HWND hdlg, 
  HWND hwndFocus, LPARAM lParam)
{
  // Устанавливаем переключатели в соответствии
  // со значениями параметров, записанных в 
  // структуре opt
  SendMessage(GetDlgItem(hdlg, IDC_BOLD), 
    BM_SETCHECK, opt.nBold, 0L);

  SendMessage(GetDlgItem(hdlg, IDC_ITALIC), 
    BM_SETCHECK, opt.nItalic, 0L);

  SendMessage(GetDlgItem(hdlg, IDC_UNDERLINE), 
    BM_SETCHECK, opt.nUnderline, 0L);

  return TRUE;
}

// -----------------------------------------------------
// Функция DlgProc1_OnNotify
// Обрабатывает извещение от первой страницы
// -----------------------------------------------------
LRESULT 
DlgProc1_OnNotify(HWND hdlg, int idFrom, NMHDR* pnmhdr)
{
  switch(pnmhdr->code)
  {
    case PSN_SETACTIVE:
	{
      // Разблокируем кнопку "Next"
      PropSheet_SetWizButtons(GetParent(hdlg), PSWIZB_NEXT);
      break;
    }

    case PSN_WIZNEXT:
	{
      opt.nBold = (int)SendMessage(
        GetDlgItem(hdlg, IDC_BOLD), 
        BM_GETCHECK, 0L, 0L);

      opt.nItalic = (int)SendMessage(
        GetDlgItem(hdlg, IDC_ITALIC), 
        BM_GETCHECK, 0L, 0L);

      opt.nUnderline = (int)SendMessage(
        GetDlgItem(hdlg, IDC_UNDERLINE), 
        BM_GETCHECK, 0L, 0L);
      break;
    }

    default:
      break;
  }
  return FALSE;
}

// -----------------------------------------------------
// Функция DlgProc2
// для второй страницы 
// -----------------------------------------------------
BOOL APIENTRY
DlgProc2(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
  switch(msg)
  {
    HANDLE_MSG(hdlg, WM_INITDIALOG, DlgProc2_OnInitDialog);
    HANDLE_MSG(hdlg, WM_NOTIFY,     DlgProc2_OnNotify);
    default:
      break;
  }
  return FALSE;
}

// -----------------------------------------------------
// Функция DlgProc2_OnInitDialog
// Вызывается при инициализации второй страницы
// -----------------------------------------------------
BOOL DlgProc2_OnInitDialog(HWND hdlg, 
  HWND hwndFocus, LPARAM lParam)
{
  SendMessage(GetDlgItem(hdlg, IDC_USETABS), 
    BM_SETCHECK, opt.nUseTabs, 0L);

  SendMessage(GetDlgItem(hdlg, IDC_DONTUSETABS), 
    BM_SETCHECK, (opt.nUseTabs) ? 0 : 1, 0L);

  return TRUE;
}

// -----------------------------------------------------
// Функция DlgProc2_OnNotify
// Обрабатывает извещение от второй страницы 
// -----------------------------------------------------
LRESULT 
DlgProc2_OnNotify(HWND hdlg, int idFrom, NMHDR* pnmhdr)
{
  switch(pnmhdr->code)
  {
    case PSN_SETACTIVE:
	{
      // Разблокируем кнопк "Next" и "Back", когда страница
      // блокнота Wizard становится активной
      PropSheet_SetWizButtons(GetParent(hdlg), 
        PSWIZB_NEXT | PSWIZB_BACK);
      break;
    }

    case PSN_WIZNEXT:
	{
      opt.nUseTabs = (int)SendMessage(
        GetDlgItem(hdlg, IDC_USETABS), 
        BM_GETCHECK, 0L, 0L);
      break;
    }
    default:
      break;
  }
  return FALSE;
}

// -----------------------------------------------------
// Функция DlgProc3
// для третьей страницы 
// -----------------------------------------------------
BOOL APIENTRY
DlgProc3(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
  switch(msg)
  {
    HANDLE_MSG(hdlg, WM_INITDIALOG, DlgProc3_OnInitDialog);
    HANDLE_MSG(hdlg, WM_NOTIFY,     DlgProc3_OnNotify);
    HANDLE_MSG(hdlg, WM_COMMAND,    DlgProc3_OnCommand);
    default:
      break;
  }
  return FALSE;
}

// -----------------------------------------------------
// Функция DlgProc3_OnInitDialog
// Вызывается при инициализации третьей страницы 
// -----------------------------------------------------
BOOL DlgProc3_OnInitDialog(HWND hdlg, 
  HWND hwndFocus, LPARAM lParam)
{
  SetWindowText(GetDlgItem(hdlg, IDC_EDITKEYWORD), 
    opt.szKeyWord);

  return TRUE;
}

// -----------------------------------------------------
// Функция DlgProc3_OnNotify
// Обрабатывает извещение от третьей страницы 
// -----------------------------------------------------
LRESULT 
DlgProc3_OnNotify(HWND hdlg, int idFrom, NMHDR* pnmhdr)
{
  switch(pnmhdr->code)
  {
    case PSN_SETACTIVE:
	{
      // Разблокируем кнопку "Back", когда страница
      // блокнота становится активной
      PropSheet_SetWizButtons(GetParent(hdlg), PSWIZB_BACK);
      break;
    }
        
    case PSN_WIZFINISH:
	{
      char szBuf[256];
      
      GetWindowText(GetDlgItem(hdlg, IDC_EDITKEYWORD), 
        opt.szKeyWord, 80);

      // Заполнение структуры opt завершено, теперь мы
      // выводим на экран установленные параметры
      wsprintf(szBuf,
        "Bold    \t= %d\n"
        "Italic  \t= %d\n"
        "Underline\t= %d\n"
        "Use Tabs\t= %d\n"
        "Keyword\t= %s\n",
        opt.nBold, opt.nItalic, opt.nUnderline,
        opt.nUseTabs, opt.szKeyWord);

      MessageBox(NULL, szBuf, "Options", 
        MB_OK | MB_ICONINFORMATION);


      break;
    }

    default:
      break;
  }
  return FALSE;
}

// -----------------------------------------------------
// Функция DlgProc3_OnCommand
// -----------------------------------------------------
#pragma warning(disable: 4098)
void DlgProc3_OnCommand(HWND hdlg, int id, 
  HWND hwndCtl, UINT codeNotify)
{
  // Сообщение от редактора текста
  if(id == IDC_EDITKEYWORD)
  {
    // Если пользователь изменил ключевое слово в окне
    // редактирования, разблокируем кнопку "Finish"
    if(codeNotify == EN_CHANGE)
    {
      PropSheet_SetWizButtons(GetParent(hdlg), 
        PSWIZB_BACK | PSWIZB_FINISH);
    }
  }
  return FALSE;
}
