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

HINSTANCE hInst;
char szAppName[]  = "UpDownApp";
char szAppTitle[] = "Up-Down and HotKey Demo";

HWND hwndEdit;
HWND hwndUpDown;
HWND hwndMainWindow;

HWND hwndHotKey;
WORD wHotKey;

// -----------------------------------------------------
// Функция 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);

  // Сохраняем идентификатор главного окна
  hwndMainWindow = hWnd;

  // Отображаем окно и запускаем цикл обработки сообщений
  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);
    HANDLE_MSG(hWnd, WM_SYSCOMMAND, WndProc_OnSysCommand);

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

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

  // Устанавливаем комбинацию клавиш для активизации
  // диалоговой панели <Alt+Ctrl+V>
  SendMessage(hWnd, WM_SETHOTKEY, 
    (WPARAM)MAKEWORD('V', HOTKEYF_ALT | HOTKEYF_CONTROL), 0); 

  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, 
        "Up-Down and HotKey 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:  
    {
      DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG1), 
        NULL, DlgProc);
      return 0L;
	  break;
    }

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

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

// -----------------------------------------------------
// Функция DlgProc_OnInitDialog
// Вызывается при инициализации первой страницы
// -----------------------------------------------------
BOOL DlgProc_OnInitDialog(HWND hdlg, 
  HWND hwndFocus, LPARAM lParam)
{

  // Получаем идентификатор редактора текста
  hwndEdit   = GetDlgItem(hdlg, IDC_EDIT1);
  
  // Создаем орган управления Up-Down и подключаем
  // его к редактору текста. Задаем начальное
  // и конечное значение, инициализируем 
  // редактор текста
  hwndUpDown = CreateUpDownControl(
    WS_CHILD | WS_BORDER | WS_VISIBLE | 
    UDS_WRAP | UDS_ARROWKEYS | UDS_ALIGNRIGHT |
    UDS_SETBUDDYINT, 	
    0, 0, 0, 0, hdlg, IDC_UPDOWN, hInst,
    hwndEdit,10, 1, 1);

  // Получаем идентификатор органа Hot Key
  hwndHotKey = GetDlgItem(hdlg, IDC_HOTKEY);

  // Получаем код комбинации клавиш, которая
  // используется для активизации диалоговой панели
  wHotKey = 
    (WORD)SendMessage(hwndMainWindow, WM_GETHOTKEY, 0, 0); 
  
  
  // Устанавливаем начальное состояние органа Hot Key
  // в соответствии с полученным кодом
  if(wHotKey != 0)
    SendMessage(hwndHotKey, HKM_SETHOTKEY, wHotKey, 0); 

  return TRUE;
}

// -----------------------------------------------------
// Функция DlgProc_OnCommand
// -----------------------------------------------------
#pragma warning(disable: 4098)
void DlgProc_OnCommand(HWND hdlg, int id, 
  HWND hwndCtl, UINT codeNotify)
{
  int nValue;
  char szBuf[80];
  BOOL fError;

  switch (id)
  {
	case IDOK:
    {
      // Определяем и отображаем выбранное значение
      nValue = (int)GetDlgItemInt(hdlg,
        IDC_EDIT1, &fError, FALSE);
      
      wsprintf(szBuf, "Value:\t%d", nValue);

      MessageBox(NULL, szBuf,
        szAppTitle, MB_OK | MB_ICONINFORMATION);
       
	  EndDialog(hdlg, TRUE); 
	  break;
    }

	case IDC_SETHOTKEYBUTTON:
    {
      // Получаем код комбинации клавиш, которая
      // используется для активизации диалоговой панели
      wHotKey = 
        (WORD)SendMessage(hwndHotKey, HKM_GETHOTKEY, 0, 0); 
      
      // Устанавливаем новую комбинацию клавиш для 
      // активизации диалоговой панели 
      SendMessage(hwndMainWindow, WM_SETHOTKEY, wHotKey, 0); 
  	  break;
    }

	case IDCANCEL:
    {
	  EndDialog(hdlg, TRUE); 
	  break;
    }
	  
  	default:
      return FALSE;
  }
  return TRUE;
}

// -----------------------------------------------------
// Функция WndProc_OnSysCommand
// -----------------------------------------------------
#pragma warning(disable: 4098)
void WndProc_OnSysCommand(HWND hwnd, UINT cmd, int x, int y)
{
  // Если пришло сообщение от клавиши активизации,
  // посылаем функции главного окна сообщение WM_COMMAND
  // с кодом, соответствующем строке Options меню File
  // для активизации диалоговой панели
  if(cmd == SC_HOTKEY)
  {
    SendMessage(hwndMainWindow, WM_COMMAND,
     (WPARAM)MAKELONG(ID_FILE_OPTIONS, 0), 0L);
    return 0;
  }
  return FORWARD_WM_SYSCOMMAND(hwnd, cmd, x, y, DefWindowProc);
}
