ß                                Программирование оконного отображения задачи

 

Адрес документа:

http://90.189.213.191:4422/temp/gr_mi38_37_mp8_sh/gr_mi38_37_mp8_sh.docинд 2-95-1-л8

 

В данной лекции рассматривается  программирование  вариантов «оконного отображения» в  системе Windows.  Создание, особенности отображения разных «окон».  Рассматриваются  «наследие» окон и «самостоятельное» функционирование после «кончины» родителей.  Варианты оповещений и сигнализаций с использованием оконного интерфейса.

 

Содержание:

 

 

Формирование окна;

Заставки  Windows  от версии 3.11. до 10  начинаются с отображения на экране окон.

    

И через 30 лет все равно стиль почти сохранился – окна.  Все программы пользуются оконным отображением. Ниже примеры разных видов окон.

   

 

Око́нный интерфе́йс — способ организации полноэкранного интерфейса программы, в котором каждая  интегральная часть располагается в окне — собственном «суб-экранном» пространстве, находящемся в произвольном месте «над» основным экраном.   Несколько окон, одновременно располагающихся на экране, могут перекрываться, находясь «выше» или «ниже» друг относительно друга.

 

В процессе подготовки программ,  возникает задача структурного отображения информации. Это означает:

Для реализации требований предусмотрено создание отдельного окна, в котором выполняется отдельный поток. Этот поток может быть и видимым – что –то показывается на экране. Поток  может сворачиваться, и быть «невидимым» для пользователя.  Невидимым только, если Вы не знаете, что такое поток и как его увидеть.

Рассмотрим создание отдельного потока, с отображением отдельного окна. Ранее в лекции 7, был пример создания многих потоков. Используем накопленный опыт, и будем реализовывать задачу через подключение библиотек.

Создаем много окон. По количеству нажатий клавиши создания окон. Ниже на рисунке экран с окнами, пример который разбирается.

    

 

Библиотека  create_okon1.f   и программа test.f     Если  скомпилировать только библиотеку программой компилятора forth. То ничего не произойдет, а только добавиться возможность формирования оконного интерфейса. Ее надо добавлять при решении задач с окнами.  Библиотека окон находиться в каталоге liber1.  Обратите внимание, что сама библиотека  create_okon1.f  тоже пользуется библиотеками.  Всю библиотеку в каталоге скачать архивом. Файлы библиотек специально имеют в названии цифры. Их последовательность показывает последовательность подключения.  Любая другая последовательность может создать ошибку компиляции.

 

 

\ начало  текста create_okon1.f

\ Библиотека для формирования оконного интерфейса.

 

  S" liber1\1_kontrolka_v1.f"           INCLUDED  ( 1. подключаем тестовые возможности  )

  S" liber1\2_bibl_local_variable.f"    INCLUDED  ( 2. подключаем работу с локальными переменными  )

  S" liber1\3_bibl_windows_ctruktur.f"  INCLUDED  ( 3. подключаем константы и переменные для построения окон  )

 

\ -----------------------

\ ----------------------------------------------

\ Основные функции создания окон

 

: Window ( class-a class-u style parent-hwnd -- hwnd )  \ 0 - ошибка

         \ создать окно указанного класса в качестве дочернего для parent

         \ если parent=0, то отдельное неподчиненное окно

  || ca cu style par || (( ca cu style par ))

  InitControls

  0 0 0 par CW_USEDEFAULT CW_USEDEFAULT CW_USEDEFAULT CW_USEDEFAULT

  style par IF WS_CHILD OR THEN

  0 ca 0 CreateWindowExA

;

 

: WindowDelete ( hwnd -- )   \ удалить окно

  DestroyWindow DROP  ( fr=0ok 0<> err )

;

 

: WindowPos ( x y hwnd -- )   \ установить позицию окна

  || x y hwnd || (( x y hwnd ))

  SWP_NOZORDER SWP_NOSIZE OR 0 0 y x 0 hwnd SetWindowPos DROP

;

 

: WindowSize ( dx dy hwnd -- ) \ установить размеры окна

  || dx dy hwnd || (( dx dy hwnd ))

  SWP_NOZORDER SWP_NOMOVE OR dy dx 0 0 0 hwnd SetWindowPos DROP

;

 

: WindowToTop ( hwnd -- )

  \ выпихнуть окно поверх других

  \ но не влияет на активность окон и другие приложения

  BringWindowToTop DROP

;

 

: WindowActivate ( hwnd -- ) \ активизировать окно

  SetActiveWindow DROP

;

 

: WindowToForeground ( hwnd -- )

  \ наиболее активная форма выдвижения окна :)

  \ рекомендуется только для критических сообщений

  SetForegroundWindow DROP

;

 

: WindowShow ( hwnd -- )   \ показать окно

  SW_SHOW SWAP ShowWindow DROP

;

 

: WindowHide ( hwnd -- )

 \ спрятать окно (сделать невидимым, но не уничтожить)

  SW_HIDE SWAP ShowWindow DROP

;

 

: WindowMinimize ( hwnd -- )  \ свернуть окно

  CloseWindow DROP

;

 

: WindowRestore ( hwnd -- ) \ развернуть окно назад

  SW_RESTORE SWAP ShowWindow DROP

;

 

: MessageLoop ( wnd --  пример цикла окна без адреса данных )

 \ обработка сообщений, поступающих в очередь окна

  || wnd mem || (( wnd ))

  /MSG ALLOCATE THROW -> mem

  BEGIN

    wnd IsWindow

    IF

      0 0 wnd mem GetMessageA 0 >

      mem CELL+ @ WM_CLOSE <> AND

    ELSE FALSE THEN

  WHILE

    DEBUG @ IF mem 16 DUMP CR THEN

    mem TranslateMessage DROP

    mem DispatchMessageA DROP

  REPEAT

  mem FREE THROW

;

 

 

 

: MessageLoop_D ( Ast wnd -- АДРЕС данных в реальных реализациях даем свой адрес )

 \ обработка сообщений, поступающих в очередь окна

 \  вводим адрес выхода из цикла т если там -1 то  выходим из цикла

 \ т это ситуация занятия ресурсов виндовса

  || wnd mem Ast || ( LOCALNO )

   -> wnd    -> Ast  (   Ast @   тут передаем команду -1 на выход или что угодно )

   /MSG ALLOCATE THROW -> mem

   Ast 0! ( начался цикл то внешнюю программу можно продолжить )

   BEGIN

         wnd IsWindow

         IF

           0 0 wnd mem GetMessageA 0 >

           mem CELL+ @ WM_CLOSE <> AND

         ELSE     FALSE THEN

          Ast @ IF   DROP 0  THEN ( ЕСЛИ  ТАМ -1 то  пишем 0 и выход из цикла выход )

  WHILE

         DEBUG @ IF mem 16 DUMP CR THEN

         mem TranslateMessage DROP

         mem DispatchMessageA DROP

  REPEAT

  mem FREE THROW

\ вышли из цикла по внешней или внутренней команде

  wnd     DestroyWindow  DROP  ( fr=0ok 0<> err  удалили )

  Ast 0! ( 0=  для выхода из внешнего цикла т тут все закончили   )     

 ;

 

:NONAME  ( поток   стиль окна определен константой SPF_STDEDIT  ) 

  || h ||  ( локальная переменная h - идентификатор окна )

   S" RichEdit20A"  SPF_STDEDIT 0 Window -> h 

   500000 0 EM_EXLIMITTEXT h PostMessageA DROP

   400 200 h WindowPos

   150 250 h WindowSize

   h WindowShow

   h WindowMinimize

   h WindowRestore

   S" 1234" DROP  h MessageLoop_D  ( АДРЕС данных в реальных реализациях даем свой адрес )

               \  h MessageLoop ( пример цикла окна без адреса данных )

   h WindowDelete

;  TASK:  CREATE_WIN_NEW (  создание нового  окна )

 

\EOF 

текст программы окончен.

 

 

Пример 1.   Сформировать окна, используя библиотеки формирования окна.  

 

 

\ начало  текста  test2.f

 S" liber1\create_okon1.f"  INCLUDED    ( подключаем библиотеку создания окон )

 

: MAIN (  главное слово создаем 2а окна )

     S" Формирование  окон windows  "  ANSI>OEM TYPE   

 CR  S" выход по клавише =tab= "       ANSI>OEM TYPE    

     CREATE_WIN_ NEW   ( окно для информации текстом )

  BEGIN

   ?KEY1 DUP  0x9 <>

  WHILE ( K -- код нажатой клавиши )

     DUP [CHAR] 1 = IF  CREATE_WIN_NEW  START   THEN     DROP

   REPEAT DROP       BYE

   ;

 

S" liber1\out_file_write.f"  INCLUDED    ( подключаем библиотеку для записи файла и выхода из компиляции )

\ текст программы окончен.

 

Рассмотрим особенности создания окон

 : CLOVO1 ….    ;  ( слово описания потока )

CLOVO1 ( a-- ) TASK:  CREATE_WIN_NEW   (  формирование адреса для запуска потока )  

 

  Отвлечение руководителя анекдот по теме лекции но, на лекции не озвучивать;

·         Ну вы мне все рассказали досконально, наконец то я все поняла. Последний вопрос - как помыть стёкла внутри стеклопакета?

 

Формирование окон по условиям задачи

 

Тексты программ увеличиваются и поэтому, дальше разбираем только отдельные значимые элементы. Рассмотрим возможность  и способы передачи «тревожного» сообщения в окнах.

·         Задача: при нажатии клавиши 1 – окно   DIN1 выдается сообщение.  

·         Библиотека окна DIN1 содержит слово PKZ_2_MN_DIN1.

·         При выполнении этого слова в потоке окна проводиться опрос клавиатуры только для активного окна и если совпал код клавиши =1=, выполняется  звуковое сообщение – слово OUT_MUZ_FRAGMENT_DIN1

 

 

Пример 2.   Формируются окна  с графическим  и текстовым интерфейсом. 

 

\ начало  текста  test2.f

 S" liber1\create_okon1.f"  INCLUDED    ( подключаем библиотеку создания окон )

 S" liber1\din1_ver1.f"    INCLUDED    ( подключаем библиотеку создания окон c графическим выводом )

 

 

: MAIN (  главное слово создаем  окно времени с графическим выводом )

    || S1 ||  ( локальная переменная только для этого слова )

\   STARTLOG ( ВКЛЮЧИТЬ ФАЙЛ ОТЧЕТА SPF.LOG )

\   ENDLOG (  выключить файл отчета )

     S" Формирование  окон windows  "  ANSI>OEM TYPE   

 CR  S" выход по клавише =tab= "       ANSI>OEM TYPE    

 CR  S" кл 1 - формирует текстовые окна с накоплением; "       ANSI>OEM TYPE    

 CR  S" кл 2 - управляет окном выдачи времени;"       ANSI>OEM TYPE     

     CREATE_WIN_DIN1     ( слово работает в библиотеке окон с графическим выводом )

  BEGIN

   ?KEY1 DUP  0x9 <>

  WHILE ( K -- код нажатой клавиши )

     DUP [CHAR] 1 = IF  CREATE_WIN_NEW  START   THEN

     DUP [CHAR] 2 = IF  S1  0=   IF  -1  CLOSE_WIN_DIN1_PZ1 ! CLOSE_WIN_DIN1 -1 ELSE CREATE_WIN_DIN1 0 THEN -> S1

                    THEN

   DROP

   REPEAT DROP

      BYE

   ;

 

S" liber1\out_file_write.f"  INCLUDED    ( подключаем библиотеку для записи файла и выхода из компиляции )

\ текст программы окончен.

 

Обратите внимание, что в теле основного слова, нет работы с окном DIN1.  Программа начинает работать формирует новый поток с графическим выводом .

По клавише 2 – окно можно закрыть и повторное нажатие вновь формирует окно.

 Ниже скан слова в графическом окне с условным названием DIN1  Слово PKZ_2_MN_DIN1 определяет действия при нажатии мышки или клавиши клавиатуры в этом окне.

Назначение слов  входящих в действия по клавишам меню:

 

Важно подробное рассмотрение ключевого слова выполнения.  Все  составляющие элементов должны иметь назначение.

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

Укажем слова для оформления стиля графического окна и надписей.

 

Пример 3.  Формируем два окна с графическим интерфейсом. А окно терминала убираем из отображения. Но поток терминала остается.    Одно окно DIN1 второе DIN12 и скрытый поток, который отображался ранее в терминальном режиме.   

 

 

\ начало  текста  test2.f

 

S" liber1\create_okon1.f" INCLUDED ( подключаем библиотеку создания окон )

S" liber1\din1_ver1.f"  INCLUDED ( подключаем библиотеку создания окон  DIN1 графика )

S" liber1\din1_ver12.f" INCLUDED ( подключаем библиотеку создания окон DIN2 графика )

 

: MAIN (  главное слово создаем  два окна с графическим выводом без консоли )

    || S1 ||  ( LOCALNO )

\   STARTLOG ( ВКЛЮЧИТЬ ФАЙЛ ОТЧЕТА SPF.LOG )

\   ENDLOG (  выключить файл отчета )

     S" Формирование  окон windows  "  ANSI>OEM TYPE   

 CR  S" выход по клавише =tab= "       ANSI>OEM TYPE    

 CR  S" кл 1 - формирует текстовые окна с накоплением; "       ANSI>OEM TYPE    

 CR  S" кл 2 - управляет окном выдачи времени;"       ANSI>OEM TYPE     

     CREATE_WIN_DIN1     ( слово работает в библиотеке окон с графическим выводом )

     CREATE_WIN_DIN12     ( слово работает в библиотеке окон с графическим выводом )

  BEGIN

CLOSE_WIN_DIN1_PZ1  @ IF CLOSE_WIN_DIN1 THEN  ( по нажатию alt+f4 окно 1 пишется признак -1 )

CLOSE_WIN_DIN12_PZ1 @ IF CLOSE_WIN_DIN12 THEN (по нажатию alt+f4 окно 1 пишется признак -1 )

Myhwnd_DIN1    0=  Myhwnd_DIN12  0=  AND    IF BYE THEN  ( выход по условию =И= прекращения работы 2х окон )

   ?KEY1 DUP  0x9 <>

  WHILE ( K -- код нажатой клавиши )

    DUP [CHAR] 2 = IF  S1  0=   IF  -1  CLOSE_WIN_DIN1_PZ1 ! CLOSE_WIN_DIN1 -1 ELSE CREATE_WIN_DIN1 0 THEN -> S1   THEN

   DROP

   REPEAT DROP

      BYE

   ;

 

 -1  TO ?GUI  (  =0 есть СМД    =-1  нет СМД  установить убрать консоль  - эта строчка закрывает консоль для компиляции  )

 S" liber1\out_file_write.f"  INCLUDED    ( подключаем библиотеку для записи файла и выхода из компиляции )

\ текст программы окончен.

 

После компиляции и выполнения программы сформируется два окна, как показано ниже на скан.

·         Нет консоли с черно белым алфавитно-цифровым выводом. Есть два окна, с возможностью выдачи данных и виде знаков, и виде растровой графики.

·         Количество потоков можно определить по диспетчеру задач или по программе   procexp.exe Ниже скан состояния процесса с тремя потоками для данной программы

  

 

Обратите внимание, окон два - а потока три. И в целом программа занимает достаточно много ресурсов процессора более 50%. На практике, для задач, не требующих большого быстродействия устанавливаются в основные цикл участки тайм-аутов.  В нашем случае эту функцию выполняет слово PAUSE1

  

 

 

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

В начале, должна быть цель программы, и затем определять, сколько Вам требуется для этого окон, какие они должны быть и пр. Это творческая задача и обычно она решается поэтапно.

 

Многооконность на примере автоматического трассировщика ;          

Покажем возможности и «мощность» многооконного интерфейса. Скачать программу автоматической трассировки DipTrace 2.4.0.2 Full portable   Не коммерческая версия. Распаковать в отдельную папку. В папке  имеется 4-е файла приложения.

Все приложения имеют свои окна, которые могут запускать и  другие приложения. Например- запускаем файл  первого приложения Schematic.exe  редактор схем.  После подготовки схемы, из  первого приложения можно запустить приложение PCB Layout.exe 

 

 

Это независимые приложения, каждое из которых  работает самостоятельно. Однако, включить и выключить их можно друг от друга.  В самом приложении открываются много других окон. Например, ниже показано открытие 3D – модели схемы.

 

Список задач программирование  окон ;          

 

Модификация – 1-й уровень понимания (оценка 3-  ).

  1. В примере 1 – ввести в переменную DEBUG разрешение  на работу в окне. Пояснить, что  выдается на консоль.
  2. В примере 1 –  изменить расположение построения окон  из условия (№-номер_студента_по_списку*0x10) размер окна,    (№-номер_студента_по_списку*0x20) – координаты левой верхней точки окна
  3. В примере 1 – установить стиль WS_EX_PALETTEWINDOW
  4. В примере 2 –  изменить включение выключение графического окна  на другую клавишу. Использовать первую букву своей фамилии.  В отчете и в стартовом меню  указать какую букву надо нажимать. Буквы русские заглавные.
  5. В примере 3 -  установить отображение консоли и убрать возможность выхода по клавише =TAB=  

 

Новые свойства – 2-ой уровень понимания. ( оценка 4-  )

  1. В  примере 2 – ввести включение по клавише 2 разрешние DEBUG и повторное нажатие клавиши 2 прекращение DEBUG  Пояснить, что выдается на консоль.
  2.  В примере 3 – ввести  двум окнам индивидуальное музыкальное сообщение.  Т.е. одно окно при нажатии одно сообщение, второе при нажатии другое сообщение. Файлы музыкальных сообщений взять из Л6
  3.  В примере 3 – ввести в отображение заголовка окна свои реквизиты, ФИО номер группы  для одного окна. В  заголовок второго окна ввести название лекции.   При нажатии клавиши 3 на обеих окна перейти на сайт лекции Л8

 

Изменения алгоритма – 3-ий уровень понимания и создания. ( оценка 5-)

  1. В примере 3 ввести третье окно DIN13, которое вызывается по нажатию клавиши 2  из первого или второго окна.  
  2. В примере 3 ввести автоматическое  определение размера окон и их расположение по правилу: рабочий стол делиться  по вертикали на  три равных участка и по горизонтали на три равных участка. Т.е. по образу игры в крестики-нолики.  Расположить первое окно в левой верхней части, второе окно под ним,
  3. В примере 3  отображать стиль с движками и сделать =неудаляемость окон=. Т.е. если нажать аlt+f4 окно закроется и снова сформируется. Пример такой возможности в архиве файл называется test2_не удаляйка.exe Предусмотреть аварийный выход, без использования диспетчера задач.

 

Задача практической полезности

  1. Программа для отображения данных прибора  СК4-Белан. Цель программы  запрашивать данные через порт и отображать в оконном режиме.

 Литература

 

 

 

 

Выводы:

 

 

23-3-2016

 

Автор Шабронов Андрей Анатольевич тс. 913-905-8839  shabronov@ngs.ru