![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Разыскивается код... [Delphi, Windows]
MTsv DN © (2009-12-02 16:08:00)Всем привет... Не знаю, будет ли продолжение данной темы, однако...
MTsv DN (2009-12-04 23:12:00) [1]На первый взгляд работает, тока у меня подключена директива DEBUG_MENU и при закрытии вылетают ошибки...при удалении меню... Завтра гляну, сегодня спать...
Дмитрий К (2009-12-04 22:40:00) [2]Вот так, кажется, работает:
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 (2009-12-04 22:24:00) [3]Дмитрий К,
Спасибо за код...
MTsv DN (2009-12-04 22:24:00) [4]Ну, судя по тому, что больше идей нету...походу действительно дескриптор "ломается"... Придется делать "через назад"...
MTsv DN (2009-12-04 21:49:00) [5]После добавления MIIM_SUBMENUошибка при повторной сортировке вот в этом месте:
Count := GetMenuItemCount(Menu);
getLastError выдал "Неверный дескриптор меню"
robt (2009-12-04 21:41:00) [6]
> ...не забывая об обработчиках
зачем?
один обработчик на все меню
итемы различать по Tag тогда позиция итема не будет иметь значения,хоть обсортируйся
MTsv DN (2009-12-04 21:36:00) [7]Вроде решает:
MII.fMask := MIIM_STRING or MIIM_SUBMENU;
Однако второй раз уже не отсортировать 8(
MTsv DN (2009-12-04 21:26:00) [8]Спасибо. Буду разбираться. ...Только он не работает 8( После нажатия Sort, субменю из D-11 переходит в df... Буду смотреть где сбой...
Дмитрий К (2009-12-04 21:18:00) [9]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.
Dy1 (2009-12-04 21:12:00) [10]...не забывая об обработчиках
robt (2009-12-04 20:08:00) [11]ну смотри ты сортируеш меню,пральна
делаеш это удалением\вставкой,пральна
при этом чета там не работает
тогда замени удаление\вставку обменом данными самих итемов
нафига их удалять и создавать новые когда можно обменяться инфой (swap)
MTsv DN (2009-12-04 19:50:00) [12]> SetMenuItemInfo ничего не двигает :)
Тада на кой она мне? Или я совсем уже запутался?.. Вы задачу поняли?
robt (2009-12-04 19:47:00) [13]SetMenuItemInfo ничего не двигает :)
она изменяет информацию о пункте меню,надпись,чеканутость и тд
и зачем по позиции,делай по идентификатору(false)
MTsv DN (2009-12-04 19:30:00) [14]Если я правильно понимаю, то:
1. Изменяться будет родитель Form1.pm.Items[MenuID].Parent.Handle
2. Третий параметр = true, значит второй - это позиция
3. wID поменял, максимальный+1.
4. Вызов SetMenuItemInfoW результат Успешно. Элемент не двигался
MTsv DN (2009-12-04 19:27:00) [15]> если не получается через 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 );
// Form1.pm.Items[MenuID].Parent.InsertSubMenu(Form1.pm.Items[Rec[i].ID], -1);
// RemoveMenu(Form1.pm.Items[MenuID].Parent.Handle, i, MF_BYPOSITION);
end;
MTsv DN (2009-12-04 19:13:00) [16]moDefault
Пардон, перестарался...
robt (2009-12-04 19:10:00) [17]
> по крайней мере, в Win7
тажа фигня
robt (2009-12-04 19:08:00) [18]LoadMenu грузит из ресурсов а LoadMenuIndirect создает из MenuTemplate который програмно создаеш
если не получается через api поменять итем например SetMenuItemInfo значит чето не так делаеш, тогда проще пересоздать полностью меню видимо
Дмитрий К (2009-12-04 19:04:00) [19]Пункт "по умолчанию", в меню может быть только один, поэтому moDefault там лишние и генерация не пашет, по крайней мере, в Win7. А сортировке проблема, если в подменю первый пункт тоже подменю.
MTsv DN (2009-12-04 19:01:00) [20]> f-11 и фсе :)
Весьма странно. ЕХЕшник в архиве работает, я ж его не с куста взял.