Вверх ↑
Этот топик читают: Гость
Ответов: 1536
Рейтинг: 176
#1: 2016-04-03 01:15:18 ЛС | профиль | цитата
Нужно, чтобы подсвечивалась только выбранный пункт меню, всё остальное "тухло".
меню.gif
Add(MainForm,2953706,126,70)
{
}
Add(MenuEx,3447409,322,175)
{
Menu=#4:меню|4:меню|4:меню|4:меню|0:|
Font=[Calibri,12,0,0,204]
SelCheckColor=128
Bitmaps=[]
Point(doIdxHighlight)
link(MenuItemIdx,14021391:doGetString,[(366,181)(366,131)(107,131)(107,195)])
}
Add(Str_Enum,4778939,182,175)
{
Delimiter=""
link(onEnum,6631447:doConvert,[])
}
Add(MathParse,4657920,182,217)
{
DataCount=1
MathStr="%1 - 1"
ResultType=0
Point(reCalc)
link(X1,4778939:NumSubStr,[])
}
Add(Convertor,6631447,224,175)
{
Mode=1
link(onResult,8466411:doAdd,[])
}
Add(StrList,14021391,126,147)
{
Strings=#4:1000|4:0100|4:0010|4:0001|
Point(doGetString)
Point(onGetString)
link(onGetString,4778939:doEnum,[(167,160)(167,181)])
}
Add(MT_Add,8466411,273,175)
{
InputMT=1
link(onAdd,3447409:doIdxHighlight,[])
link(Data,4657920:reCalc,[(279,163)(240,163)(240,261)(195,261)])
}
карма: 1
Не так страшна ошибка, как опасность её не заметить.

0
файлы: 1меню.gif [744.6KB] [924]
Ответов: 1926
Рейтинг: 172
#2: 2016-04-03 11:10:40 ЛС | профиль | цитата
Да тут проблема в KOL.
Кто разбирается: зайдите на 897 строчку файла XPMenus.pas и ниже добавьте такой код:
#pas
msgbox(int2str(integer(Menu.Items[Idx].Highlight)),0);

Чтобы получилось:
#pas
procedure TXPMenu._work_doHighlight;
var Idx:integer;
begin
Idx:= ReadInteger(_Data,_data_Index,_prop_Index);
if (Menu.Count > 0) and (Idx >= 0 ) and (Idx < Menu.Count) then
Menu.Items[Idx].Highlight:= not Menu.Items[Idx].Highlight;
msgbox(int2str(integer(Menu.Items[Idx].Highlight)),0);
end;

Вы увидите, что сообщение выдаёт каждый раз единицу!
Т.е. снять состояние (флаг) подсветки невозможно, а оно реализуется в kol.
------------ Дoбавленo в 11.10:
Оказывается, проблема даже не в KOL, а в windows.

Кто хочет копнуть глубже:
1. В КОЛ есть описание:
#pas
property Highlight: Boolean index MFS_HILITE read GetState write SetState;
{* Highlight state of the item. }

2. Также есть реализация:
#pas
//[procedure TMenu.SetState]
procedure TMenu.SetState( const Index: Integer; Value: Boolean );
var MII: TMenuItemInfo;
begin
GetState( 0 );
if Value xor (Index < 0) then
FSavedState := FSavedState or DWORD( Index and $7FFFFFFF )
else
FSavedState := FSavedState and not DWORD( Index );
if FVisible then
begin
MII.fMask := MIIM_STATE;
if GetInfo( MII ) then
begin
MII.fState := FSavedState;
SetInfo( MII );
end;
end;
end;

3. Задействуется ф-ция SetInfo:
#pas
//[function TMenu.SetInfo]
function TMenu.SetInfo( var MII: TMenuItemInfo ): Boolean;
var H: THandle;
begin
MII.cbSize := MenuStructSize;
H := FHandle;
if FParent <> nil then
H := FParent.FHandle;
Result := SetMenuItemInfo( H, FId, FALSE, Windows.PMenuitemInfo( @ MII )^ );
if Result and ((FParent = nil) or (FParent.FParent = nil)) then {YS}
RedrawFormMenuBar;
end;

4. И вот тут ф-ция винды SetMenuItemInfo, которая и выдаёт такой косяк, как описывает LeonCrew здесь: http://rsdn.ru/forum/winapi/2209306.all

текст http://rsdn.ru/forum/winapi/2209306.all
Возникла проблема, не возможно снять установленый флаг "подсветки" итема меню.
Устанавливается очень просто:

memset(&mmi, 0, sizeof(MENUITEMINFO));
mmi.cbSize = sizeof(MENUITEMINFO);
mmi.fMask = MIIM_STATE;
mmi.fState = MFS_HILITE;
SetMenuItemInfo(hMenu, m_iOverMenuItemId, FALSE, &mmi);


И сбрасываться должен просто:

memset(&mmi, 0, sizeof(MENUITEMINFO));
mmi.cbSize = sizeof(MENUITEMINFO);
mmi.fMask = MIIM_STATE;
mmi.fState = MFS_UNHILITE;
SetMenuItemInfo(hMenu, m_iOverMenuItemId, FALSE, &mmi);


Нигде никаких ошибок не возвращает, просто не сбрасывается флаг и все... Решил подсмотреть как делает MS в данном случае, но там оказалось все гениально просто, они напрямую работают со структурой итема и не используют никакие функции. Тогда решил посмотреть, а как реализована сама функция SetMenuItemInfo и вот тут удивился....

...
if (lpmii->fMask & MIIM_STATE) {
/*
* Preserve private bits (~MFS_MASK).
* Also preserve MFS_HILITE | MFS_DEFAULT if already set; if not set,
* let the caller turn them on.
*/
UserAssert(!(lpmii->fState & ~MFS_MASK));
pItem->fState &= ~MFS_MASK | MFS_HILITE | MFS_DEFAULT;
pItem->fState |= lpmii->fState;
if (pItem->fType & MFT_SEPARATOR)
pItem->fState |= MFS_DISABLED;
fRedraw = TRUE;
}
...


Получается, что единожды установленый флаг MFS_HILITE или MFS_DEFAULT больше не сбрасывается...
Кто как решил данную проблему "подсветки" итема?

Вывод: стандартными средствами это не исправить (поправьте, если ошибаюсь). Надо искать обходные пути.
карма: 9
0
Ответов: 9906
Рейтинг: 351
#3: 2016-04-03 12:14:45 ЛС | профиль | цитата
Ну вот...
А то сразу kol, kol ...


------------ Дoбавленo в 12.14:
И ведь что занимательно: сбросить подсветку таки можно.
Если почесать левой ногой правое ухо

Add(MenuEx,3447409,273,98)
{
Menu=#4:меню|4:меню|4:меню|4:меню|0:|
Font=[Calibri,12,0,0,204]
SelCheckColor=128
Bitmaps=[]
Point(doIdxHighlight)
link(MenuItemIdx,1570114:doValue,[])
link(Index,1686810:Var1,[(286,89)(314,89)(314,138)])
}
Add(Memory,1570114,336,98)
{
link(onData,16652447:doRead,[])
}
Add(IntegerArray,1557145,399,35)
{
IntArray=['0'=0,'0'=0,'0'=0,'0'=0]
}
Add(ArrayRW,16652447,399,98)
{
link(onRead,7112816:doOperation,[])
link(Array,1557145:Array,[])
link(Index,1686810:Var3,[(412,89)(377,89)(377,138)])
}
Add(GetDataEx,1686810,336,133)
{
link(Data,1570114:Value,[])
}
Add(Hub,3081202,497,98)
{
link(onEvent1,3447409:doIdxHighlight,[(522,104)(522,83)(263,83)(263,104)])
link(onEvent2,16652447:doWrite,[(522,111)(522,139)(389,139)(389,111)])
}
Add(Math,7112816,448,98)
{
OpType=6
Op2=1
ResultType=0
link(onResult,3081202:doEvent1,[])
}

карма: 9

0
Ответов: 1536
Рейтинг: 176
#4: 2016-04-03 14:16:40 ЛС | профиль | цитата
Получается, программно подсветку установить можно, а вот снять, только ручками.
Add(MainForm,2953706,21,105)
{
Width=308
Height=222
}
Add(MenuEx,3447409,105,161)
{
Menu=#4:меню|4:меню|4:меню|4:меню|0:|
Font=[Calibri,12,0,0,204]
SelCheckColor=128
Bitmaps=[]
Point(doIdxHighlight)
link(MenuItemIdx,1570114:doValue,[])
link(Index,1686810:Var1,[(118,152)(146,152)(146,201)])
}
Add(Memory,1570114,168,161)
{
Default=Integer(0)
link(onData,11987719:doWork2,[])
}
Add(IntegerArray,1557145,329,77)
{
IntArray=['0'=0,'0'=0,'0'=0,'0'=0]
}
Add(ArrayRW,16652447,252,161)
{
link(onRead,7112816:doOperation,[])
link(Array,15642335:Var1,[(258,128)])
link(Index,1686810:Var3,[(265,152)(213,152)(213,201)])
}
Add(GetDataEx,1686810,168,196)
{
link(Data,1570114:Value,[])
}
Add(Hub,3081202,357,161)
{
OutCount=3
link(onEvent1,3447409:doIdxHighlight,[(376,167)(376,143)(92,143)(92,167)])
link(onEvent2,16652447:doWrite,[(388,174)(388,208)(241,208)(241,174)])
link(onEvent3,11200908:doEvent1,[])
}
Add(Math,7112816,301,161)
{
OpType=6
Op2=1
ResultType=0
link(onResult,3081202:doEvent1,[])
}
Add(ArrayEnum,16284858,504,182)
{
link(onItem,10105664:doAdd,[(555,188)(555,174)])
link(Array,15642335:Var3,[(510,128)])
}
Add(Button,11114107,105,217)
{
Left=15
Top=60
link(onClick,11850020:doData,[])
}
Add(Memo,10105664,567,168)
{
Left=85
Top=65
Strings=#1:0|1:0|1:0|1:0|
}
Add(DoData,11850020,168,217)
{
link(onEventData,11987719:doWork3,[(228,223)])
link(Data,1686810:Var2,[])
}
Add(HubEx,11987719,224,161)
{
link(onEvent,16652447:doRead,[])
}
Add(GetDataEx,15642335,329,123)
{
link(Data,1557145:Array,[])
}
Add(Hub,11200908,476,175)
{
link(onEvent1,10105664:doClear,[])
link(onEvent2,16284858:doEnum,[])
}


Ну, хрен с ней, найду что-нибудь другое.
карма: 1
Не так страшна ошибка, как опасность её не заметить.

0
Ответов: 9906
Рейтинг: 351
#5: 2016-04-03 14:27:55 ЛС | профиль | цитата
Получается, что через SetMenuItemInfo -- фигу с маслом.
Теоретически, существует еще HiliteMenuItem, но у меня чего-то нет настроения для тренировки на ней.
Без гарантированного результата ...

Может у nesco такое настроение будет (его же элемент).
карма: 9

1
Голосовали:3042
Ответов: 1926
Рейтинг: 172
#6: 2016-04-03 15:38:36 ЛС | профиль | цитата
Ещё можно сделать так. Поскольку отрисовкой выделения занимается наш файл XPMenus.pas (ф-ция _DrawItem), то эта ф-ция может определять выделенность не по флагу odsHotList (т.е. не по Menu.Items[Idx].Highlight), а по собственному флагу - глобальной переменной. По doHighlight в такую переменную будет записываться true/false, а _DrawItem будет её считывать и уже на её основе решать, рисовать выделение или нет.

Единственная опаность - не помешает ли это выделению, которое происходит не по doHighlight, а, например, по проведению над меню мышью. Но это тоже можно решить с помощью комбинации odsHotList и собственной глобальной переменной.
карма: 9
0
Разработчик
Ответов: 26156
Рейтинг: 2127
#7: 2016-04-03 16:02:10 ЛС | профиль | цитата
Galkov писал(а):
Может у nesco такое настроение будет

Никакого желания чего-то ковырять в настоящее время нет, от слова совсем.
карма: 22

0
Ответов: 1926
Рейтинг: 172
#8: 2016-04-06 06:21:47 ЛС | профиль | цитата
Вот пример с HiliteMenuItem
#pas
procedure TXPMenu._work_doHighlight;
var Idx:integer;
begin
Idx:= ReadInteger(_Data,_data_Index,_prop_Index);
if (Menu.Count > 0) and (Idx >= 0 ) and (Idx < Menu.Count) then
if Menu.Items[Idx].Highlight then
HiliteMenuItem(FC.Handle, Menu.Handle, Idx, MF_BYPOSITION or MF_UNHILITE)
else HiliteMenuItem(FC.Handle, Menu.Handle, Idx, MF_BYPOSITION or MF_HILITE);
//Menu.Items[Idx].Highlight:= not Menu.Items[Idx].Highlight;
end;

Или так:
#pas
procedure TXPMenu._work_doHighlight;
var Idx:integer;
begin
Idx:= ReadInteger(_Data,_data_Index,_prop_Index);
if (Menu.Count > 0) and (Idx >= 0 ) and (Idx < Menu.Count) then
if Menu.Items[Idx].Highlight then
HiliteMenuItem(FC.Handle, Menu.Handle, Menu.Items[Idx].MenuId, MF_BYCOMMAND or MF_UNHILITE)
else HiliteMenuItem(FC.Handle, Menu.Handle, Menu.Items[Idx].MenuId, MF_BYCOMMAND or MF_HILITE);
//Menu.Items[Idx].Highlight:= not Menu.Items[Idx].Highlight;
end;

Но оба варианта хорошо работают, лишь когда нет вложенных пунктов. Иначе получается фигня. С чем это может быть связано?
карма: 9
0
Ответов: 1926
Рейтинг: 172
#9: 2016-04-09 21:33:18 ЛС | профиль | цитата
ser_davkin, вот программное решение проблемы:

code_37176.txt

Суть здесь в том, что скрытие/показ пункта реализуется в КОЛ через его удаление и создание заново с теми же параметрами. А так как мы перед скрытием сняли флаг подсветки, то и появляется пункт заново без подсветки. А вот без удаления пункта просто снять подсветку, как уже говорил, не удастся.
карма: 9
1
файлы: 1code_37176.txt [783B] [554]
Голосовали:ser_davkin
Ответов: 1536
Рейтинг: 176
#10: 2016-04-10 09:03:47 ЛС | профиль | цитата
3042 писал(а):
вот программное решение проблемы
Galkov писал(а):
Если почесать левой ногой правое ухо

карма: 1
Не так страшна ошибка, как опасность её не заметить.

0
10
Сообщение
...
Прикрепленные файлы
(файлы не залиты)