Как запретить повторное открытие окна из меню

Clarion, Clarion 7

Модератор: Дед Пахом

Правила форума
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
Ответить
alex789
Новичок
Сообщения: 12
Зарегистрирован: 15 Март 2009, 11:46

Как запретить повторное открытие окна из меню

Сообщение alex789 »

Суть простая. Есть browse с номенклатурой, когда из меню APPFrame вызываю эту процедуру start(browse,50000) открывается окно. Хочется при повторном открытии не открывать еще одно окно, а активизировать уже открытое.
vd-vuf
Бывалый
Сообщения: 61
Зарегистрирован: 12 Декабрь 2008, 12:09
Откуда: Верхний Уфалей
Контактная информация:

Re: Как запретить повторное открытие окна из меню

Сообщение vd-vuf »

давным давно сочинил простенький шаблон.
не нравится шаблон, думаю что по коду понятно что нада делать:
в глобальную переменную записываем номер thread.
При запуске процедуры проверяем,
если там не ноль то активируем тот thread что прописан в глобальной переменной и уходим.
А если ноль то прописываем туда текущий thread, по завршеню работы обнуляем.
(шаблон работает и с сурце процедурой, но код завршеиия нужно вписать руками)

Код: Выделить всё

#EXTENSION (OneProcOneTime, 'Запрещение повторного запуска процедуры'),PROCEDURE
#BOXED('')
  #DISPLAY('Запрещение повторного запуска процедуры')
#ENDBOXED
#AT(%GlobalData)
OneProc:%Procedure  LONG
#ENDAT
#AT(%ProcessedCode),FIRST
  #IF(UPPER(%ProcedureTemplate) = 'SOURCE')
  IF OneProc:%Procedure = 0
    OneProc:%Procedure = THREAD()
  ELSE
    SYSTEM{PROP:Active} = OneProc:%Procedure
    #EMBED(%OneProcReturnCode,'"OneProc" Return Code IF Procedure Not One')
  END
  #ENDIF
#ENDAT
#AT(%ProcessedCode),LAST
  #IF(UPPER(%ProcedureTemplate) = 'SOURCE')
  OneProc:%Procedure = 0
  #ENDIF
#ENDAT
#AT(%WindowManagerMethodCodeSection,'Run','(),BYTE'),FIRST
IF OneProc:%Procedure = 0
  OneProc:%Procedure = THREAD()
ELSE
  SYSTEM{PROP:Active} = OneProc:%Procedure
  RETURN 0
END
#ENDAT
#AT(%WindowManagerMethodCodeSection,'Run','(),BYTE'),LAST
OneProc:%Procedure = 0
#ENDAT
Последний раз редактировалось vd-vuf 02 Июнь 2009, 9:07, всего редактировалось 1 раз.
Dias2004
Посетитель
Сообщения: 29
Зарегистрирован: 31 Январь 2006, 15:02
Откуда: Россия, Москва

Re: Как запретить повторное открытие окна из меню

Сообщение Dias2004 »

Решение первой половины задачи - запрет повторного вызова MDI child - описан в HELP (я читал в Clarion 6.0 и старше) в разделе How To в статье Manage Threads. Я использовал - работает.

На всякий случай привожу исходный текст :)
Если есть проблемы с переводом - обращайся.

This topic will show you how to limit an MDI Child browse procedure to a single instance using messaging.
The simplest solution is to disable the menu item when the browse procedure is active. You can't do this in the menu itself--you must send a message to the Frame procedure from the browse.
First you need to declare two new events in the Global Properties, Global Data embed point:

EVENT:DisableCustomerItem EQUATE(401h)
EVENT:EnableCustomerItem EQUATE(402h)

(Note that user-defined events must start after 400h.)
You also need a global variable, define this in Global Properties, Data. Call this GLO:MainThreadNo, make it a BYTE.
In the Frame procedure, WindowManager Executable Code--Init embed, type the following:

GLO:MainThreadNo = THREAD()

(Whenever an MDI procedure is STARTed, a thread number is allocated to it. We need the thread number in order to post a message to the frame procedure.)
Now, still in the frame procedure, you need to write code in the WindowManager Executable Code--TakeWindowEvent [Priority: 2800] embed to handle the two user-defined events that the frame procedure will receive.

OF EVENT:DisableCustomerItem
DISABLE(?ShowCust)
OF EVENT:EnableCustomerItem
ENABLE(?ShowCust)

In the Browse procedure, in the WindowManager Executable Code--Init [Priority:5600] embed, type:

POST(EVENT:DisableCustomerItem,,GLO:MainThreadNo)

In the WindowManager Executable Code--Kill [Priority:8000] embed, type:

POST(EVENT:EnableCustomerItem,,GLO:MainThreadNo)

Now, the first time you select the Browse Procedure from your menu, ShowCust starts up, the POST() statement executes and an EVENT:DisableCustomerItem is sent to the Frame procedure.
If the user then clicks on the menu again, the message is processed and the item is disabled.
As the user exits ShowCust, the EVENT:EnableCustomerItem message is sent to the Frame. When that message is processed the menu item is enabled again.
Why store the Frame's thread number - surely it would always be number 1? Well it might NOT be the first thread in the application.

Thanks to Rob Mousley of Chariot Software for submitting this topic.
Ответить