Кто разбирается: зайдите на 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 больше не сбрасывается...
Кто как решил данную проблему "подсветки" итема?
Устанавливается очень просто:
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 больше не сбрасывается...
Кто как решил данную проблему "подсветки" итема?
Вывод: стандартными средствами это не исправить (поправьте, если ошибаюсь). Надо искать обходные пути.