Конференция "KOL" » Разыскивается код... [Delphi, Windows]
 
  • Dy1 (04.12.09 21:12) [20]
    ...не забывая об обработчиках
  • Дмитрий К © (04.12.09 21:18) [21]
    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.

  • MTsv DN (04.12.09 21:26) [22]
    Спасибо. Буду разбираться. ...Только он не работает 8( После нажатия Sort, субменю из D-11 переходит в df... Буду смотреть где сбой...
  • MTsv DN (04.12.09 21:36) [23]
    Вроде решает:
    MII.fMask := MIIM_STRING or MIIM_SUBMENU;


    Однако второй раз уже не отсортировать 8(
  • robt (04.12.09 21:41) [24]

    > ...не забывая об обработчиках

    зачем?
    один обработчик на все меню
    итемы различать по Tag тогда позиция итема не будет иметь значения,хоть обсортируйся
  • MTsv DN (04.12.09 21:49) [25]
    После добавления MIIM_SUBMENU ошибка при повторной сортировке вот в этом месте:
    Count := GetMenuItemCount(Menu);


    getLastError выдал "Неверный дескриптор меню"
  • MTsv DN (04.12.09 22:24) [26]
    Ну, судя по тому, что больше идей нету...походу действительно дескриптор "ломается"... Придется делать "через назад"...
  • MTsv DN (04.12.09 22:24) [27]
    Дмитрий К,
    Спасибо за код...
  • Дмитрий К © (04.12.09 22:40) [28]
    Вот так, кажется, работает:
    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;

  • MTsv DN (04.12.09 23:12) [29]
    На первый взгляд работает, тока у меня подключена директива DEBUG_MENU и при закрытии вылетают ошибки...при удалении меню... Завтра гляну, сегодня спать...
 
Конференция "KOL" » Разыскивается код... [Delphi, Windows]
Есть новые Нет новых   [134431   +12][b:0][p:0.002]