-
Всем привет... Не знаю, будет ли продолжение данной темы, однако...
-
Может есть у кого наработки по поводу сортировки элементов меню? Т.е. есть меню, глубина произвольная, число элементов произвольное. Надо отсортировать все меню в этом меню по алфавиту...
-
иногда пригодилось бы. Наработок нет, я вижу StrListEx-ы и создание нового меню (кстати, рабочая модификация меню в рантайме мне так и не удалась)
-
> Наработок нет, я вижу StrListEx-ы и создание нового меню Ничего против не имею, т.к. иногда главное - результат, но это способ через "одно место". Думаю оффтопа достаточно?..
Т.е. никто углубленно не работал с динамическими меню?
-
Всем привет... Нужна помощь. Глаз замылился, мозг кипит... Нужно новое видение темы. http://ifolder.ru/15309146Это проект рекурсивной сортировки меню. Затык в том, что функция InsertSubMenu, как-то так хитро добавляет SubMenu, что потом его не удалить. Если после запуска на форме кликнуть правой кнопкой, то выпадает исходное меню, затем один раз можно корректно отсортировать (т.е. сам механизм рекурсии работает верно), но вот потом, ни повторную сортировку, ни сброс к исходному меню сделать нельзя... Хелпми, помогите кто чем может...
-
у меня даже генерация твоя не пашет :) забей на кол (он зло), обратись к первоисточнику LoadMenuIndirect+ MENUITEMTEMPLATEHEADER+массив MENUITEMTEMPLATE как вариант уничтожай меню полностью и создавай заново отсортированое
-
В каком месте генерация не пашет?
-
f-11 и фсе :)
кста есть такая функция ModifyMenu мошт и сгодица
-
Как я только не пытался SubMenu двигать и ModifyMenu, и InsertMenu, и InsertMenuItem, и SetMenuItemInfo...не пашет...
А про LoadMenuIndirect я вообще не понял...он же вроде как из списка MenuItemTemplate создает меню. Или нет?
-
SetMenuItemInfo точней
-
> f-11 и фсе :) Весьма странно. ЕХЕшник в архиве работает, я ж его не с куста взял.
-
Пункт "по умолчанию", в меню может быть только один, поэтому moDefault там лишние и генерация не пашет, по крайней мере, в Win7. А сортировке проблема, если в подменю первый пункт тоже подменю.
-
LoadMenu грузит из ресурсов а LoadMenuIndirect создает из MenuTemplate который програмно создаеш
если не получается через api поменять итем например SetMenuItemInfo значит чето не так делаеш, тогда проще пересоздать полностью меню видимо
-
> по крайней мере, в Win7
тажа фигня
-
moDefault Пардон, перестарался...
-
> если не получается через api поменять итем например SetMenuItemInfo значит чето не так делаешЯ в курсе. Если делал так не было б проблемы. Вот код с SetMenuItemInfo: for i := 0 to Length(Rec) - 1 do
begin
if not Rec[i].IsSM then
begin
Form1.pm.Items[MenuID].Parent.InsertItem(-1,
PWideChar(Rec[i].Name),
nil,
[]);
Form1.pm.RemoveSubMenu(Rec[i].Id);
end
else
begin
ZeroMemory(@MII, SizeOf(MII));
MII.cbSize := MenuStructSize;
MII.fMask := MIIM_ID;
MII.wID := Form1.pm.Items[Form1.pm.Count - 1].MenuId + 1;
SetMenuItemInfoW( Form1.pm.Items[MenuID].Parent.Handle,
i,
TRUE,
MII );
end;
-
Если я правильно понимаю, то: 1. Изменяться будет родитель Form1.pm.Items[MenuID].Parent.Handle 2. Третий параметр = true, значит второй - это позиция 3. wID поменял, максимальный+1. 4. Вызов SetMenuItemInfoW результат Успешно. Элемент не двигался
-
SetMenuItemInfo ничего не двигает :) она изменяет информацию о пункте меню,надпись,чеканутость и тд и зачем по позиции,делай по идентификатору(false)
-
> SetMenuItemInfo ничего не двигает :) Тада на кой она мне? Или я совсем уже запутался?.. Вы задачу поняли?
-
ну смотри ты сортируеш меню,пральна делаеш это удалением\вставкой,пральна при этом чета там не работает тогда замени удаление\вставку обменом данными самих итемов нафига их удалять и создавать новые когда можно обменяться инфой (swap)
-
...не забывая об обработчиках
-
MTsv DNСортировка по алфавиту. Остальное за Вами. program SortMenu;
uses
Windows, KOL;
var Menu: PMenu;
Form, Btn1, Btn2 : PControl;
procedure Sort(const Menu: hMenu);
var i: Integer; Count: Integer; IID: Integer;
MII: TMenuItemInfo; MIIS: array of TMenuitemInfo;
function CompareItems(const Data: Pointer; const e1,e2 : Dword) : Integer;
var MIIS: array of TMenuItemInfo;
begin
MIIS := Data;
Result := StrComp_NoCase(MIIS[e1].dwTypeData, MIIS[e2].dwTypeData);
end;
procedure SwapItems(const Data : Pointer; const e1,e2 : Dword);
var MIIS: array of TMenuItemInfo;
MII: TMenuItemInfo;
begin
MIIS := Data;
MII := MIIs[e1];
MIIs[e1] := MIIs[e2];
MIIs[e2] := MII;
end;
var Buff: Pointer;
begin
Count := GetMenuItemCount(Menu);
SetLength(MIIS, Count);
for i := 0 to Count - 1 do
begin
IID := GetMenuItemID(Menu, i);
if IID = -1 then
Sort(GetSubMenu(Menu, i));
FillChar(MII, SizeOf(MII), 0);
MII.cbSize := SizeOf(MII);
MII.fMask := MIIM_STRING;
if not GetMenuItemInfo(Menu, i, True, PMenuItemInfo(@MII)^) then
MsgOK(SysErrorMessage(getLastError));
Buff := AllocMem(MII.cch + 1);
MII.dwTypeData := Buff;
MII.cch := MII.cch + 1;
if not GetMenuItemInfo(Menu, i, True, PMenuItemInfo(@MII)^) then
MsgOK(SysErrorMessage(getLastError));
MIIS[i] := MII;
end;
SortData(MIIS, Count, @CompareItems, @SwapItems);
for i := 0 to Count - 1 do
begin
SetmenuItemInfo(Menu, i, True, PMenuItemInfo(@(MIIS[i]))^);
FReeMem(MIIs[i].dwTypeData);
end;
end;
procedure Btn2Click(Dummy, Sender: Pobj);
begin
Sort(Menu.Handle);
end;
procedure FormMouseUp(Dummy, Sender: PControl; var Mouse: TMouseEventData);
var
pt : TPoint;
begin
if Mouse.Button = mbRight then
begin
GetCursorPos(pt);
Menu.PopupEx(pt.X, pt.Y);
end;
end;
var a: PMenu;
begin
Form := newForm(nil, 'test');
Form.OnMouseUp := TOnMouse(MakeMethod(nil, @FormMouseUp));
NewMenu(Form, 0, [], nil);
Menu := newmenu(Form, 0, ['a','1', '2', '0','df'], nil);
Btn2 := NewButton(Form, 'Sort');
Btn2.OnClick := TOnEvent(MAkeMethod(nil, @Btn2Click));
Menu.Insert(-1, 'f-11', nil, []);
a := Menu.Insert(-1, 'D-11', nil, [moSubMenu]);
a.Insert(-1, '4444444', nil, []);
a := a.Insert(-1, '3333333', nil, []);
a.Insert(-1, 'BBBBBBB', nil, []);
a.Insert(-1, 'CCCCCCC', nil, []);
a.Insert(-1, 'AAAAAAA', nil, []);
Menu.Insert(-1, 'A-11', nil, []);
Menu.Insert(-1, 'k-11', nil, []);
Menu.Insert(-1, 'L-11', nil, []);
Menu.Insert(-1, 'Я-11', nil, []);
Run(Form);
end.
-
Спасибо. Буду разбираться. ...Только он не работает 8( После нажатия Sort, субменю из D-11 переходит в df... Буду смотреть где сбой...
-
Вроде решает: MII.fMask := MIIM_STRING or MIIM_SUBMENU; Однако второй раз уже не отсортировать 8(
-
> ...не забывая об обработчиках
зачем? один обработчик на все меню итемы различать по Tag тогда позиция итема не будет иметь значения,хоть обсортируйся
-
После добавления MIIM_SUBMENU ошибка при повторной сортировке вот в этом месте: Count := GetMenuItemCount(Menu); getLastError выдал "Неверный дескриптор меню"
-
Ну, судя по тому, что больше идей нету...походу действительно дескриптор "ломается"... Придется делать "через назад"...
-
Дмитрий К, Спасибо за код...
-
Вот так, кажется, работает: begin
Count := GetMenuItemCount(Menu);
SetLength(MIIS, Count);
for i := 0 to Count - 1 do
begin
IID := GetMenuItemID(Menu, i);
if IID = -1 then
Sort(GetSubMenu(Menu, i));
FillChar(MII, SizeOf(MII), 0);
MII.cbSize := SizeOf(MII);
if IID = -1 then
MII.fMask := MIIM_STRING or MIIM_SUBMENU
else
MII.fMask := MIIM_STRING;
if not GetMenuItemInfo(Menu, i, True, PMenuItemInfo(@MII)^) then
MsgOK(SysErrorMessage(getLastError));
Buff := AllocMem(MII.cch + 1);
MII.dwTypeData := Buff;
MII.cch := MII.cch + 1;
if not GetMenuItemInfo(Menu, i, True, PMenuItemInfo(@MII)^) then
MsgOK(SysErrorMessage(getLastError));
MIIS[i] := MII;
end;
SortData(MIIS, Count, @CompareItems, @SwapItems);
for i := 0 to Count - 1 do
begin
RemoveMenu(Menu, i, MF_BYPOSITION);
InsertMenuItem(Menu, i, True, PMenuItemInfo(@(MIIS[i]))^);
FReeMem(MIIs[i].dwTypeData);
end;
end;
-
На первый взгляд работает, тока у меня подключена директива DEBUG_MENU и при закрытии вылетают ошибки...при удалении меню... Завтра гляну, сегодня спать...
|