Способы реализации функции (callback) функции обратного вызова в Java

👁 242 просмотров

Callback — функция обратного вызова. Используется тогда, когда необходимо выполнить определенный кусок кода, передав данный кусок кода в виде параметра методу и, естественно, данный кусок будет исполняться внутри переданного метода. Чтобы передать данный кусок кода, нам необходимо это кусок кода как-то именовать, естественно, что в Java мы будет это организовать в виде метода и будем передавать этот метод в виде аргумента другим методам.

Когда и где это может быть использовано?

Для начала, рассмотрим задачу вывода диалогового окна, средствами JavaFX. Так как JavaFX не содержит в арсенале понятие диалоговое окно, то нам придется его создавать самим. Такое окно может выводить любую информацию в виде элемента управления или просто текста. Нам необходимо как-то обработать события, которые расположены на данном диалоговом окне. Для решения данной задачи, сначала, воспользуемся решением без использования callback

public class Dialog {
    /** Интерфейс для обработки события*/
    public static String result = null;//Создадим поле хранения текущего значения
      
    public static void setResult(String result)//Реализуем setter
    {
        Dialog.result = result;
    }
    public static String getResult()//Реализуем getter
    {
        return Dialog.result;
    }

    //Метод реализации вывода диалогового окна
    public static void showAlert(String title){

          //Создаем новый экземпляр стадии(будет выполняться наряду с основным потоком программы)
          final Stage dlgStage = new Stage();

          //Создадим кнопку
          Button btnOk = new Button("Ok");
          
          //Прикрепим к кнопке событие
          btnOk.setOnAction(new EventHandler(){
              @Override
              public void handle(ActionEvent arg0) {
                  setResult("Yo click Ok!");//Устанавливаем значение при нажатии на кнопку
                  dlgStage.close();//Закрываем диалоговое окно при нажатии
              }
          });

          //Текстовое поле для вывода информации
          Label lblTitle = new Label(title);
          lblTitle.setFont(Font.font("Amble CN", FontWeight.NORMAL, 14));

          //Создаем контейнер для вертикального выравнивания элементов
          VBox vbox = new VBox(lblTitle,btnOk);
          vbox.setAlignment(Pos.CENTER);
          vbox.setMinSize(300, 200);

          //Создаем новую сцену и передаем ей контейнер
          Scene dlgScene = new Scene(vbox);

          //Устанавливаем сцену, инициализировав стили и т.д.
          dlgStage.setScene(dlgScene);
          dlgStage.initStyle(StageStyle.UNDECORATED);
          dlgStage.initModality(Modality.APPLICATION_MODAL);
          dlgStage.setMinWidth(300);
          dlgStage.setMinHeight(200);
          dlgStage.show();      
  }
}

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

Dialog.showAlert("Hello world!");
if(Dialog.getResult() != null)
{
  System.out.println(Dialog.getResult());// Результат, записанный при нажатии
}

В результате мы получим следующий результат на экране

java-dialog-callback

Нажмем на кнопку и посмотрим на вывод в консоле NetBeans, где у нас ничего не выведется в первый раз, потому что диалоговое окно выполняется своим потоком, а программа своим и после нажатия на «ok» мы инициализируем значение поля result, закрываем диалоговое окно, но повторно — то этот код не выпонится, поэтому значение в result при первом запуске будет null, как мы его инициализировали в классе Dialog. При повторном выполнении данного кода у нас выведется тоже самое окно, но значение уже будет не текущее, а предыдущего нажатия, что не есть нормально, так как создается 2 потока: 1- поток программы, 2 — поток диалогового окна.

 Решение проблемы с помощью callback

Код ниже именуется как callback.

new EventHandler<ActionEvent>(){
    @Override 
    public void handle(ActionEvent arg0){    
    dlgStage.close();
  }
}

Callback не возвращает type, как вы можете видеть выше в примере, он void.

Callback — и имеют методы, которые вы получаете как аргументы в другом методе.  Другой метод должен вызвать callback метод, когда он пожелает. Это значит, что callback — и имеют асинхронность.

В вашем примере, он вызывает callback, когда вы жмете на кнопку.

И в заключении, вы не сможете возвратить его, используя return.

Что делать ?

Вы можете вызвать метод из вашего callback и отправить ваше возвращаемое значение ему как аргумент.

Пример:

btnCancel.setOnAction( newEventHandler<ActionEvent>(){
    @Override
    public void handle(ActionEvent arg0){

        YourClass.setReturnValue("This is button Cancel");
        dlgStage.close();
   }
 });

Где setReturnValue  -метод принадлежащий вашему классу YourClass или его экземпляр, который будет содержать ваше возвращаемое значение.

Другой и лучшим путем подхода будет создание класса, который будет наследовать Stage. Также в вашем  showPrompt методе вы должны блокировать выполнение основного потока, используя showAndWait() или похожим образом.

В заключении, вы не можете создавать весь Prompt из только одного метода.

Работа с обработчиками событий в JavaFX

👁 149 просмотров

Данная статья расскажет вам как работать с обработчиками событий в JavaFX программах. Вы узнаете как можно обработать событие, которое было сгенерировано клавиатурой, мышью, скролами и другими элементами управления на экране вашего JavaFX приложения 🙂 .

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

Регистрация и удаление обработчика события для узла

Для обработки события на этапе восходящей фазы узел должен зарегистрировать обработчик. Обработчик события наследует интерфейс EventHandler. Метод handle() данного интерфейса предоставляет код, который будет выполнен, когда событие, которое ассоциировано с обработчиком получит узел,для которого зарегистрирован обработчик.

Для регистрации обработчика используется метод addEventHandler(). Данный метод получает тип события и обработчик в виде аргумента. Ниже представлен пример , где первый обработчик добавляется к простому узлу и обрабатывается определенный тип события. Второй обработчик — для обработки события ввода, определен и зарегистрирован для 2-х различных узлов. Обработчик также зарегистрирован для двух различных типов событий.

//Пример регистрации обработчика для одного узла определенного типа события
node.addEventHandler(DragEvent.DRAG_ENTERED, 
                    new EventHandler() {
                        public void handle(DragEvent) { ... };
                    });

//Определение обработчика для предыдущего события
EventHandler handler = new EventHandler(() {
    public void handle(InputEvent event) {
        System.out.println("Handling event " + event.getEventType()); 
        event.consume();
    }

//Регистрация одного обработчика для двух различных узлов
myNode1.addEventHandler(DragEvent.DRAG_EXITED, handler);
myNode2.addEventHandler(DragEvent.DRAG_EXITED, handler);

//Регистрация еще одного типа события для первого из двух различных узлов
myNode1.addEventHandler(MouseEvent.MOUSE_DRAGGED, handler);

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

Когда вам больше не нужен обработчик события для узла, то его можно удалить, используя метод  removeEventHandler(). Данный метод в виде параметров получает тип удаляемого события и его обработчик. В ниже следующем примере представлен код, который демонстрирует данную возможность, где удаляется событие DragEvent.DRAG_EXITED узла myNode1 из предыдущего примера, но обработчик еще выполняет данный тип события для узла myNode2, и событие MouseEvent.MOUSE_DRAGGED для узла myNode1.

//Удаляем событие обработчика
myNode1.removeEventHandler(DragEvent.DRAG_EXITED, handler);

 Совет: Для удобства удаления обработчика события достаточно передать значение null в виде параметра через специальный метод, к примеру node1.setOnMouseDragged(null).

 

Архитектура JavaFX

👁 102 просмотров

В данной статье будет рассмотрена архитектура приложений JavaFX.  JavaFX является надслойкой виртуальной машины JVM и включает в себя целый набор утилит и модулей для полноценной работы с 2D/3D графикой, с представлениями окон, медиа — контентом, WEB — контентом, а также предоставляет программные инструменты для взаимодействия между, вышеперечисленными, компонентами. Ниже представлена иллюстрация того, как устроена надслойка JavaFX

Архитектура JavaFX

 

Графы сцены

Графы сцены или Scene Graph  — это самый верхний слой в архитектуре JavaFX. Он представлен иерархической структурой узлов и является начальной точкой построения визуального приложения JavFX, который включает в себя различные визуальные элементы управления. Данный слой управляет вводом и выводом данных начальных и конечных данных от пользователя. Графа сцены представлен набором узлов, которые имеют атрибуты такие как ID(уникальный идентификатор узла), который необходим для идентификации элемента управления в Java или CSS коде, class(используется, как правило при придании различных стилевых свойств атрибутов через CSS) и др., а также представлен определенным, ограниченным размером в пределах экрана монитора. За исключением корневого элемента или как его еще называют root node, каждый узел имеет свой родительский элемент и 0 или более дочерних узлов, которым можно придать следующие атрибуты:

  • Эффекты, такие как мутность и тень;
  • Прозрачность;
  • Трансформации;
  • Обработчики событий мыши, клавиатуры, внутренних методов в коде Java;
  • Специфичных для приложения различные состояния отображения;

В отличии от Swing и AWT(Abstract Window Toolkit) , JavaFX включает в себя еще графические примитивы такие как линии, прямоугольники, окружности и т.д., которые можно использовать наряду с остальными элементами управления и в дополнении имеет контейнеры, элементы для просмотра изображений и проигрывания медиа-контента.

JavaFX предоставляет богатые возможности для графов через javafx.animation API, который способен добавлять различные динамические спецэффекты и анимации.

JavaFX API позволяет создавать контент, специфичный для нескольких типов:

  • Узлы: Сущности (2-D и 3-D), изображения, медиа, встроенный WEB браузер, текст, UI элементы, графики, группы и другие контейнеры;
  • Состояние: Трансформации (позиции и ориентации узлов), визуальные эффекты и другие визуальные состояния;
  • Эффекты: Простые объекты, которые меняют свой внешний вид, обретая эффекты замутнения, тени и цветовых установок;

 Публичный открытый API для JavaFX

Верхний слой JavaFX архитектуры, показанный на вышеприведенной картинке, предоставляет законченный, публичный API, который поддерживает построение богатых возможностями клиентских приложений. Данный API предоставляет не параллельную, свободную и гибкую возможность для построения богатые клиентскими возможностями приложения. В JavaFX скомбинорованы лучшие возможности Java платформы со всесторонним погружением в медиа-функционал. Java для JavaFX характеризует:

  • Позволяет использовать полноценные Java характеристики , такие как генераторы, аннотации, многопоточность и лямбда выражения(включенные в Java SE 8);
  • Делает разработку для WEB очень легкой и позволяет для этого использовать другие, базовые для JVM, языки, такие как Groovy и JavaScript;
  • Позволяет разработчикам использовать другие системные языки, такие как Groovy для написания больших комплексных и сложных JavaFX приложений;
  • Позволяет использовать связывание, которое включают поддержку для высокопроизводительных lazy binding, binding выражения, bound sequence выражения и частичное связывание;
  • Внешние Java коллекции библиотек включают наблюдаемые списки(observable lists) и карты, которые позволяют программам соединять пользовательский интерфейс к моделям данных, позволяя наблюдать за обновлением или изменением данных в этих моделях и обновлением или изменением вместе с этим данных в пользовательских элементах управления;

JavaFX API и и программная модель имеет продолжение от JavaFX 1.x линейки выпуска, поэтому старые проекты можно легко перенести на новый выпуск JavaFX 2.x без особых затруднений.

 

Использование библиотеки jackcess для работы с MS Access через Java

👁 205 просмотров

Jakcess — библиотека на чистом Java для чтения и редактирования реляционной базы данных Access от компании Microsoft. Данная библиотека, на момент написания данной статьи(а это 30.04.2014), поддерживает версии MS Access 2000 — 2010. Данная библиотека предоставляет кросс-платформенный, ясный Java API для использования MS Access в пользовательских Java программах . Jakcess хорошо задокументирован и является частью проекта OpenHMS, который является брендом, продвигающий коллекции open source проектов.

Что нам потребуется для использования библиотеки Jackcess?

Если мы скачаем библиотеку jackcess.jar  попытаемся использовать ее, то у нас ничего не получится, так как у Jakcess есть зависимости, т.е. он еще нуждается в дополнительных библиотеках, которые будет необходимо параллельно добавить. Данные зависимости используются только самой библиотекой, вам остается только пользоваться чисто классами Jackcess и все. Ниже приведу зависимости которые будут необходимы для полноценной работы и следует отметить, что необходимо учитывать версии зависимостей, так как новая версия зависимости может включать видоизмененные классы, которые в текущей версии библиотеки Jackcess не успели обновить, поэтому вам необходимо это учитывать.

Зависимости компиляции

Ниже представлен список зависимостей, которые требуются для компиляции и запуска приложения с библиотекой Jackcess:

Наименование Ссылка  Версия   Тип  Лицензия Опции
commons-lang commons-lang 2.0 jar The Apache Software License, Version 2.0 Нет
commons-logging commons-logging 1.0.3 jar The Apache Software License, Version 2.0 Нет
org.apache.poi poi 3.9 jar The Apache Software License, Version 2.0 Да

Зависимости запуска программы с Jackcess

Следующие зависимости необходимы для среды времени выполнения:

 Наименование   Ссылка   Версия   Тип  Лицензия Опции
log4j log4j 1.2.7 jar The Apache Software License, Version 2.0 Да

Зависимости для тестирования

Следующие зависимости необходимы для тестирования приложения с Jackess:

Наименование Ссылка Версия Тип Лицензия
junit junit 4.11 jar Common Public License Version 1.0

Замечание 1. В данной статье приведены 3 зависимости, полный перечень зависимостей можете найти на официальном сайте — вот на этой странице.

Замечание 2.  Вам не нужно иметь все зависимости, достаточно те, которые я тут привел.

Пример использования Jackcess

try {
    Table table = DatabaseBuilder.open(new File("E:\\file.mdb")).getTable("Table");//Читаем из таблицы "Table"
     for(Row row : table) {
        System.out.println("Look ma, a row: " + row.get("Column"));//Читаем колонку под именем "Column"
     }
} catch (Exception ex) {
    ex.printStackTrace(); 
}

 

Часть 1. Работа с XML в Java. Описание

👁 77 просмотров

В Java JDK встроены 2 вида XML парсеров, которые доступны как DOM(Document Object Model) и SAX(Simple API for XML). У обеих у них как свои преимущества, так и недостатки. В данном посте приведены примеры работы с файлами XML: будет создан, изменен и прочтен файл XML с помощью DOM и SAX.

DOM XML парсер

DOM парсер — это самый легкий инструмент для работы с XML структурой в Java. При использовании данного подхода все содержимое файла XML загружается в память компьютера, моделируя объект, чтобы можно было легко производить операции со структурой файла, но, данная легкость расплачивается  прожорливостью памяти и ресурсов процессора, поэтому, данный способ эффективен, если производиться операция с файлом небольшого размера.

SAX XML парсер

SAX парсер, в отличии от DOM, не загружает структуру документа в память, а использует для манипуляции функцию обратного вызова (org.xml.sax.helpers.DefaultHandler), с помощью которого он держит связь между пользователем и файлом. Помимо этого, SAX парсер имеет возможность в любой момент обратиться к любой части XML документа и манипулировать локальным содержимым, по этой причине SAX быстрее и менее расточительнее, чем DOM парсинг.

Что выбрать?

Требования к программе могут быть разные, поэтому, сразу ответить что лучше нельзя, все исходит из потребностей, но ничто не мешает использовать и SAX и DOM парсер  одновременно в одном и том же проекте.

Tennis Anime — программа на OpenGL для моделирования игры в теннис

👁 79 просмотров

Tennis Anime —  программа, которая анимирует процесс игры в теннис. Программа реализована на графической библиотеке OpenGL на платформе Win32. Есть возможность управления движения видовым экраном в пространстве с помощью стрелок Вверх, Вниз, Влево, Направо. Написан на C++ в среде Visual Studio 2010. Основной целью данной программы является демонстрация движения мяча в воздухе и движение ракеток.

tennis-anime

Для создания временных интервалов движения мяча в программе используется таймер. Движение мяча в пространстве от ракетки описывается формулой горизонтально брошенного тела, а отскок от земли — формулой движения тела под углом.

Safe Manager — программа для изменения атрибутов файлов

👁 223 просмотров

Safe Manager — программа для Windows, которая помогает устанавливать или изменять атрибуты любого файла. С помощью данной программы вы можете также скрывать файлы на компьютере под пароль, возведя файл в собственный формат программы .smf и извлекать их из сейфа, введя поставленный пароль. С помощью атрибутов можете скрывать файл на компьютере, установив атрибут Hidden, а также запретить его удалять с компьютера установив атрибут System. Программа очень легкая и весит от силы 1 Мгб и со скромными потребностями .NET 3.5 или выше.

Prewiev Image

Примечание: При скрытии файла имейте в виду, что увидеть его и изменить его атрибут на видимый можно, в дальнейшем,  через настройки папок и файлов Windows(Панель управления\Все элементы панели управления\Параметры папок) сняв галочку с пункта Скрывать защищенные системные файлы.

Решаем проблему нерабочих USB на Windows 7

👁 75 просмотров

Операционная система взаимодействует с железом с помощью прослойки драйверов. Драйверы  — это программные модули, которые напрямую работают с модулями железа и как ни странно их тоже нужно обновлять, когда обновляется модули ОС или модули железа. Проблема нерабочих USB может произойти, отчасти, от разных ситуаций:

  • Обновили какое-то физическое устройство на ПК;
  • Обновили ОС или модуль ОС;
  • Переустановка ОС;
  • Неудачная работа с реестром;
  • Неудачная работа с папкой C:\Windows\System32;
  • Автоматический сброс в USB : Disable в BIOS;

Одним из основных путей решения данной проблемы состоит из 3-х шагов:

  1. Скачиваем и устанавливаем любую, зарекомендованную, программу обновления и установки драйверов. Один из кандидатов  — Driver Booster:

Driever BoosterПосле установки обновляем все устаревшие драйвера и устанавливаем отсутствующие, далее перезагружаем компьютер;

2.  Заходим в реестр Windows через специализированную программу или через стандартный редактор реестра выполнив команду regedit.exe в строке пуск:

reg-edit-winЗапускаем этот редактор и находим в дереве реестра ветку HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{36FC9E60-C465-11
CF-8056-444553540000} , нажимая на которую в правой части выводятся соответствующие ей параметры и их значения:

reg-param-value

 

Там же(в правой части) смотрим, нет ли параметров LowerFilters и UpperFilters, если они есть, то удаляем их;

3. Перезагружаем комп и на этапе загрузки циклично нажимаем на  кнопку F2 или Delete, чтобы зайти в BIOS. Зайдя в BIOS находим пункт, где конфигурируется USB, на разных операционках может отличаться данный пункт. В BIOS находим пункт Integrated Peripherals в Award BIOS или пункт Advanced в Ami BIOS , наводя на них метку жмём Enter,   заходим в USB Configuration и проверяем стоит ли USB в положении Enabled, если USB в Disabled, то меняем на Enabled;

Далее выходим из BIOS и USB должен заработать. Может получиться так, что 3-го этапа и не понадобиться — смотря что за ситуация именно у вас.

 

 

 

1.Введение в Android

👁 85 просмотров

Данные и последующие темы данной рубрике будут ориентированы на программистов, которые хотят освоить для себя новую мобильную платформу Android. По ходу пьесы будут затрагиваться основные моменты, на которые следует остановиться начинающему разработчику Android и это поможет избежать путаницы. Для разработки существуют фирменные наборы SDK android с IDE Eclipse на основе ADT(Android Development Tools)-плагина. Почему выбран IDE Eclipse? Потому что в Гугл решили выпустить собственную реализацию IDE, добавив к Eclipse свои инструменты с набором Android SDK и является Open Source, поэтому никому ничего ненадо платить. Недавно был релиз нового фирменного IDE на основе IntelliJ IDEA Open Source -версии. Новая Android-студия представляет собой подобно Eclipse с ADT Plugin, Android-студия предоставляет интегрированные Android средства разработки для разработки и отладки. Кроме возможностей, которые вы ожидаете от IntelliJ, Android-студия предлагает:

  • Gradle -поддержка сборки;
  • Android-специфичный рефакторинг и быстрое решение;
  • Lint-инструменты для анализа производительности, удобство использования, решения совместимости версий и другие проблемы;
  • ProGuard и приложение с возможностью подписи;
  • Мастера на основе шаблонов для создания общих конструкций и компонентов Android;
  • Визуальный редактор макета, который позволяет перетаскивать и вставлять компоненты пользовательского интерфейса, просматривать макеты на нескольких конфигурациях экрана и многое другое;
  • Встроенная поддержка для Google Cloud Platform , что позволяет легко интегрировать Google Cloud сообщения и App Engine как серверные компоненты;

В настоящее время очень много новых IDE, которых выталкивают на рынок сторонние разработчики, как правило они охватывают не узкий сегмент одного лишь Android, а комплекс различных платформ, т.е. пишешь один раз и получаешь для всех(Windows Phone, iOS, Android …). Я не думаю, что, если вы начинающий программист, то вам следует начать с них, конечно, они вам дают удобный и понятный интерфейс, который, из-за своей «сырости», редко пригоден для полноценной разработки в дальнейшем и мало того, вам еще потребуется за это платить, когда ваше понимание в Android увеличится за пределы Free -релиза. Ниже привожу список основных IDE и плагинов, которые, на данный момент участвуют на рынке мобильного ПО:

  1. Codename One — Open Source плагин для Eclipse, Net Beans, IntelliJ IDEA, есть платная версия, которая исключает ограничение в количестве раз компиляции исходного кода. На данный момент идет полным ходом его усоверщенствование и поиск багов. Имеет очень большую перспективу, так как в основе данной разработки лежит лозунг Java: «Напиши один раз, запускай везде» и действительно, данное детище позволяет писать один код и компилировать его под Android, iOS, JME, Win Phone, Mac OS, Windows, RIM. При компиляции происходит создание нативного кода под ту или иную ОС. Код компилируется на сервере разработчиков и для этого придется зарегистрироваться на сайте www.codenameone.com;
  2. Xamarin Studio — полноценная IDE для разработки приложений на C#. Позволяет писать нативный код под Android, iOS,  Win Phone. Не является бесплатной;
  3. RAD Studio XE5 — это среда разработки native-приложений для рабочих групп, которая позволяет быстро создавать приложения для Android и iOS, загружать их в магазины приложений и внедрять в организациях. Данная среда позволяет писать код на C++ и Delphi. Не является бесплатной;

Стартовый код OpenGL /Win32

👁 104 просмотров

Часто бывает, особенно у новичков, что когда-то занимались на OpenGL, но забыли как написать начальный код для OpenGL приложения. Ниже представлен шаблонный код для дальнейшего развертывания графической библиотеки OpenGL. Конечно, Win32— приложения сейчас используются не столь популярностью, как раньше, но на на Win32 до сих учатся и программируют в учебных целях. Особенностью работы с OpenGL в Win32 является простота.

Легче, при разрастании кода, разделить главный исходный файл на несколько файлов с заголовками, чтобы не путаться в одном большом коде, как говориться : «Разделяй и властвуй!» :).

/*
*WebSofter MG
*/

#include <windows.h>
#include <math.h>

#include <gl/gl.h>
#include <gl/glu.h>

#include "glut.h"
#include "glaux.h"

#pragma comment(lib, "glut32.lib")//Подключаем библиотеку Glut
#pragma comment(lib, "Glaux.lib")//Подключаем библиотеку Glaux

HWND hWnd;
HGLRC hGLRC;
HDC hDC;



int SetWindowPixelFormat()
{
    int m_GLPixelIndex;
    PIXELFORMATDESCRIPTOR pfd;


    pfd.nSize       = sizeof(PIXELFORMATDESCRIPTOR);
    pfd.nVersion    = 1;

    pfd.dwFlags   = PFD_DRAW_TO_WINDOW | 
                    PFD_SUPPORT_OPENGL | 
                    PFD_DOUBLEBUFFER;

    pfd.iPixelType     = PFD_TYPE_RGBA;
    pfd.cColorBits     = 32;
    pfd.cRedBits       = 8;
    pfd.cRedShift      = 16;
    pfd.cGreenBits     = 8;
    pfd.cGreenShift    = 8;
    pfd.cBlueBits      = 8;
    pfd.cBlueShift     = 0;
    pfd.cAlphaBits     = 0;
    pfd.cAlphaShift    = 0;
    pfd.cAccumBits     = 64;    
    pfd.cAccumRedBits  = 16;
    pfd.cAccumGreenBits   = 16;
    pfd.cAccumBlueBits    = 16;
    pfd.cAccumAlphaBits   = 0;
    pfd.cDepthBits        = 32;
    pfd.cStencilBits      = 8;
    pfd.cAuxBuffers       = 0;
    pfd.iLayerType        = PFD_MAIN_PLANE;
    pfd.bReserved         = 0;
    pfd.dwLayerMask       = 0;
    pfd.dwVisibleMask     = 0;
    pfd.dwDamageMask      = 0;



    m_GLPixelIndex = ChoosePixelFormat( hDC, &pfd);
    if(m_GLPixelIndex==0) // Let's choose a default index.
    {
     m_GLPixelIndex = 1;    
     if(DescribePixelFormat(hDC,m_GLPixelIndex,sizeof(PIXELFORMATDESCRIPTOR),&pfd)==0)
       return 0;
    }


    if (SetPixelFormat( hDC, m_GLPixelIndex, &pfd)==FALSE)
        return 0;


    return 1;
}




void resize(int width,int height)
{
    glViewport(0,0,width,height);
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    glOrtho(-5,5, -5,5, 2,12);    
    gluLookAt( 0,0,5, 0,0,0, 0,1,0 );
    glMatrixMode( GL_MODELVIEW );
}    

int DrawGLScene(GLvoid)//Здесь будет весь код OpenGL объектов
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();
	glTranslatef(0.0,0.0,1.0);//Настраиваем координаты	

	glPushMatrix();
	  auxSolidSphere(2.5f);//Выводим сферу
        glPopMatrix();

	return TRUE;
}


void display()
{
  glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

  	/* remove next tree lines
	 * and enter your code here
	 */
     DrawGLScene();

  glFinish();
  SwapBuffers(wglGetCurrentDC());
}




LRESULT CALLBACK WindowFunc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
float pos[4] = {3,3,3,1};
float dir[3] = {-1,-1,-1};
PAINTSTRUCT ps;

switch(msg)
	{

	case WM_CREATE:
	hDC = GetDC(hWnd);
	SetWindowPixelFormat();
	hGLRC = wglCreateContext(hDC);
	wglMakeCurrent(hDC, hGLRC);

    glEnable(GL_ALPHA_TEST);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_COLOR_MATERIAL);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    glLightfv(GL_LIGHT0, GL_POSITION, pos);
    glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, dir);

        break; 

    
	case WM_DESTROY:
	if (hGLRC) 
	{
	    wglMakeCurrent(NULL, NULL);
	    wglDeleteContext(hGLRC);
	}
	ReleaseDC(hWnd, hDC);
	PostQuitMessage(0);
	break;

	
	
	case WM_PAINT:
	BeginPaint(hWnd, &ps);
	display();
	EndPaint(hWnd, &ps);
	break;
	

    
	case WM_SIZE:
	resize( LOWORD(lParam), HIWORD(lParam) );
	break;  


       default:
	return DefWindowProc(hWnd,msg,wParam,lParam);
	}

return 0;
}




int WINAPI WinMain(HINSTANCE hThisInst,
				   HINSTANCE hPrevInst,
				   LPSTR str,int nWinMode)
{
MSG msg;
WNDCLASS wcl;


wcl.hInstance=hThisInst;
wcl.lpszClassName = L"OpenGLWinClass";
wcl.lpfnWndProc = WindowFunc;
wcl.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;

wcl.hIcon = NULL;
wcl.hCursor = LoadCursor(NULL,IDC_ARROW);
wcl.lpszMenuName = NULL;

wcl.cbClsExtra = 0;
wcl.cbWndExtra = 0;

wcl.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
RegisterClass(&wcl);


hWnd = CreateWindow(L"OpenGLWinClass", L"Win API Template", 
					 WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
					 200,
					 150,
					 400,
					 420,
					 HWND_DESKTOP, NULL,
					 hThisInst, NULL);


ShowWindow(hWnd,nWinMode);
UpdateWindow(hWnd);


while(1)
{
  while( PeekMessage(&msg,NULL,0,0,PM_NOREMOVE) ) 
    if(GetMessage(&msg,NULL,0,0))
     { 
      TranslateMessage(&msg);
      DispatchMessage(&msg);
     }
    else
      return 0;

  display();
} 


return 0;
}

Вы можете работать со стандартными библиотеками OpenGl, это:

#include <gl/gl.h>
#include <gl/glu.h>

а можете подключить и дополнительные библиотеки, на подобие:

#include "glut.h"
#include "glaux.h"
#pragma comment(lib, "glut32.lib")//Подключаем библиотеку Glut
#pragma comment(lib, "Glaux.lib")//Подключаем библиотеку Glaux

Чтобы подключить их, вам нужно скачать последние версии glut32.lib/glut.h и glaux.lib/glaux.h и закинуть их в ту же директорию, где ваш файл запуска главной функции WinMain, т.е. вышеприведенный.