VR
Virtual Reality On-line   Журнал
Новости   |     Журнал    |    Хаkер    |     Магазин   |   Проекты
[   Вход    ]
[Kарта сайтa]

[ Download  ]
[  Конкурс  ]
[ Анекдоты  ]
[  Ссылки   ]
[  Реклама  ]
[ Почтальон ]
[ О проекте ]






TopList
Visual C++
А я "С", просто "С"
:
Logo

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

Прежде чем приступить, запомни одно правило: "С++ предирчив к регистру". Это значит, что функции Create не create разные вещи, потому что первая буква написана в разных регистрах.

Запусти Visual C++ и создай новый проект. Нашим проектом будет "Win32 Application", а имя проекта "Examp3" (см рис 1). Как только ты всё это указал, жми "ОК".

Logo
Рис 1. Окно нового проекта

Итак, мы запросили Win 32 проект. Это проект без использования объектов MFC и здесь придётся писать руками. Хотя писать мы не будем, мы будем только разбирать код, чтобы понять основы работы Windows приложений.

Кстати, сейчас перед нами уже тасуется следующее окно (рис 2). Здесь мы выберем пункт "A typical "Hallo World!" application". Как все любят этот "Hallo World". Хотя мне всё по барабану. Выбирай его и жми Finish .

Logo
Рис 2. Мастер создания Win32 приложения

Можешь запустить полученный пример и посмотреть на результат. Для этого нажми Ctrl+F5 или выбери "Execute" из меню "Build".
Logo
Рис 3. Левая панель

После того, как наиграешься первой прогой, возвращайся в среду разработки Visual C++. Осмотрись. Слева находится панель, как на рис 3. Внизу панели есть три закладки:

  • ClassView - здесь тебе наглядно представлены все глобальные переменные и функции.
  • ResourceView - здесь представлены все ресурсы используемые в проге. К ним относятся менюшки, диалоги, иконки и т.д.
  • FileView - здесь перечислены все файлы проекта. Так как проект может состоять из нескольких файлов, то переключаться между ними очень удобно на этой закладке.

Сегодня мы немного поработаем с ресурсами, но только немного. Так что перейди на эту закладку и дважды щёлкни по группе String Table . Эта ветка должна раскрыться и ты увидишь пункт String Table (Neutral) . Это таблица строк. В такой таблице хранятся различные строки (константы строк). Их очень удобно выносить в ресурсы, чтобы потом можно было легко изменить, особенно при локализации твоей будущей проги.
Logo
Рис 4. Редактор таблицы строк

Дважды кликни по String Table (Neutral) и у тебя откроется окно как на рис 4. Только у меня ресурсы уже подкорректированы. Первая строка IDS_APP_TITLE используется в проге как заголовок примера. Вторую строку IDS_HELLO мы выводим в окно.

Я изменил текст, который выводится внутри окна. Для этого я дважды щёлкнул по строке, и в появившемся окне (рис 5) изменил параметр Caption .
Logo
Рис 5. Свойства строки

Теперь ты снова можешь запустить пример и посмотреть на результат.

Пока что с ресурсами хватит. Сейчас мы перейдём к самому коду. Перейди на закладку FileView и дважды щёлкни по группе Source Files . Перед тобой открылось три файла:

  • Examp3.cpp - В этом файле расположен основной код проги.
  • Examp3.rc - в RC файлах хранятся ресурсы.
  • stdafx.cpp - Пока не будем трогать, потому что он всё равно пустой.

Открой (двойным щелчком) файл Examp3.cpp. Давай рассмотрим исходник.

//Подключение модулей
#include "stdafx.h"
#include "resource.h"

//Объявление константы MAX_LOADSTRING со значением 100. 
//Теперь, вместо цифры 100 можно писать MAX_LOADSTRING.
#define MAX_LOADSTRING 100

// Объявление глобальных переменных:
HINSTANCE hInst;				// Экземпляр класса
TCHAR szTitle[MAX_LOADSTRING];	// Заголовок окна
TCHAR szWindowClass[MAX_LOADSTRING];	// Класс окна

// Объявление функций используемых в файле:
ATOM				MyRegisterClass(HINSTANCE hInstance);
BOOL				InitInstance(HINSTANCE, int);
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK	About(HWND, UINT, WPARAM, LPARAM);

//Первая процедура. 
int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
 {
  MSG msg;
  HACCEL hAccelTable;

  // Загружаем строки IDS_APP_TITLE и IDC_EXAMP3 из ресурсов StringTable
  LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
  LoadString(hInstance, IDC_EXAMP3, szWindowClass, MAX_LOADSTRING);

  //Регистрируем новый класс окна.
  MyRegisterClass(hInstance);

  //Вызываем функцию InitInstance, которая инициализирует новое окно.
  if (!InitInstance (hInstance, nCmdShow)) 
  {
    return FALSE;
  }

  //Загружаем из ресурсов таблицу горячих клавиш 
  hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_EXAMP3);

  // Цикл обработки сообщений:
  while (GetMessage(&msg, NULL, 0, 0)) 
   {
     if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
      {
       TranslateMessage(&msg);
       DispatchMessage(&msg);
      }
    }
  return msg.wParam;
}



//Функция MyRegisterClass, которая регистрирует новый класс окна. 
//Мы эту функцию вызываем в WinMain
ATOM MyRegisterClass(HINSTANCE hInstance)
{
//Объявляем переменную wcex типа WNDCLASSEX
 WNDCLASSEX wcex;

// WNDCLASSEX – это структура, поэтому мы должны заполнить
// все её поля
 wcex.cbSize = sizeof(WNDCLASSEX); //Размер структуры
 wcex.style= CS_HREDRAW | CS_VREDRAW; //Стиль будущего окна
 wcex.lpfnWndProc= (WNDPROC)WndProc; //Функция-обработчик сообщений
 wcex.cbClsExtra = 0;//Пока умолчу
 wcex.cbWndExtra= 0;
 wcex.hInstance= hInstance;//Класс окна
 wcex.hIcon= LoadIcon(hInstance, (LPCTSTR)IDI_EXAMP3); //Иконка окна
 wcex.hCursor	= LoadCursor(NULL, IDC_ARROW);//Курсор окна
 wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);//Цвет фона
 wcex.lpszMenuName= (LPCSTR)IDC_EXAMP3;//Меню
 wcex.lpszClassName	= szWindowClass;//Имя класса окна
 wcex.hIconSm= LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);//Маленькая иконка.

//Регистрируем новый класс окна, с параметрами установленными в wcex
 return RegisterClassEx(&wcex);
}

//Создание окна
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
 //Переменная указатель на окно
 HWND hWnd;

 hInst = hInstance; 

 hWnd = CreateWindow (
           szWindowClass, //Зарегистрированный класс окна
           szTitle, //Заголовок окна
           WS_OVERLAPPEDWINDOW, //Стиль окна
           100, 100, //Левый, верхний угол. 
           300, 200, //Ширина, высота
           NULL, //Дескриптор родительского окна
           NULL, // Дескриптор меню
           hInstance, //Дескриптор экземпляра окна
           NULL//Параметры создания
       );

   
//Проверяем на правильность созданного окна
 if (!hWnd)
  {
   return FALSE;
  }


   ShowWindow(hWnd, nCmdShow); //Показать окно
   UpdateWindow(hWnd); //Обновить его содержимое

   return TRUE;
}

//Функция обработчик сообщений окна.
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
 //Объявляем переменные
 int wmId, wmEvent;
 PAINTSTRUCT ps;
 HDC hdc;
 TCHAR szHello[25];
 LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);

// Проверяем, каеое событие произошло
 switch (message) 
  {
   case WM_COMMAND://Выбран пункт меню
    wmId    = LOWORD(wParam); 
    wmEvent = HIWORD(wParam); 
    
      switch (wmId)//Проверяем, какой именно пункт
       {
        case IDM_ABOUT://Если пункт меню About, то показать окно
          DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
          break;
	case IDM_EXIT:
	  DestroyWindow(hWnd);
	  break;
	default:
	 return DefWindowProc(hWnd, message, wParam, lParam);
       }
      break;
    case WM_PAINT://Нужна прорисовка окна
     hdc = BeginPaint(hWnd, &ps);//Начало рисования
     RECT rt;
     GetClientRect(hWnd, &rt);//Возвращаем размер окна
     DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER);//Рисуем текст
     EndPaint(hWnd, &ps);//Конец рисования
     break;
    case WM_DESTROY://Уничтоженение окна
     PostQuitMessage(0);
     break;
    default:
     return DefWindowProc(hWnd, message, wParam, lParam);
   }
  return 0;
}

//Функция обработчик сообщений окна About (О программе). 
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
 switch (message)
  {
   case WM_INITDIALOG://Создаётся окно
    return TRUE;
   
   case WM_COMMAND:
    if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) 
     {
      EndDialog(hDlg, LOWORD(wParam));
      return TRUE;
     }
    break;
  }
 return FALSE;
}

С большинством происходящего можно разобратся по коментариям. Я только остановлюсь на некоторых моментах.

Самая главная функция здесь - это WinMain. Эта функция обязательна, потому что выполнение программы начинается именно с неё.

Когда мы начнём писать проги с использованием MFC, WinMain будет отсутствовать, но только для твоего взгляда. На самом деле эта функция присутствует всегда.

Работа моей проги начинается с того, что я загружаю строки из ресурсов. После этого, я вызываю свою функцию MyRegisterClass, в которой происходит регистрация нового класса окна (RegisterClassEx).

После этого я взываю свою функцию InitInstance, в которой я создаю окно CreateWindow с зарегистрированным классом и отображаю её.

После этого я запускаю цикл обработки сообщений:

 while (GetMessage(&msg, NULL, 0, 0))
  {
   if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
    {
     TranslateMessage(&msg);
     DispatchMessage(&msg);
    }
  }

Этот цикл постоянно проверяет сообщения Windows (GetMessage) и запускает их обработку (TranslateMessage и DispatchMessage).

В самой программе есть специальная функция-обработчик событий WndProc. Она вызывается каждый раз, когда происходит какое-то событие. Здесь я проверяю, какое событие произошло. Если меня оно интересует, то я его обрабатываю. Если событие не обработано, то вызывается DefWindowProc - обработчик событий Windows по умолчанию, который действует по своему усмотрению.

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

 Исходники примера забирай здесь

При открытии исходника, выбери в окне тип файла "Workspaces" и открывай мой файл с расширением dsw. Так ты откроешь весь проект, а не один C++ файл.


Design by FMk group ©
Copyright©: Horrific aka Флёнов Михаил ©