Школа создателей компьютерных игр

BannerDrive.ru
[Главная] [С чего начать?] [Дистанционное обучение] [Статьи] [Обучалки] [Книги] [Софт] [Форум] [Ссылки] [О сайте]

Окно редактирования



Подпишитесь на рассылку "Создание компьютерных игр"

Рассылки Subscribe.Ru
Создание компьютерных игр

Рассылка выходит раз в месяц.


Понравился сайт? Узнайте, как помочь сайту.


Рекомендуемые книги


Андре Ламот.
Программирование трехмерных игр для Windows. Советы профессионала по трехмерной графике и растеризации


Андре Ламот.
Программирование игр для Windows. Советы профессионала


Проголосуйте за сайт в рейтинге GameTop!
(нажмите на кнопку рейтинга)

GameTop - рейтинг игровых ресурсов. Портал Rolemancer (www.rolemancer.ru)

Не забывайте, что результаты рейтинга обновляются раз в неделю. Пожалуйста, голосуйте почаще!


Статистика посещаемости

Rambler's Top100

Открытие файлов диалоговым окном | Все обучалки раздела | Загрузка изображения

Описание

Обучалка рассматривает, как использовать окно редактирования для создания простейшего текстового редактора.

Программа представляет собой простейший редактор наподобие NotePad с возможностью набора текста, сохранения и загрузки файла.

Скачать обучалку (Visual C++ 6)

Работа программы

Исходный код

// Done by TheTutor -- 7/26/01 (Updated Last: 9/29/02)
// Перевод © 2005 Евгений Казеко
// www.gamecoder.kazeko.com
// evgeniy@kazeko.com

/*      Мы собираемся сделать очень простую версию редактора NotePad.
      Тема, на которой мы будем фокусироваться, это "окно редактирования" и
      загрузка/сохранение текста в окне. Мы назовем файл для загрузки и
      сохранения "OurFile.txt".
*/

#include <windows.h>
#include <string.h>
#include <stdio.h>
#include "resource.h"

#define classname "GameTutorials_notepad" 

#define EDIT_BOX 0x00EB // Ссылка на окно редактирования

// Ширина и высота окна
#define WIN_WIDTH 640
#define WIN_HEIGHT 480      

// Глобальные переменные
HWND edit_box = NULL; // Ссылка на окно редактирования, которое мы создадим

// Стандартная WinProc
LRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);

// WinMain
int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprev, PSTR cmdline, int ishow)
{
    HWND hwnd;
    MSG msg;
    WNDCLASSEX wndclassex = {0}; // Оконный класс
    HMENU menu = NULL;               // Ссылка на меню

    // Заполняем необходимые поля
    wndclassex.cbSize = sizeof(WNDCLASSEX);
    wndclassex.style = CS_HREDRAW | CS_VREDRAW;
    wndclassex.lpfnWndProc = WinProc;
    wndclassex.hInstance = hinstance;
    wndclassex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wndclassex.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wndclassex.lpszClassName = classname;

      // Загружаем меню
      menu = LoadMenu(hinstance,MAKEINTRESOURCE(IDR_MENU1));

            // Проверка ошибки
            if(!menu)
                  return EXIT_FAILURE;

    RegisterClassEx(&wndclassex);

    hwnd = CreateWindowEx(WS_EX_APPWINDOW,
                                      classname,
                                      "EditBoxes",
                                      WS_OVERLAPPEDWINDOW,
                                      CW_USEDEFAULT,
                                      CW_USEDEFAULT,
                                      WIN_WIDTH,
                                      WIN_HEIGHT,
                                      NULL,
                                      menu, // Мы создаем окно с меню
                                      hinstance,
                                      NULL);

            // Проверка ошибки
            if(!hwnd)
            {
                  UnregisterClass(classname,hinstance); // Разрегистрируем WNDCLASSEX
                  DestroyMenu(menu); // Освобождаем меню
                        return EXIT_FAILURE; 
            }

    // Выводим и обновляем окно
    ShowWindow(hwnd, ishow);
    UpdateWindow(hwnd);

    // Цикл сообщений
    while(1)
      {
            // Если есть сообщение, обрабатываем его
            if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
            {
                  // Если выражение истинно - программа завершена
                  if(msg.message == WM_QUIT)
                        break;
                  
                  TranslateMessage(&msg);
                  DispatchMessage(&msg);
            }
            else
            {
                  ;// Здесь проводим все сложные расчеты, если они понадобятся
            }
      }


      UnregisterClass(classname,hinstance); // Разрегистритуем WNDCLASSEX
      DestroyMenu(menu); // Освобождаем меню

    return msg.wParam; // Код возврата (завершилась ли программа корректно?)
}


// WinProc
LRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
    // Выполняем действия в зависимости от "message"
    switch(message)
    {
        case WM_CREATE:
            {

                  RECT rect;

                  // Сперва мы получаем клиент-область окна. Мы будем использовать ее
                  // для создания окна редактирования
                  GetClientRect(hwnd,&rect);
         
                  // -- Создаем окно редактирования -- //

                  /* Что здесь происходит? Рассмотрим шаг за шагом:
                  1)      Первый параметр означает, что мы создаем заданный тип окна - окно редактирования.
                  2)      Второй параметр указывает "текст по умолчанию" окна редактирования (NULL
                        означает, что его нет).
                  3)    Третий параметр (WS_CHILD) указывает, что это окно редактирования будет
                        принадлежать родительскому окну, что означает, что они будут иметь общую
                        WinProc().
                        Значение остальных параметров:
                        WS_VISIBLE -- окно видимое,
                        ES_AUTOHSCROLL -- автоматически прокручивать вправо, когда пользователь
                                                  достигает конца строки
                        ES_AUTOVSCROLL -- автоматически прокручивать текст на страницу вверх,
                                                  когда пользователь нажимает "enter" в конце страницы
                        ES_LEFT -- выравнивать текст по левому краю,
                        ES_MULTILINE -- разрешить несколько строк
                        ES_NOHIDESEL -- запретить "поведение по умолчанию" окна редактирования,
                                                (оно не будет спрятано, когда оно неактивно)
                        ES_WANTRETURN -- когда пользователь нажимает "enter", он будет функционировать
                                                 как "возврат каретки"
                        WS_VSCROLL - вертикальная строка прокрутки,
                        WSHSCROLL -- горизонтальная строка прокрутки
                        WS_BORDER -- у окна редактирования будет тонкая рамка
                  4)      0, 0 -- положение верхнего левого угла окна редактирования по отношению к
                                    родительскому окну
                  5)      rect.right -- ширина окна редактирования
                  6)      rect.bottom -- высота окна редактирования
                  6)      hwnd -- ссылка на родительское окно
                  7)      (HMENU)EDIT_BOX -- способ определить наше окно редактирования (просто число)
                  8)      Сначала посмотрите на CreateWindow() в WinMain(), обратите внимание как мы
                        передавали в функцию hinstance.  Нам нужно передать это значение и здесь.
                        Но если вы посмотрите на WinProc(), вы увидите, что мы не передаем в нее
                        эту переменную, поэтому у нас нет к ней доступа. Это не совсем верно.
                        Если вы попробуете просто передать "hinstance", программа не будет компилироваться.
                        Но у нас есть значение "hinstance", спрятанное в "lparam". -- Преобразованием
                        типа "lparam" в LPCREATESTRUCT, мы можем извлечь из него "hinstance".
                  9)      NULL -- Этот параметр используется для передачи "дополнительной информации", но у нас ее нет.
                  */
                  edit_box = CreateWindow("EDIT",NULL,WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL |
                                                      ES_AUTOVSCROLL | ES_LEFT | ES_MULTILINE | ES_NOHIDESEL |
                                                      WS_VSCROLL | WS_HSCROLL | WS_BORDER | ES_WANTRETURN,
                                                      0, 0, rect.right, rect.bottom, hwnd, (HMENU)EDIT_BOX,
                                                      ((LPCREATESTRUCT)lparam)->hInstance, NULL);

                  return 0;
            }

       case WM_COMMAND:
         {
               // Если выбран пункт меню "Load"
               if(LOWORD(wparam) == LoadFile)
               {
                     FILE *file = NULL;
                     fpos_t length = 0; // Используется для записи длины файла
                     char *buff = NULL; // Символьный буфер, используется для хранения загружаемого текста.

                     file = fopen("OurFile.txt","rb");

                              // Проверка ошибки
                              if(!file)
                              {
                                    MessageBox(hwnd,"Couldn't load OurFile.txt","Error",MB_OK | MB_ICONERROR);
                                    PostQuitMessage(0);
                                          return 0;
                              }

                        // Ищем конец файла
                        fseek(file,0,SEEK_END);

                        // Эта функция получает положение файлового указателя -- Мы используем его для того,
                        // чтобы выделить достаточно памяти, чтобы загрузить весь файл
                        fgetpos(file,&length);

                        buff = new char[(int)length + 1]; // Выделяем память
                                                                          // "+ 1" нужно для завершающего NULL
                                                                          // мы хотим точно знать, что buff заканчивается символом NULL

                              // Проверка ошибки
                              if(!buff)
                              {
                                    MessageBox(hwnd,"Couldn't allocate the memory","Error",MB_OK | MB_ICONERROR);
                                    PostQuitMessage(0);
                                          return 0;
                              }

                        // Перемещаем файловый указатель обратно в начало файла
                        fseek(file,0,SEEK_SET);

                        // Читаем весь файл в буфер buff
                        fread(buff,(int)length,1,file);
                        
                        buff[(int)length] = NULL; // Завершаем buff символом NULL
                                                              // (Мы добавили "+ 1" к длине буфера, и теперь
                                                              // "length" это индекс последней ячейки массива buff)

                        // Закрываем файл
                        fclose(file);

                        // Здесь все и происходит -- Эта функция заполняет окно редактирования текстом,
                        // который мы прочитали.
                        SetWindowText(edit_box,buff);

                        delete[] buff; // Освобождаем "buff"
                              return 0;
               
               } // конец if(LOWORD(wparam) == LoadFile)

               // В другом случае, если мы записываем файл...
               else if(LOWORD(wparam) == SaveFile)
               {
                     // Создаем символьную строку для пути к каталогу, куда мы будем записывать файл
                     char dir_path[256] = {0};
                     char *buff = NULL; // Символьный буфер, используемый для хранения ВСЕГО текста,
                                                  // набранного в окне редактирования
                     
                     // Так мы получаем текущий каталог, из которого запущен .exe файл
                     GetCurrentDirectory(256,dir_path);

                     // Дописываем в конец имя файла -- Помните, что необходимо два "\\"
                     // для представления одного "\"
                     strcat(dir_path,"\\OurFile.txt");

                     // Получаем "длину текста" (количество символов) в окне редактирования
                     int length = GetWindowTextLength(edit_box);

                     length++; // Прибавляем единицу, учитывая NULL terminator 
                                     // (нулевой завершающий символ)
                                       
                     // Создаем буфер достаточного размера для хранения всего текста
                     buff = new char[length];

                              // Проверка ошибки - Если мы не смогли выделить память
                              if(!buff)
                              {
                                    MessageBox(hwnd,"Couldn't allocate the memory","Error",MB_OK | MB_ICONERROR);
                                    PostQuitMessage(0);
                                          return 0;
                              }
                     
                        // Заполняем буфер текстом из окна редактирования
                        GetWindowText(edit_box, buff, length);
                        
                        buff[length - 1] = NULL; // Для уверенности, что "buff" завершается символом NULL
                                          
                        // Открываем файл для записи
                        FILE *file_pointer = fopen(dir_path, "wb");
                        
                        // Записываем содержимое окна редактирования в файл
                        fwrite(buff, length, 1, file_pointer);
                        
                        fclose(file_pointer); // Закрываем файл
                        
                        delete[] buff; // Освобождаем "buff"
                              return 0;
               }

               return 0;

         } // конец case WM_COMMAND:
                  
        case WM_CLOSE:
            case WM_DESTROY:
            
                  PostQuitMessage(0);
                        return 0;
    }

    return DefWindowProc(hwnd, message, wparam, lparam);
}

/*  Примечание

  Конечно же, если вы бы создавали более функциональную программу, вы бы
  НЕ прописывали в коде имя .txt файла. Вы бы дали пользователю возможность назвать
  его при записи, а также реализовали бы возможность загружать различные текстовые
  файлы.

  Но это выходит за предмет данной обучалки :)
  
  Может быть в будущем, обучалка перейдет "на следующий уровень" :)
  
*/

/*
|  TheTutor                    
|  thetutor@gametutorials.com  
|  © 2000-2002 GameTutorials   
*/
// Перевод © 2005 Евгений Казеко
// www.gamecoder.kazeko.com
// evgeniy@kazeko.com

Скачать обучалку (Visual C++ 6)

Открытие файлов диалоговым окном | Все обучалки раздела | Загрузка изображения

[Главная] [С чего начать?] [Дистанционное обучение] [Статьи] [Обучалки] [Книги] [Софт] [Форум] [Ссылки] [О сайте]

Copyright © 2003-2005 Евгений Казеко. Все права защищены. E-mail: evgeniy@kazeko.com

Компания Теплокровля роквул, гарантия качества. , Infly.ru: тунис туры, отдых в болгарии. , окна от 6044 р.