// ==================================================
// Приложение STIME (работает вместе с приложением RTIME)
// Демонстрация использования сообщения WM_COPYDATA
// для передачи данных между процессами
//
// (С) Фролов А.В., 1996
// Email: frolov@glas.apc.org
// ==================================================

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

HINSTANCE hInst;
char szAppName[]  = "StimeApp";
char szAppTitle[] = "Time Sender";

// Имя приложения RTIME
char szServerAppName[]  = "RclockApp";

// Идентификатор главного окна приложения RTIME
HWND hWndServer;

// Структура для передачи данных между процессами
// при помощи сообщения WM_COPYDATA
COPYDATASTRUCT cd;

// Буферы для передаваемых данных
char szBuf[80];
char szTerminated[] = "<Terminated>";

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

  // Ищем окно серверного приложения RTIME и сохраняем
  // его идентификатор
  hWndServer = FindWindow(szServerAppName, NULL);
  if(hWndServer == NULL)
  {
    // Если окно серверного приложения не найдено,
    // выводим сообщение об ошибке и завершаем работу
    // приложения
    MessageBox(NULL, "Server RTIME not found", szAppName,
      MB_ICONEXCLAMATION | MB_OK); 
    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_TIMER,   WndProc_OnTimer);
    HANDLE_MSG(hWnd, WM_CREATE,  WndProc_OnCreate);
    HANDLE_MSG(hWnd, WM_DESTROY, WndProc_OnDestroy);

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

// -----------------------------------------------------
// Функция WndProc_OnCreate
// -----------------------------------------------------
BOOL WndProc_OnCreate(HWND hWnd, 
                      LPCREATESTRUCT lpCreateStruct)
{
  // Создаем таймер с периодом работы 1 сек
  SetTimer(hWnd, CLOCK_TIMER, 1000, NULL);
  return TRUE;
}

// -----------------------------------------------------
// Функция WndProc_OnTimer
// -----------------------------------------------------
#pragma warning(disable: 4098)
void WndProc_OnTimer(HWND hWnd, UINT id)
{
  time_t t;
  struct tm *ltime;

  // Определяем текущее время
  time(&t);
  ltime = localtime(&t);

  // Формируем текстовую строку времени
  wsprintf(szBuf, "%02d:%02d:%02d",
    ltime->tm_hour, ltime->tm_min,ltime->tm_sec);

  // Записываем адрес и размер строки в структуру
  // типа COPYDATASTRUCT
  cd.lpData = szBuf;
  cd.cbData = strlen(szBuf) + 1;

  // Посылаем сообщение серверному приложению RCLOCK
  SendMessage(hWndServer, WM_COPYDATA, (WPARAM)hWnd, (LPARAM)&cd);
  return 0;
}

// -----------------------------------------------------
// Функция WndProc_OnDestroy
// -----------------------------------------------------
#pragma warning(disable: 4098)
void WndProc_OnDestroy(HWND hWnd)
{
  // Перед завершением работы приложения передаем
  // серверу строку <Terminated>
  cd.lpData = szTerminated;
  cd.cbData = strlen(szTerminated) + 1;

  SendMessage(hWndServer, WM_COPYDATA, (WPARAM)hWnd, (LPARAM)&cd);

  // Удаляем таймер
  KillTimer(hWnd, CLOCK_TIMER);

  PostQuitMessage(0);
  return 0L;
}
