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

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

HINSTANCE hInst;
char szAppName[]  = "RclockApp";
char szAppTitle[] = "Remote Clock";

// Метрики шрифта с фиксированной шириной символов
LONG cxChar, cyChar;

RECT rc;
char szBuf[80];

// -----------------------------------------------------
// Функция 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_POPUPWINDOW | WS_THICKFRAME, 
     100, 100, 100, 100, 
     NULL, NULL, hInst, NULL);
  if(!hWnd) return(FALSE);

  // Размещаем окно в нижней левой части рабочего стола
  GetWindowRect(GetDesktopWindow(), &rc);

  MoveWindow(hWnd,
    rc.right  - cxChar * 25,
    rc.bottom - cyChar * 3,
    cxChar * 10, cyChar * 2, TRUE);
    
  // Отображаем окно и запускаем цикл 
  // обработки сообщений
  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)
  {
    // Это сообщение посылается приложением STIME
    case WM_COPYDATA:
    {
      // Копируем данные, полученные от приложения STIME,
      // во внутренний буфер
      strcpy(szBuf, ((PCOPYDATASTRUCT)lParam)->lpData);

      // Перерисовываем содержимое окна, отображая в нем
      // полученную строку символов
      InvalidateRect(hWnd, NULL, TRUE);
      break;
    }

    HANDLE_MSG(hWnd, WM_CREATE,  WndProc_OnCreate);
    HANDLE_MSG(hWnd, WM_DESTROY, WndProc_OnDestroy);
    HANDLE_MSG(hWnd, WM_PAINT,   WndProc_OnPaint);

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

// -----------------------------------------------------
// Функция WndProc_OnCreate
// -----------------------------------------------------
BOOL WndProc_OnCreate(HWND hWnd, 
                      LPCREATESTRUCT lpCreateStruct)
{
  HDC hdc;
  TEXTMETRIC tm;
  
  hdc = GetDC(hWnd);
  
  // Выбираем в контекст отображения шрифт с фиксированной
  // шириной букв
  SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));

  // Определяем и сохраняем метрики шрифта
  GetTextMetrics(hdc, &tm);

  cxChar = tm.tmMaxCharWidth;
  cyChar = tm.tmHeight + tm.tmExternalLeading;
  
  ReleaseDC(hWnd, hdc);

  // Выполняем инициализацию буфера szBuf, содержимое
  // которого отображается в окне приложения
  strcpy(szBuf, (LPSTR)"<Unknown>");
 
  return TRUE;
}

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

// -----------------------------------------------------
// Функция WndProc_OnPaint
// -----------------------------------------------------
#pragma warning(disable: 4098)
void WndProc_OnPaint(HWND hWnd)
{
  HDC hdc;
  PAINTSTRUCT ps;
  RECT rc;

  // Перерисовываем внутреннюю область окна
  hdc = BeginPaint(hWnd, &ps);
  
  GetClientRect(hWnd, &rc);

  // Рисуем в окне строку символов, полученную от
  // приложения STIME
  DrawText(hdc, szBuf, -1, &rc,
    DT_SINGLELINE | DT_CENTER | DT_VCENTER);

  EndPaint(hWnd, &ps);
  return 0;
}
