Элементы управления окна

Создание Windows-приложений / Элементы управления окна

Главным элементом программы в среде Windows является окно. Окно может содержать элементы управления: кнопки, списки, окна редактирования и др. Эти элементы также являются окнами, но обладающими особым свойством: события, происходящие с этими элементами (и самим окном), приводят к приходу сообщений в процедуру окна.

Системный класс Предназначение
  BUTTON   Кнопка.
  COMBOBOX   Комбинированное окно (окно со списком и поля выбора).
  EDIT   Окно редактирования текста.
  LISTBOX   Окно со списком
  SCROLLBAR   Полоса прокрутки
  STATIC   Статический элемент (текст)

Создание элементов управления окна  осуществляется функцией

HWND WINAPI CreateWindow(
  _In_opt_ LPCTSTR lpClassName, // имя предопределенного класса
  _In_opt_ LPCTSTR lpWindowName, // текст
  _In_ DWORD dwStyle, // стиль
  _In_ int x, // координата x
  _In_ int y, // координата y
  _In_ int nWidth, // ширина
  _In_ int nHeight, // высота
  _In_opt_ HWND hWndParent, // дескриптор родительского окна
  _In_opt_ HMENU hMenu, // номер пункта меню
  _In_opt_ HINSTANCE hInstance, // дескриптор приложения
  _In_opt_ LPVOID lpParam ); // NULL

Указанная функция возвращает дескриптор элемента управления окна, который может быть впоследствии использован для анализа элемента управления, с которым связано обрабатываемое событие. Дескриптор кнопки, например, передается в оконную функцию в качестве параметра lparam.

Таблицу стилей элементов управления окна можно  устанавливать в параметре dwStyle как и для создания родительского окна. При этом обязательно указывается, что создаваемое окно является дочерним - WS_CHILD.

Кнопка

Кнопка - маленькое прямоугольное дочернее окно, которое представляет собой кнопку, по которой пользователь может щелкать мышью, чтобы включить или выключить ее. Кнопки управления могут использоваться самостоятельно или в группах, и они могут или быть подписаны или появляться без текста. Кнопки управления обычно изменяют свой вид, когда пользователь щелкает мышью по ним.
Кнопка
При нажатии кнопки операционная система генерирует сообщение WM_COMMAND с параметром lParam, соответствующим дескриптору кнопки.

Обработка нажатия кнопки:

LONG WINAPI WndProc(HWND hwnd, UINT Message, WPARAM wparam, LPARAM lparam) {
  ...
  switch (Message) {
    case WM_COMMAND:
      if(lparam == (LPARAM)hBtn) {
        //обработка нажатия кнопки
      }
      break;
    ...
  }
}

Поле редактирования

Поле редактирования - прямоугольное дочернее окно, внутри которого пользователь может напечатать с клавиатуры текст. Пользователь выбирает орган управления и дает ему фокус клавиатуры, щелкая по нему мышью или перемещая в него, каретку путем нажатия клавиши ТАБУЛЯЦИИ (TAB). Пользователь может вводить текст, когда окно редактирования текста отображает мигающую каретку.
edit

Для считывания информации из поля редактирования используется функция

int WINAPI GetWindowText(
_In_   HWND hWnd,   // дескриптор поля
_Out_  LPTSTR lpString,   // указатель на текстовую строку
_In_   int nMaxCount );       // максимальное количество символов

Возвращаемое значение – длина считанной текстовой строки.

Для установки текста в поле редактирования используется функция

BOOL WINAPI SetWindowText(
_In_      HWND hWnd,   // дескриптор поля
_In_opt_  LPCTSTR lpString ); // указатель на текстовую строку

В случае успешного завершения функция возвращает ненулевое значение.

Статический текст

Статический текст - текстовое поле, окно или прямоугольник, используемый для надписей, не подлежащих редактированию.

Для установки статического текста используется та же функция SetWindowText.

Пример Найти сумму двух чисел
Программа создает два поля редактирования для ввода чисел и кнопку "Рассчитать", при нажатии на которую выводится статический текст, соответствующий сумме.
Для перевода строки в целое число и обратно использованы функции StrToInt и IntToStr, описанные в статье Преобразование строки в число и обратно. Также использовалась многобайтовая кодировка.

#include <windows.h>
LONG WINAPI WndProc(HWND, UINT, WPARAM, LPARAM);
int StrToInt(char *s) {...}
char* IntToStr(int n) {...}
// Стартовая функция
int  WINAPI  WinMain(HINSTANCE  hInstance,
HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
  HWND hwnd;
  MSG msg;
  WNDCLASS w;
  memset(&w, 0, sizeof(WNDCLASS)); // очистка памяти для структуры
  w.style = CS_HREDRAW | CS_VREDRAW;
  w.lpfnWndProc = WndProc;
  w.hInstance = hInstance;
  w.hbrBackground = CreateSolidBrush(0x00FFFFFF);
  w.lpszClassName = "MyClass";
  RegisterClass(&w);
  hwnd = CreateWindow("MyClass","Сумма двух чисел",
    WS_OVERLAPPEDWINDOW,
    500, 300, 500, 380,
    NULL, NULL, hInstance, NULL);
  ShowWindow(hwnd, nCmdShow);
  UpdateWindow(hwnd);
  while (GetMessage(&msg, NULL, 0, 0)) {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }
  return msg.wParam;
}
LONG WINAPI WndProc(HWND hwnd, UINT Message,
  WPARAM wparam, LPARAM lparam) {
  HDC hdc;
  HINSTANCE hInst;
  PAINTSTRUCT ps;
  static HWND hBtn; // дескриптор кнопки
  static HWND hEdt1, hEdt2; // дескрипторы полей редактирования
  static HWND hStat; // дескриптор статического текста
  TCHAR StrA[20];
  int a, b, sum, Len;
  switch (Message) {
    case WM_CREATE:
      hInst = ((LPCREATESTRUCT)lparam)->hInstance;
      hEdt1 = CreateWindow("edit", "0",
        WS_CHILD | WS_VISIBLE | WS_BORDER | ES_RIGHT, 50, 50, 60, 20,
        hwnd, 0, hInst, NULL);
      ShowWindow(hEdt1, SW_SHOWNORMAL);
      hEdt2 = CreateWindow("edit", "0",
        WS_CHILD | WS_VISIBLE | WS_BORDER | ES_RIGHT, 150, 50, 60,
        20, hwnd, 0, hInst, NULL);
      ShowWindow(hEdt2, SW_SHOWNORMAL);
      hBtn = CreateWindow("button", "Рассчитать",
        WS_CHILD | WS_VISIBLE | WS_BORDER,
        50, 100, 120, 30, hwnd, 0, hInst, NULL);
      ShowWindow(hBtn, SW_SHOWNORMAL);
      hStat = CreateWindow("static", "0",WS_CHILD | WS_VISIBLE,
        150, 180, 120, 20, hwnd, 0, hInst, NULL);
      ShowWindow(hStat, SW_SHOWNORMAL);
      break;
    case WM_COMMAND:
      if (lparam == (LPARAM)hBtn) {
        Len = GetWindowText(hEdt1, StrA, 20);
        a = StrToInt(StrA);
        Len = GetWindowText(hEdt2, StrA, 20);
        b = StrToInt(StrA);
        sum = a + b;
        SetWindowText(hStat, IntToStr(sum));
      }
      break;
    case WM_PAINT:
      hdc = BeginPaint(hwnd, &ps);
      TextOut(hdc, 50, 20, "Введите два числа", 18);
      TextOut(hdc, 50, 180, "Результат:", 10);
      EndPaint(hwnd, &ps);
      break;
    case WM_DESTROY:
      PostQuitMessage(0);
      break;
    default:
      return DefWindowProc(hwnd, Message, wparam, lparam);
  }
  return 0;
}

Результат выполнеия
Сумма двух чисел

Назад

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

Ваш e-mail не будет опубликован. Обязательные поля помечены *