powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Как заставить несистемное меню работать как системное?
5 сообщений из 5, страница 1 из 1
Как заставить несистемное меню работать как системное?
    #38523720
Rostislav D. Kudryashov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нужно, чтоб линейка несистемного меню в верху формы продолжала реагировать на горячие клавиши после потери фокуса. Чтоб при фокусе на любом контроле формы можно было запустить действие любой кнопки в дереве из линейки меню нажатием горячей клавиши.

Если при запуске формы DEFINE MENU MyMenu IN WINDOW ... ACTIVATE MENU MyMenu NOWAIT, то меню не реагирует на свои горячие клавиши. Переводя фокус на меню, например, мышкой, восстанавливаем реакцию на горячие клавиши, уводя фокус с меню таким же способом, теряем реакцию меню на горячие клавиши.
Если же ACTIVATE MENU MyMenu без NOWAIT, то после перевода фокуса на другой контрол формы меню деактивируется - исчезает из виду и MENU()=''.
А системное меню не годится, т.к. его шрифт не поддаётся увеличению. На дисплеях с высоким разрешением в моём приложении это неприемлемо. И прописываться DEFINE MENU _MSYSMENU IN WINDOW ... тоже не хочет.

Поменять шрифт во всех системных меню в Windows через SystemParametersInfo() из API Win32 не годится, т.к. это затронет все задачи на ПК. Обрабатывать сообщение WM_NCPAINT для перерисовки системного меню в своём окне кажется чересчур трудоёмким.
Расписывать уйму ON KEY LABEL вне описания меню DEFINE PAD, DEFINE BAR тоже кажется не очень подходящим делом.
Приходится ограничиваться всплывающим меню, но может кто-то знает, как в Фоксе добиться, чтоб несистемное меню после потери фокуса продолжало реагировать на горячие клавиши?
...
Рейтинг: 0 / 0
Как заставить несистемное меню работать как системное?
    #38523878
Дед Евгений
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Поиграйся и почитай посторителем меню. Меню можно встроить в фому.

[rutube=* To attach this menu to your Top-Level form,
* call it from the Init event of the form:

* Syntax: DO <mprname> WITH <oFormRef> [,<cMenuname>|<lRename>][<lUniquePopups>]

* oFormRef - form object reference (THIS)
* cMenuname - name for menu (this is required for Append menus - see below)
* lRename - renames Name property of your form
* lUniquePopups - determines whether to generate unique ids for popup names

* example:

* PROCEDURE Init
* DO mymenu.mpr WITH THIS,.T.
* ENDPROC

* Use the optional 2nd parameter if you plan on running multiple instances
* of your Top-Level form. The preferred method is to create an empty string
* variable and pass it by reference so you can receive the form name after
* the MPR file is run. You can later use this reference to destroy the menu.

* PROCEDURE Init
* LOCAL cGetMenuName
* cGetMenuName = ""
* DO mymenu.mpr WITH THIS, m.cGetMenuName
* ENDPROC

* The logical lRename parameter will change the name property of your
* form to the same name given the menu and may cause conflicts in your
* code if you directly reference the form by name.

* You will also need to remove the menu when the form is destroyed so that it does
* not remain in memory unless you wish to reactivate it later in a new form.

* If you passed the optional lRename parameter as .T. as in the above example,
* you can easily remove the menu in the form's Destroy event as shown below.
* This strategy is ideal when using multiple instances of Top-Level forms.

* example:

* PROCEDURE Destroy
* RELEASE MENU (THIS.Name) EXTENDED
* ENDPROC

* Using Append/Before/After location options:

* You might want to append a menu to an existing Top-Level form by setting
* the Location option in the General Options dialog. In order to do this, you
* must pass the name of the menu in which to attach the new one. The second
* parameter is required here. If you originally created the menu with the lRename
* parameter = .T., then you can update the menu with code similar to the following:

* example:

* DO mymenu2.mpr WITH THISFORM,THISFORM.name
*
* Using lUniquePopups:

* If you are running this menu multiple times in your application, such as in multiple
* instances of the same top-level form, you should pass .T. to the lUniquePopups
* parameter so that unique popup names are generated to avoid possible conflicts.

* example:

* PROCEDURE Init
* DO mymenu.mpr WITH THIS,.T.,.T.
* ENDPROC
*
* Note: Parm4-Parm9 are not reserved and freely available for use with your menu code.
*

LPARAMETERS oFormRef, getMenuName, lUniquePopups, parm4, parm5, parm6, parm7, parm8, parm9
LOCAL cMenuName, nTotPops, a_menupops, cTypeParm2, cSaveFormName
IF TYPE("m.oFormRef") # "O" OR LOWER(m.oFormRef.BaseClass) # 'form' OR m.oFormRef.ShowWindow # 2
MESSAGEBOX([This menu can only be called from a Top-Level form. Ensure that your form's ShowWindow property is set to 2. Read the header section of the menu's MPR file for more details.])
RETURN
ENDIF
m.cTypeParm2 = TYPE("m.getMenuName")
m.cMenuName = SYS(2015)
m.cSaveFormName = m.oFormRef.Name
IF m.cTypeParm2 = "C" OR (m.cTypeParm2 = "L" AND m.getMenuName)
m.oFormRef.Name = m.cMenuName
ENDIF
IF m.cTypeParm2 = "C" AND !EMPTY(m.getMenuName)
m.cMenuName = m.getMenuName
ENDIF
DIMENSION a_menupops[3]
IF TYPE("m.lUniquePopups")="L" AND m.lUniquePopups
FOR nTotPops = 1 TO ALEN(a_menupops)
a_menupops[m.nTotPops]= SYS(2015)
ENDFOR
ELSE
a_menupops[1]="Отчеты"
a_menupops[2]="Справочник"
a_menupops[3]="Настройки"
ENDIF


* *********************************************************
* *
* * Menu Definition
* *
* *********************************************************
*

DEFINE MENU (m.cMenuName) IN (m.oFormRef.Name) BAR
* ...и так далее описываешь меню
]
...
Рейтинг: 0 / 0
Как заставить несистемное меню работать как системное?
    #38523964
Rostislav D. Kudryashov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дед Евгений, это у тебя случай "чужую беду - руками разведу". Конечно, фоксово меню можно поместить в форму, если объявить Form.ShowWindow = 2 && As Top-Level Form.
Беда в том, что если DEFINE MENU _MSYSMENU или DEFINE MENU MyMenu BAR, что означает одно и то же - системное меню, то Фокс игнорирует FONT Name,Size в описании меню. А если без _MSYSMENU и без BAR, то такое несистемное меню не реагирует на горячие клавиши после потери фокуса.
...
Рейтинг: 0 / 0
Как заставить несистемное меню работать как системное?
    #38523979
Дед Евгений
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
К сожалению системное меню берет настройки шрифтов и размер из системы, на то оно и системное меню и подчиняется Операционной системе, тут ничего исправить невозиможно, только если для все видов меню в окнах. А встроить системное меню в форму можно прекрасно.
...
Рейтинг: 0 / 0
Как заставить несистемное меню работать как системное?
    #38525051
Rostislav D. Kudryashov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Rostislav D. Kudryashov, Вот придумал сам. Это решение всё ж лучше, чем ничего.
Код: plaintext
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.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
PROCEDURE TMenu1
SET TALK OFF
CLEAR
SET ESCAPE OFF
SET SYSMENU TO
SET SYSMENU OFF
SET SYSMENU AUTOMATIC
HIDE MENU _MSYSMENU
PRIVATE m.fo, m.Menu_pc, m.MenuRows_pn
m.MenuRows_pn = 3
@ m.MenuRows_pn+1,0
? 'F12 to Clear Events'
m.Menu_pc = 'MyMenu' && '_MSYSMENU'
m.fo = NEWOBJECT ('MyForm')
fo.AddObject ('B1_cmd', 'CommandButton')
fo.AddObject ('B2_cmd', 'CommandButton')
STORE 100 TO fo.B1_cmd.Left, fo.B1_cmd.Top, fo.B2_cmd.Top
STORE 200 TO fo.B2_cmd.Left
fo.SetAll('Visible',.T.)
fo.Show()
PUSH KEY CLEAR
ON KEY LABEL F10 DO ToggleMenu
ON KEY LABEL F12 DO P0
ON KEY LABEL ESC EXECSCRIPT ('m.fo.Tag=""'+CHR(13)+'KEYBOARD "{ESCAPE}" PLAIN')
DO MakeMenu
HIDE MENU (m.Menu_pc) SAVE
READ EVENTS

SET SYSMENU TO DEFAULT
POP KEY
SET ESCAPE ON
SET TALK ON
ENDPROC && TMenu1

PROCEDURE P0
WAIT 'P0 ' + MENU() WINDOW
DEACTIVATE MENU ALL
RELEASE MENUS ALL
CLEAR EVENTS
ENDPROC && P0

PROCEDURE ToggleMenu (m.ByHotKey_yl)
IF PCOUNT() = 0 AND EMPTY (m.fo.Tag) && Вход по F10 для активации линейки
  m.fo.Tag = IIF (NOT EMPTY (m.fo.Tag), m.fo.Tag;
            ,IIF (TYPE ('m.fo.ActiveControl') = 'O', m.fo.ActiveControl.Name;
                 ,m.fo.Controls[1].Name))
  ACTIVATE MENU (m.Menu_pc)
ELSE
* Для деактивации по F10 или из кнопки (с линейки или по горячей клавише)
  IF PCOUNT() = 0 OR NOT m.ByHotKey_yl
    KEYBOARD '{ESCAPE}'
  ELSE && Меню было запущено по горячей клавише
    LOCAL m.I_ln, m.O_lo
    FOR m.I_ln = 1 TO m.fo.ControlCount
      IF fo.Controls[m.I_ln].Name == fo.Tag
        EXIT 
      ENDIF
    ENDFOR
    m.O_lo = m.fo.Controls[MIN(fo.ControlCount, m.I_ln)]
    m.fo.Tag = ''
    m.O_lo.SetFocus()
  ENDIF
ENDIF
ENDPROC && ToggleMenu

PROCEDURE MakeMenu
DEFINE MENU (m.Menu_pc) IN WINDOW (m.fo.Name) FONT "Courier New",16
DEFINE PAD MenuTitle1 OF (m.Menu_pc) PROMPT "MenuTitleText1" KEY Alt+1
DEFINE PAD MenuTitle2 OF (m.Menu_pc) PROMPT "MenuTitleText2" KEY Alt+2
ON SELECTION PAD MenuTitle1 OF (m.Menu_pc) MenuProc ('1')
ON SELECTION PAD MenuTitle2 OF (m.Menu_pc) MenuProc ('2')
KEYBOARD '{Escape}'       && Деактивируем меню
ACTIVATE MENU (m.Menu_pc) && NOWAIT не годится
ENDPROC && MakeMenu

PROCEDURE MenuProc (m.N_yc)
LOCAL m.ByHotKey_ll
m.ByHotKey_ll = .T.
IF EMPTY (m.fo.Tag)
  m.fo.Tag  = IIF (TYPE ('m.fo.ActiveControl') = 'O', m.fo.ActiveControl.Name;
                  ,m.fo.Controls[1].Name)
ELSE
  m.ByHotKey_ll = .F.
ENDIF
WAIT m.N_yc + ' ' + m.fo.Tag WINDOW
ToggleMenu (m.ByHotKey_ll)
ENDPROC && MenuProc

DEFINE CLASS MyForm AS Form
Left = 150
Top = 300
Width = 700

PROCEDURE Click
IF MROW (0, 0) <= m.MenuRows_pn
  THIS.Tag = THIS.ActiveControl.Name
  ACTIVATE MENU (m.Menu_pc)
ELSE
  THIS.Tag = ''
  THIS.ActiveControl.SetFocus()
ENDIF
ENDPROC && MyForm.Click

ENDDEFINE && MyForm
...
Рейтинг: 0 / 0
5 сообщений из 5, страница 1 из 1
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Как заставить несистемное меню работать как системное?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]