purebasic.info

PureBasic forum
Текущее время: Вт дек 11, 2018 6:14 am

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




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

Зарегистрирован: Сб окт 31, 2009 7:44 am
Сообщений: 168
Благодарил (а): 92 раз.
Поблагодарили: 5 раз.
Пункты репутации: 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
Сообщений: 11336
Благодарил (а): 4 раз.
Поблагодарили: 443 раз.
bizdon писал(а):
Новая функция Event() никак не спасает ситуацию..
Почему? Нужен пример кода показывающий такую ситуацию.
Bind событий позволяет обрабатывать их даже в DLL. EXE может быть написан не на PB, а на другом ЯП.

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

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


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

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


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

Зарегистрирован: Вт дек 05, 2006 8:46 am
Сообщений: 6412
Благодарил (а): 21 раз.
Поблагодарили: 200 раз.
Пункты репутации: 52
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
Сообщений: 6412
Благодарил (а): 21 раз.
Поблагодарили: 200 раз.
Пункты репутации: 52
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
Сообщений: 11336
Благодарил (а): 4 раз.
Поблагодарили: 443 раз.
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
Сообщений: 11336
Благодарил (а): 4 раз.
Поблагодарили: 443 раз.
Пётр писал(а):
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]
Скачиваний: 33

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

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


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

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

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


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Пн ноя 19, 2018 8:10 pm 
Не в сети
профессор

Зарегистрирован: Вс июл 05, 2009 5:55 pm
Сообщений: 336
Благодарил (а): 1 раз.
Поблагодарили: 11 раз.
Пункты репутации: 0
Цитата:
Не могу понять логику работы "SetWindowData"
А я немогу понять назначение или где это применить, больше похоже на то как зачем зайцу стоп-сигнал :roll: .
В TreeGadget с итемами понятно, Фред итемы тасует всегда вот и теряется гдето, а тут чего
теряется, открыл окно с номером один и пока незакроешь оно так и останется номер один хоть сто окон создай не сменится, да и есть хендл , тож не меняется.

Может поздновато но кину код, иногда бывает нужно когда тянеш скрол и нужно чегото обтобразить, а обработчик завис на WaitWindowEvent и пока не одпустишь скрол картинку нет возможности обновить, может BindEvent и можно это решить но по каждому чиху бинды создавать негодится, ну конечно для скрола только один прикол, так у других этих приколов хватает.
Обработка оконной процедуры на уровне АПИ что появилась со временем на пурике и облегчила жизнь чтобы несоздавать привязку новых оконных процедур к окну, имеюю ввиду SetWindowCallback.

показывает положение полосы прокрутки, можно выводить текст в редактор например с изменением полосы прокрутки когда она неодпущена
Код:
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
#Scroll=1
 
Procedure WinCallback(hWnd, uMsg, WParam, LParam)
    ; Windows fills the parameter automatically, which we will use in the callback...
    Global n
    If uMsg = #WM_SIZE
        Select WParam
            Case #SIZE_MINIMIZED
                Debug "Window was minimized"
            Case #SIZE_RESTORED
                Debug "Window was restored"
            Case #SIZE_MAXIMIZED
                Debug "Window was maximized"
        EndSelect
    EndIf
    Debug uMsg
    If IsGadget(#Scroll);тут нужно обязательно проверять наличие гаджета иначе после закрытия окна, вызывает ошибку, помоему какойто есть меседж по этому поводу, я гдето иначе это делал
        Debug Str(N)+"     Scroll: "+Str(GetGadgetState(1))
    EndIf
   
    n+1
    ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
 
 
Global Hwnd_Scroll
If OpenWindow(0, 0, 0, 300, 200, "Messages", #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
    Hwnd_Scroll=ScrollBarGadget (#Scroll, 170, 40,  25, 120 ,0, 300, 50, #PB_ScrollBar_Vertical)
    SetWindowCallback(@WinCallback())    ; activate the callback
   
    Repeat
        Select WaitWindowEvent()
            Case #PB_Event_CloseWindow
                End
        EndSelect
    ForEver
   
EndIf


_________________
искатель истины


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

Зарегистрирован: Вт дек 05, 2006 8:46 am
Сообщений: 6412
Благодарил (а): 21 раз.
Поблагодарили: 200 раз.
Пункты репутации: 52
balex1978, внутри Procedure принято объявлять вместо Global n более безопасную в плане совместимости с другими переменными проекта Static n

_________________
read-only ¯\_(ツ)_/¯


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

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


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

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


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

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