purebasic.info

PureBasic forum
Текущее время: Пт июн 22, 2018 6:23 pm

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 9 ] 
Автор Сообщение
СообщениеДобавлено: Пт июн 08, 2018 10:10 am 
Не в сети
док

Зарегистрирован: Сб окт 31, 2009 7:44 am
Сообщений: 155
Благодарил (а): 85 раз.
Поблагодарили: 3 раз.
Пункты репутации: 0
https://www.purebasic.fr/english/viewtopic.php?f=13&t=70673&hilit=Event+%3D+Event
вроде "насущная" проблема, распространенная ситуация.. для которой так и нет решения (предлагается код на кавансе, совсем смешно). Портянки кода уже совсем неприличных размеров.. Новая функция Event() никак не спасает ситуацию.. Попутно выясняется, что функции "Bind..." страдают утечкой памяти вплоть до последних релизов.
п.с. А полез всего лишь посмотреть необходимость функции Event()..

Вот смотрю историю изменений версий:
25th July 2016 : Version 5.50
Added: #StringConstant$ syntax support, to get the address of a string constant
Ого, нужная вещь! В справке ни одного примера. Лезу на форум за примерами:
https://www.purebasic.fr/english/viewtopic.php?f=23&t=66258
Цитата:
It does not work on windows 64 either.


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Пт июн 08, 2018 11:08 am 
Не в сети
МОДЕРАТОР
Аватар пользователя

Зарегистрирован: Пн апр 09, 2007 4:53 pm
Сообщений: 11187
Благодарил (а): 4 раз.
Поблагодарили: 415 раз.
bizdon писал(а):
Новая функция Event() никак не спасает ситуацию..
Почему? Нужен пример кода показывающий такую ситуацию.
Bind событий позволяет обрабатывать их даже в DLL. EXE может быть написан не на PB, а на другом ЯП.

bizdon писал(а):
Попутно выясняется, что функции "Bind..."
Об этом было известно с самого ее появления и по моему я об этом даже писал Фреду, но он это проигнорировал.

_________________
Компьютер позволяет решать все те проблемы, которые до его изобретения не существовали. :) :)


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Пт июн 08, 2018 11:34 am 
Не в сети
док

Зарегистрирован: Сб окт 31, 2009 7:44 am
Сообщений: 155
Благодарил (а): 85 раз.
Поблагодарили: 3 раз.
Пункты репутации: 0
Пётр писал(а):
bizdon писал(а):
Новая функция Event() никак не спасает ситуацию..
Почему? Нужен пример кода показывающий такую ситуацию.
в первой ссылке речь о том, что никак не получается запрограммировать (организовать очередь обработки сообщений - без потоков и глобальных переменных), чтобы было родительское и дочернее окна, и чтобы на каждом окне шли часы без подвисаний (может, у винды такие ограничения?)


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Пт июн 08, 2018 12:05 pm 
Не в сети
МОДЕРАТОР

Зарегистрирован: Вт дек 05, 2006 8:46 am
Сообщений: 6312
Благодарил (а): 19 раз.
Поблагодарили: 189 раз.
Пункты репутации: 48
bizdon писал(а):
для которой так и нет решения

У меня такое решение.
1. Один главный цикл на всю программу где обрабатываются события от всех окон и гаджетов.
2. Заменить нативный таймер на системный из API и вызывать процедуру часов по таймеру.
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
 
Procedure Child()
  If OpenWindow(1, 550, 400, 200, 150, "child", #PB_Window_SystemMenu, WindowID(0))
     ButtonGadget(10, 100, 100, 100, 25, "click")
  EndIf
EndProcedure
 
Procedure TimerProc()
   SetGadgetText(1, FormatDate("%hh:%ii:%ss", Date()))
EndProcedure
 
 
 
If OpenWindow(0, 300, 300, 300, 200, "parent")
  ButtonGadget(0, 100, 100, 100, 25, "click")
  TextGadget(1, 0, 40, 300, 50, "Clock Display", #PB_Text_Center)
  SetTimer_(WindowID(0), 1, 1000, @TimerProc());
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_Gadget
        If EventGadget() = 0
          Child()
        ElseIf   EventGadget() = 10
          MessageRequester("","Привет от 2-го окна")
        EndIf
      Case #PB_Event_CloseWindow
        If EventWindow() = 1
          CloseWindow(1)
        EndIf
        If EventWindow() = 0
          ParentQuit = #True
        EndIf
    EndSelect
  Until ParentQuit
EndIf


_________________
read-only


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Пт июн 08, 2018 12:14 pm 
Не в сети
МОДЕРАТОР

Зарегистрирован: Вт дек 05, 2006 8:46 am
Сообщений: 6312
Благодарил (а): 19 раз.
Поблагодарили: 189 раз.
Пункты репутации: 48
bizdon писал(а):
и чтобы на каждом окне шли часы без подвисаний (может, у винды такие ограничения?)

На каждом окне часы
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
 
Procedure TimerProc()
   SetGadgetText(1, FormatDate("%hh:%ii:%ss", Date()))
EndProcedure
Procedure TimerProc2()
   SetWindowTitle(1, FormatDate("%hh:%ii:%ss", Date()))
EndProcedure
 
Procedure Child()
  If OpenWindow(1, 550, 400, 200, 150, "child", #PB_Window_SystemMenu, WindowID(0))
    ButtonGadget(10, 100, 100, 100, 25, "click")
    SetTimer_(WindowID(1), 2, 1000, @TimerProc2());
  EndIf
EndProcedure
 
 
 
If OpenWindow(0, 300, 300, 300, 200, "parent")
  ButtonGadget(0, 100, 100, 100, 25, "click")
  TextGadget(1, 0, 40, 300, 50, "Clock Display", #PB_Text_Center)
  SetTimer_(WindowID(0), 1, 1000, @TimerProc());
 
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_Gadget
        If EventGadget() = 0
          Child()
        ElseIf   EventGadget() = 10
          MessageRequester("","Привет от 2-го окна")
        EndIf
      Case #PB_Event_CloseWindow
        If EventWindow() = 1
          KillTimer_(WindowID(1),2)
          CloseWindow(1)
         
        EndIf
        If EventWindow() = 0
          ParentQuit = #True
        EndIf
    EndSelect
  Until ParentQuit
EndIf


_________________
read-only


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Пт июн 08, 2018 12:15 pm 
Не в сети
МОДЕРАТОР
Аватар пользователя

Зарегистрирован: Пн апр 09, 2007 4:53 pm
Сообщений: 11187
Благодарил (а): 4 раз.
Поблагодарили: 415 раз.
bizdon писал(а):
никак не получается запрограммировать (организовать очередь обработки сообщений - без потоков и глобальных переменных), чтобы было родительское и дочернее окна, и чтобы на каждом окне шли часы без подвисаний
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
Procedure Child_Event()
  Event = Event()
  Window = EventWindow()
 
  Select Event
    Case #PB_Event_Timer
      SetGadgetText(GetWindowData(Window), FormatDate("%hh:%ii:%ss", Date()))
    Case #PB_Event_CloseWindow
      UnbindEvent(#PB_Event_CloseWindow, @Child_Event(), Window)
      UnbindEvent(#PB_Event_Timer, @Child_Event(), Window, 0)
      RemoveWindowTimer(Window, 0)
      CloseWindow(Window)
  EndSelect
EndProcedure
 
Procedure Child()
  id=OpenWindow(#PB_Any, #PB_Ignore, #PB_Ignore, 200, 150, "child", #PB_Window_SystemMenu, WindowID(0))
  If id
    SetWindowData(id, TextGadget(#PB_Any,20, 0, 160, 30,"", #PB_Text_Right))
    AddWindowTimer(id, 0, 500)
    BindEvent(#PB_Event_CloseWindow, @Child_Event(), id)
    BindEvent(#PB_Event_Timer, @Child_Event(), id, 0)
  EndIf
EndProcedure
 
If OpenWindow(0, #PB_Ignore, #PB_Ignore, 400, 300, "parent")
  ButtonGadget(2, 100, 100, 100, 25, "click")
   
  Repeat
    Event = WaitWindowEvent()
    If EventWindow() = 0
      Select Event
        Case #PB_Event_Gadget
          If EventGadget() = 2
            Child()
          EndIf
        Case #PB_Event_CloseWindow
          Break
      EndSelect
    EndIf
  ForEver
EndIf


_________________
Компьютер позволяет решать все те проблемы, которые до его изобретения не существовали. :) :)


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Пт июн 08, 2018 9:52 pm 
Не в сети
МОДЕРАТОР
Аватар пользователя

Зарегистрирован: Пн апр 09, 2007 4:53 pm
Сообщений: 11187
Благодарил (а): 4 раз.
Поблагодарили: 415 раз.
Пётр писал(а):
Bind событий позволяет обрабатывать их даже в DLL. EXE может быть написан не на PB, а на другом ЯП.
Для примера. EXE написан на AutoIT.
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <GUIConstantsEx.au3>
 
_Main()
 
Func _Main()
        Local $hParentWin, $hButton
 
        ;Create main/parent window
        $hParentWin = GUICreate("Parent GUI",400, 300)
        $hButton = GUICtrlCreateButton("click", 100, 100, 100, 25)
 
    GUISetState(@SW_SHOW, $hParentWin)
 
        Local $hDLL = DllOpen("DLL.dll")
 
        While 1
            Switch GUIGetMsg()
                        Case $GUI_EVENT_CLOSE
                                  GUISwitch($hParentWin)
                                  GUIDelete()
                                  Exit
             case $hButton
                                DllCall($hDLL, "int", "Child")
                EndSwitch
         WEnd
 
         DllClose($hDLL)
EndFunc   ;==>_Main

DLL на PB.
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Procedure Child_Event()
  Event = Event()
  Window = EventWindow()
 
  Select Event
    Case #PB_Event_Timer
      SetGadgetText(GetWindowData(Window), FormatDate("%hh:%ii:%ss", Date()))
    Case #PB_Event_CloseWindow
      UnbindEvent(#PB_Event_CloseWindow, @Child_Event(), Window)
      UnbindEvent(#PB_Event_Timer, @Child_Event(), Window, 0)
      RemoveWindowTimer(Window, 0)
      CloseWindow(Window)
  EndSelect
EndProcedure
 
ProcedureDLL Child()
  id=OpenWindow(#PB_Any, #PB_Ignore, #PB_Ignore, 200, 150, "child", #PB_Window_SystemMenu)
  If id
    SetWindowData(id, TextGadget(#PB_Any,20, 0, 160, 30,"", #PB_Text_Right))
    AddWindowTimer(id, 0, 500)
    BindEvent(#PB_Event_CloseWindow, @Child_Event(), id)
    BindEvent(#PB_Event_Timer, @Child_Event(), id, 0)
  EndIf
EndProcedure

Если посмотреть на код DLL, видно что у него нет своего обработчика событий, а используется тот что у GUI AutoIT. При этом все нормально работает. Можно открыть множество окон, в каждом из которых свой таймер.


Вложения:
GUI_DLL.7z [354.71 KiB]
Скачиваний: 15

_________________
Компьютер позволяет решать все те проблемы, которые до его изобретения не существовали. :) :)
Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Сб июн 09, 2018 7:18 am 
Не в сети
док

Зарегистрирован: Сб окт 31, 2009 7:44 am
Сообщений: 155
Благодарил (а): 85 раз.
Поблагодарили: 3 раз.
Пункты репутации: 0
Пётр, всё круто! попробовал сам скомпилить, в том числе для х64 - работает!
Не могу понять логику работы "SetWindowData" даже читая русскую справку. Что делает эта команда, какие данные и для чего сохраняет? Можно ли вместо неё использовать переменную?


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Сб июн 09, 2018 11:26 am 
Не в сети
МОДЕРАТОР
Аватар пользователя

Зарегистрирован: Пн апр 09, 2007 4:53 pm
Сообщений: 11187
Благодарил (а): 4 раз.
Поблагодарили: 415 раз.
bizdon писал(а):
Не могу понять логику работы "SetWindowData"
Функция позволяет сохранить данные (4 или 8 байт в зависимости от разрядности системы) связав их с идентификатором окна. Т. е. доступ к данным по идентификатору окна.

_________________
Компьютер позволяет решать все те проблемы, которые до его изобретения не существовали. :) :)


Вернуться наверх
 Профиль  
 
Показать сообщения за:  Сортировать по:  
Начать новую тему Ответить на тему  [ Сообщений: 9 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 3


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Создано на основе phpBB® Forum Software © phpBB Group (блог о phpBB)
Сборка создана CMSart Studio
Русская поддержка phpBB