-
...не забывая об обработчиках
-
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 и при закрытии вылетают ошибки...при удалении меню... Завтра гляну, сегодня спать...
|