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

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

Открытие файлов диалоговым окном



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

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

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


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


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


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


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


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

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

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


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

Rambler's Top100

Диалоговые окна часть 2 | Все обучалки раздела | Окно редактирования

Описание

Используется стандартное диалоговое окно для открытия .bmp файла.

Программа открывает с помощью стандартного диалоговоо окна .bmp файл и выводит его на экран. Показывается (но не объясняется), как загружать .bmp файлы и выполнять "блиттинг".

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

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

Исходный код

// Done by TheTutor -- 9/08/01
// Перевод © 2004 Евгений Казеко
// www.gamecoder.kazeko.com
// evgeniy@kazeko.com

/*      Это обучалка об открытии файлов с использованием диалоговых окон. Мы не будем
      использовать для этого "истинное диалоговое окно" (т.е. у нас не будет диалоговой
      процедуры), а просто используем windows API.
*/

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

#define WIN_WIDTH 640
#define WIN_HEIGHT 480

#define BUFF_MAX 256 // Размер буфера, который нужен для открытия файлов

#define class_name "GameTutorials_OpenFileUseDialog"

// Эта функция заполнит структуру типа OPENFILENAME, которая нам понадобится для
// создания диалогового окна "по умолчанию".
void FillOpenParams(OPENFILENAME&, HWND, char*, char*); 
                                                                               
// Загружает и выводит передаваемый .bmp файл на экран
bool BlitImage(char*, HWND);

// "Очищает" окно, заполняя его белым цветом
void ClearWindow(HWND);

// Стандартная callback функция
LRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);


int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprev, PSTR cmdline, int ishow)
{
    HWND hwnd;
    HMENU hmenu;
    MSG msg;
    WNDCLASSEX wndclassex = {0};

    // Заполняем нужные нам поля
    wndclassex.cbSize = sizeof(WNDCLASSEX);
    wndclassex.style = CS_HREDRAW | CS_VREDRAW;
    wndclassex.lpfnWndProc = WinProc;
    wndclassex.hInstance = hinstance;
    wndclassex.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wndclassex.lpszClassName = class_name;

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

            // Проверка ошибки
            if(!hmenu)
                  return EXIT_FAILURE; // Произошло что-то плохое :(

    RegisterClassEx(&wndclassex);      // Регистрируем окно

    
    hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, // У окна будет толстая рамка
                                      class_name,
                                      "GameTutorials -- Opening Files with a Dialog Box",
                                      WS_OVERLAPPEDWINDOW,
                                      CW_USEDEFAULT, // Окно будет размещено в позиции по умолчанию
                                      CW_USEDEFAULT, 
                                      WIN_WIDTH,
                                      WIN_HEIGHT,
                                      NULL,
                                      hmenu,
                                      hinstance,
                                      NULL);

            // Проверка ошибки
            if(!hwnd)
                  return EXIT_FAILURE; // Произошло что-то плохое! 

    ShowWindow(hwnd, ishow);
    UpdateWindow(hwnd);

    while(1)
      {
            // Получаем сообщения, если они есть
            if(PeekMessage(&msg,hwnd,0,0,PM_REMOVE))
            {
                  if(msg.message == WM_QUIT)
                        break;
                        
                  TranslateMessage(&msg);
                  DispatchMessage(&msg);
            }
            else
            {
                  // Здесь мы можем проводить все основные операции
            }
      }

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

      return msg.wParam;
}

//  WinProc
LRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
    PAINTSTRUCT ps;


      /*      Эта структура используется либо функцией GetOpenFileName() (для открытия файлов),
            либо функцией GetSaveFileName() (для сохранения файлов). Мы будем использовать
            ее для открытия файла. Информация о файле, который мы будем пытаться открыть, будет
            размещаться в этой структуре.      */
      OPENFILENAME open_params = {0}; 
      
      char filter[BUFF_MAX] = {0};  // Будет заполняться "фильтром", объяснение позже
      char file_name[BUFF_MAX] = {0}; // Будет использоваться для "имени файла по умолчанию" диалогового окна
      
    // В зависимости от сообщения - выполняем различные действия
    switch(message)
    {
            case WM_PAINT:
            
                  BeginPaint(hwnd,&ps);
                  EndPaint(hwnd,&ps);
                        return 0;

            case WM_COMMAND:

                  // Если пользователь выбрал "Quit" из меню
                  if(LOWORD(wparam) == ID_FILE_QUIT)
                        PostQuitMessage(0); // Мы поступим как просят и выйдем из программы

                  // Если пользователь выбрал "Open" из меню
                  if(LOWORD(wparam) == ID_BMP_FILE_OPEN)
                  {
                        /*      Мы собираемся заполнить нужные нам поля структуры "open_params", но
                              сперва нам нужно определить "filter". Это указатель на буфер, содержащий
                              пару строк с завершающим нулевым символом. Последняя строка в буфере
                              должна завершаться двумя символами NULL. Первая строка содержит описание
                              типа файла, который будет отображаться. Вторая строка это расширение(я)
                              файла(ов). Если расширений много, они разделяются точкой с запятой.

                              Это немного запутывает, поэтому мы будем рассматривать фильтр шаг за
                              шагом. Поскольку мы определили фильтр следующим образом:

                              char filter[BUF_MAX] = {0};

                              то мы можем быть уверены, что каждый символ в символьном массиве изначально
                              равен NULL                        */

                        
                        strcat(filter,"BMP Files"); // Записываем в фильтр "BMP Files"

                        // Теперь фильтр выглядит вот так:
                        //
                        // filter[0] = 'B'
                        // filter[1] = 'M'
                        // filter[2] = 'P'
                        // filter[3] = ' '
                        // filter[4] = 'F'
                        // filter[5] = 'i'
                        // filter[6] = 'l'
                        // filter[7] = 'e'
                        // filter[8] = 's'
                        // filter[9] = NULL // Все оставшиеся символы также равны NULL

                        int index = strlen(filter) + 1; // Индекс теперь равняется первому свободному символу
                                                                        // после первого NULL в фильтре

                        // "Вторая половина" фильтра заполняется "*.bmp"
                        filter[index++] = '*';
                        filter[index++] = '.';
                        filter[index++] = 'b';
                        filter[index++] = 'm';
                        filter[index++] = 'p';
                        
                        // В итоге фильтр выглядит вот так:
                        //
                        // filter[0] = 'B'                  filter[10] = '*'
                        // filter[1] = 'M'                  filter[11] = '.'
                        // filter[2] = 'P'                  filter[12] = 'b'
                        // filter[3] = ' '                  filter[13] = 'm'
                        // filter[4] = 'F'                  filter[14] = 'p'
                        // filter[5] = 'i'                  filter[15] = NULL
                        // filter[6] = 'l'                  filter[16] = NULL // Все остальные символы 
                        // filter[7] = 'e'                                            // в фильтре
                        // filter[8] = 's'                                            // также равны NULL
                        // filter[9] = NULL 


                        FillOpenParams(open_params, hwnd, filter, file_name);

                        // Если GetOpenFileName НЕ завершается неудачно (она может возвратить код ошибки
                        // и пройти "if test")
                        if(GetOpenFileName(&open_params))
                        {
                              /*      Обратите внимание, что мы передаем "open_params.lpstrFile".
                                    С нашим вызовом GetOpenFileName() она заполнилась значением полного
                                    пути к файлу, выбранному пользователем. Мы будем использовать ее
                                    для загрузки файла и вывода его на экран (если все пройдет хорошо).
                              */

                              if(BlitImage(open_params.lpstrFile, hwnd) == false)
                                    MessageBox(hwnd,"Failed to blit the image","ERROR",MB_OK | MB_ICONERROR);
                        }
                  }

                  return 0;
                        

        case WM_DESTROY:
            case WM_CLOSE:
            
                  PostQuitMessage(0);
             return 0;

    } // конец switch(message)

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

void FillOpenParams(OPENFILENAME &open_params, HWND hwnd, char *filter, char *file_name)
{
      /** Инициализируем поля "open_params", нужные нам для открытия .bmp файла **/

      open_params.lStructSize = sizeof(OPENFILENAME); // Размер структуры
      open_params.hwndOwner = hwnd;                              // "Окно-собственник" диалогового окна
      open_params.lpstrFilter = filter;
      
      open_params.lpstrFile = file_name;  // Это указатель на имя файла, используемое для
                                                            // инициализации диалогового окна. Так как наша
                                                            // "file_name" равна NULL, не будет использовано
                                                            // никакого "имени файла по умолчанию"
                              
      open_params.nMaxFile = BUFF_MAX;      // Размер буфера "file_name"
                        
      open_params.lpstrInitialDir = NULL; // Эта переменная уже равна NULL, но я устанавливаю
                                                            // это значение снова, чтобы прокомментировать.
                                                            // Это значит (для Windows NT 5.0/Windows 98 и более
                                                            // поздних), что если "текущая директория" содержит
                                                            // файлы типов, определенных фильтром, то эта директория
                                                            // будет начальной. В противном случае начальной будет
                                                            // "директория персональных файлов"

      open_params.lpstrFileTitle = NULL;  // Опять же, переменная уже NULL, но она является
                                                            // заголовком диалогового окна. Так как мы установили
                                                            // NULL, то будет использован заголовок по умолчанию
                                                            // ("Open" в нашем случае)

      /*      Как вы можете предположить, есть набор флагов, которые могут быть установлены
            для диалогового окна. Я опишу, что означают эти четыре.

            OFN_FILEMUSTEXIST -- Разрешает набирать в поле набора имени файла только
                                           имена существующих файлов.

            OFN_PATHMUSTEXIST -- Разрешает пользователю набирать только верные пути и имена файлов.

            OFN_NOCHANGEDIR -- Изменяет текущую директорию обратно к прежнему значению, если пользователь
                                       изменил ее при поиске файлов
      
            OFN_HIDEREADONLY -- Скрывает кнопку выбора "read only" (возможность открывать файлы "read only")      

      */

                        
      open_params.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_NOCHANGEDIR
                                    | OFN_HIDEREADONLY;

      // Теперь мы заполнили все, что хотели
}


bool BlitImage(char *file_name, HWND hwnd)
{
      ClearWindow(hwnd); // Сперва мы очистим окно (закрасим его в белый цвет)

      // Загружаем bitmap
      HBITMAP hbitmap = (HBITMAP)LoadImage(NULL,file_name,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);

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

      HDC hdc = GetDC(hwnd); // Получаем контекст устройства окна

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

      HDC bmp_hdc = CreateCompatibleDC(hdc); // Создаем совместимый контекст устройства

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

      HBITMAP old_bmp = (HBITMAP)SelectObject(bmp_hdc, hbitmap); // Выбираем загруженный нами bitmap
                                                                                            // в совместимый контекст устройства

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

      // Если мы добрались досюда, мы можем отобразить bitmap, который мы загрузили
      BitBlt(hdc,0,0,WIN_WIDTH,WIN_HEIGHT,bmp_hdc,0,0,SRCCOPY);

      /*** Освобождаем память ***/
      SelectObject(bmp_hdc, old_bmp); // Всегда нужно выбирать "обратно" прежний HGDIOBJ 
      DeleteObject(hbitmap);

      DeleteDC(bmp_hdc);
      ReleaseDC(hwnd,hdc);

      return true; // Изображение загружено и отображено

} // конец bool BlitImage(char *file_name, HWND hwnd)


// Заполняем фон окна белым
void ClearWindow(HWND hwnd)
{
      HDC hdc = GetDC(hwnd); // Получаем контекст устройства окна

      RECT rect = {0}; // Прямоугольник RECT, который определяет клиент-область окна

      GetClientRect(hwnd,&rect); // Записываем в "rect" клиент-область окна

      // Заполняем окно белым
      FillRect(hdc,&rect,(HBRUSH)GetStockObject(WHITE_BRUSH));

      // Освобождаем память
      ReleaseDC(hwnd,hdc);

}

/*      Несколько слов напоследок --

      Для размера буфера мы использовали BUFF_MAX. У Windows есть собственное определение
      #define - MAX_PATH. Для ваших приложений вы вероятно захотите использовать его для
      размера буфера "file name". Я не использовал его, потому что подумал, что так
      будет немного понятнее.
      
      **Задание**

      Мы использовали функцию windows API GetOpenFileName(), чтобы "вывести диалоговое
      окно для выбора загружаемого файла". У Windows есть похожая функция API, GetSaveFileName()
      которая получает имя файла для сохранения. Сможете ли вы написать небольшое приложение,
      которое позволит пользователю вводить текст (как в NotePad), и затем записывать файл
      с использованием GetSaveFileName().
*/

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

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

Диалоговые окна часть 2 | Все обучалки раздела | Окно редактирования

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

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

Эхолоты и GPS навигаторы купить туристическое снаряжение в украине, для активного отдыха. , уменьшить поры , зимняя обувь магазины , Косметика, парфюмерия Нытва объявления доски ООО "Транс-Медиа Континент"