Программа для племянниц: ABC, часть 1


Автор: Рэймонд Чен.
Оригинал статьи: A program for my nieces: The ABCs, part 1.

В ближайшие недели я буду писать про маленькую программу из нескольких частей. Эту программу я написал для своих племянниц, которым нравится играть с моим ноутбуком (а не со мной).

Сначала я запускал Блокнот, разворачивал его и менял размер шрифта, но это стало утомлять, потому что после окончания игры мне надо было восстановить размер шрифта и Перенос по словам. В добавление к этому старшая племянница пожаловалась, что некоторые буквы «неправильные»: заглавная J в шрифте, который я использую, не похожа на ту, которую она изучала (дело было в верхней засечке).

Необходимость смены и последующего восстановления шрифта стала достаточным стимулом для написания собственной программы. Я начал с шаблона программы и сделал следующие изменения:

HFONT g_hfEdit;

#define MARGIN 20

void
OnSize(HWND hwnd, UINT state, int cx, int cy)
{
  if (g_hwndChild) {
    MoveWindow(g_hwndChild,
               MARGIN, MARGIN,
               cx - 2 * MARGIN,
               cy - 2 * MARGIN, TRUE);
  }
}

Текстовое поле окружено «полями», чтобы не «прилипать» к краям экрана.

void
OnNcDestroy(HWND hwnd)
{
  if (g_hfEdit) DeleteObject(g_hfEdit);
  PostQuitMessage(0);
}
...
//HANDLE_MSG(hwnd, WM_DESTROY, OnDestroy);
HANDLE_MSG(hwnd, WM_NCDESTROY, OnNcDestroy);

Очистка шрифта выполняется в обработчике WM_NC­DESTROY, потому что он запускается после уничтожения дочерних окон. Мы не уничтожаем шрифт, пока он используется текстовым полем.

BOOL
OnCreate(HWND hwnd, LPCREATESTRUCT lpcs)
{
  g_hfEdit = CreateFont(-72, 0, 0, 0, FW_NORMAL,
                        FALSE, FALSE, FALSE, DEFAULT_CHARSET,
                        OUT_DEFAULT_PRECIS,
                        CLIP_DEFAULT_PRECIS,
                        DEFAULT_QUALITY,
                        DEFAULT_PITCH,
                        TEXT("Miriam"));
  if (!g_hfEdit) return FALSE;

  g_hwndChild = CreateWindow(
      TEXT("edit"),                   /* Имя класса */
      NULL,                           /* Заголовок */
      WS_CHILD | WS_VISIBLE |
      ES_UPPERCASE | ES_MULTILINE,    /* Стиль */
      0, 0, 0, 0,                     /* Положение и размер */
      hwnd,                           /* Parent */
      NULL,                           /* Без меню */
      g_hinst,                        /* Instance */
      0);                             /* No special parameters */
  if (!g_hwndChild) return FALSE;

  SetWindowFont(g_hwndChild, g_hfEdit, TRUE);

  return TRUE;
}

Во время создания главного окна мы создаём многострочное текстовое поле без полос прокрутки с отображением содержимого заглавными буквами, поскольку мои племянницы ещё не изучали строчные буквы.

Моя программа ничего не рисует, поэтому я удалили обработчики WM_PAINT и WM_PRINT­CLIENT.

С другой стороны, ей надо передать фокус текстовому полю, поэтому программа сразу переходит в режим набора текста:

void OnSetFocus(HWND hwnd, HWND hwndOldFocus)
{
  if (g_hwndChild) {
    SetFocus(g_hwndChild);
  }
}
...
HANDLE_MSG(hwnd, WM_SETFOCUS, OnSetFocus);

Наконец, я создаю полноэкранное всплывающее окно, так что мои племянницы получают чистый экран.

hwnd = CreateWindow(
   TEXT("Scratch"),                /* Имя класса */
   TEXT("ABC"),                    /* Заголовок */
   WS_POPUP,                       /* Стиль */
   0, 0,                           /* Положение */
   GetSystemMetrics(SM_CXSCREEN),
   GetSystemMetrics(SM_CYSCREEN),  /* Размер */
   NULL,                           /* Parent */
   NULL,                           /* Без меню */
   hinst,                          /* Instance */
   0);                             /* No special parameters */

Вот и готова простая программа с текстовым полем, в котором мои племянницы могут набирать буквы.

Они назвали эту программу ABC. Теперь, когда я прихожу к ним домой, они спрашивают, «Можно поиграть в ABC?»

Программа хорошо работала первое время, но мои племянницы обнаружили в ней несколько проблем. Мы поговорим о них в ближайшие недели.

Поскольку это маленькая программка, я пропускаю проверку ошибок и предполагаю, что в системе лишь один монитор (потому что она работает на моём ноутбуке).

Реклама
Запись опубликована в рубрике перевод, программирование с метками . Добавьте в закладки постоянную ссылку.

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s