![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Меню со стилем OfficeXP [Delphi, Windows]
shalex © (2005-10-07 14:19:00)Я перевел на KOL компонент для отрисовки меню со стилем OfficeXP с возможностью изменять цвет, шрифт... может кому-нибудь тоже пригодится:
http://kol.lighthost.ru/files/XPMenus.rar
Это мой первый опыт создания KOL компонента, поэтому обо всех ошибках сообщите мне на мыло. Предложения тоже приветствуются :)
shalex (2005-10-12 10:17:00) [21]
> ещё виш:
> http://personal.primorye.ru/speller/xpmenu.gif
При каких свойствах это получается?
SPeller (2005-10-12 04:43:00) [22]shalex © (11.10.05 23:27) [21]
нужно ли освобождать fFont после завершения работы?
Да. Как и любой объект, который на был добавлен в AutoFree другого.
SPeller (2005-10-12 04:42:00) [23]shalex © (11.10.05 23:27) [21]
вот если бы Владимир объявил функцию WndProcMenu публичной в KOL
Ой, я наверное, больше года назад впервые просил Владимира сделать несколько глобальных объявлений таких WndProc-ов. Но почему-то воз и ныне там.
shalex (2005-10-11 23:27:00) [24]Вышла версия 1.06 с исправленным багом.
Пришлось много кода перенести из KOL (вот если бы Владимир объявил функцию WndProcMenu публичной в KOL, то было бы меньше кода).
Это повлияло только на размер компонента, а на размер программы это не повлияет (если одновременно не использовать вместе со стандартным меню)
2ECM: Еще вопрос по распределению памяти: нужно ли освобождать fFont после завершения работы? или он автоматически освобождается?
MTsv DN (2005-10-11 19:41:00) [25]Так когда исправления увидим :)
С Уважением MTsv DN
shalex (2005-10-11 19:30:00) [26]
> Это баг (а может недостаточно глубокое понимание идеологии
> KOL?) Ваш... И достаточно сложно упрятанный...
Конечно, это из-за недостаточно глубокого понимания идеологии KOL, т.к. это был мой первый KOL компонент, да еще примерами для меня были Controlы, к которым меню не относится.
> можно убрать вызов NewMenu из NewXPMenu - вместо этого перенести
> "тело" функции NewMenu прямо в NewXPMenu
Большое спасибо за совет!
ECM (2005-10-11 17:21:00) [27]
> по адресу в котором на самом деле храниться буфер значений
> списка Items
Очепятка - на самом деле указатель на буфер...:)
ECM (2005-10-11 17:15:00) [28]
> Почему-то работает только с заменой системных файлов...
> Может кто-нибудь подскажет почему?
> При любом присвоении...ломается на функции TMenu.GetItems.
> Например: SetItemAccelerator вызывает TMenu.GetItems ->
> Result := nil. Ошибка!!!
> Не знаю мой это баг или в KOL
Решил вот посмотреть...:)
Это баг (а может недостаточно глубокое понимание идеологии KOL?) Ваш... И достаточно сложно упрятанный...:(
Я думаю это будет интересно и другим...
Все дело в том что у Вас класс TXPMenu является наследником KOL.TMenu,
а у него нет виртуального конструктора (это один из "недостатков :=) " KOL, который тем не менее позволяет уменьшить размер). Поэтому нельзя получить настоящее наследование при помощи такого типа создания класса:
Result := PXPMenu(NewMenu( AParent,MaxCmdReserve,Template,aOnMenuItem ));
На самом деле здесь привязывается VMT (это нестрашно так как у Вас нет виртуальных методов) и выделяется память (и это главный подвох!) под поля данных только базового класса - TMenu! Т.е. при вызове New компилятор не догадывается что необходимо зарезервировать место и для полей
FFont, FGutterColor,...FIsPopup которые появились в наследнике.
При обращении к этим полям компилятор берет смещение соответсвующее полю и отсчитывает память от начала выделенного под объект куска памяти.
Но при этом получается мы обращаемся к памяти уже за пределами выделенной области - а там уже находятся данные других объектов распределенных поздее!!!
Так получилось что
Result.FMinHeight := SetMinHeight(20);
Записывает данные по адресу в котором на самом деле храниться буфер значений списка Items(TList.fItems)!!! (Поэтому и падения GetItems см. выше)
Как исправить?
Для классов наследуемых от TControl можно вынести все дополнительные поля в отдельный вспомогательный объект (см статью http://bonanzas.rinet.ru/r_docs.htm"Создание визуальных компонентов для библиотеки KOL."). Но здесь это не подходит... т.к. у TMenu нет резервных полей в которых можно хранить ссылку на такой объект (разве что Tag ... но вдруг кто-то захочет им воспользоваться по назначению?)
ИМХО: можно убрать вызов NewMenu из NewXPMenu - вместо этого перенести "тело" функции NewMenu прямо в NewXPMenu. После этого строка
New(Result,Create) будет правильно распределять память...
З.Ы. а эффект с заменой системных файлов - это просто повезло там память распределяется другим механизмом и эффект затирания не проявился ...:)
shalex (2005-10-11 16:59:00) [29]Вышла версия 1.05:
[+] В MCK добавлены свойства ItemHeight и ItemWidth
[*] Свойства MinHeight и MinWidth переименованы, соответственно, в ItemHeight и ItemWidth
[*] "Задизабленный" итем не выделяется.
shalex (2005-10-11 15:44:00) [30]
> Так же, хотелось бы иметь свойство вроде ItemHeight, по
> умолчанию равное нулю. Если оно = нолю, то высота итемов
> вычисляется автоматически, иначе - высота задается значением
> этого свойства.
Такое свойство уже есть: MinHeight, в будущей версии я его добавлю в MCK, сейчас же им можно пользовать в runtime.
SPeller (2005-10-11 14:25:00) [31]У меня тоже pas-version.
ещё виш:
http://personal.primorye.ru/speller/xpmenu.gif
Чтобы нижняя полоска рамки не закрывалась выпадающим меню.
shalex (2005-10-11 14:17:00) [32]
> Баг (?) - при завершении программы, запущенной в Дельфи
> 6, прога вылетает в окошко CPU.
Не знаю мой это баг или в KOL, но такие ошибки у меня пропадали, когда при компиляции я ставил параметр PAS_VERSION
SPeller (2005-10-11 14:13:00) [33]Так же, хотелось бы иметь свойство вроде ItemHeight, по умолчанию равное нулю. Если оно = нолю, то высота итемов вычисляется автоматически, иначе - высота задается значением этого свойства.
SPeller (2005-10-11 14:05:00) [34]SPeller © (11.10.05 14:05) [10]
В ничего - вроде симпатично выглядит
Ничего - вроде симпатично выглядит )
SPeller (2005-10-11 14:05:00) [35]В ничего - вроде симпатично выглядит.
Баг (?) - при завершении программы, запущенной в Дельфи 6, прога вылетает в окошко CPU.
Пожелание - чтобы задизабленный итем не выделялся.
shalex (2005-10-11 10:22:00) [36]2MTsv DN: В Delphi 7 работает, просто Вы забыли заменить системные файлы, читайте readme внимательно. Да и здесь я уже об этом писал...
MTsv DN (2005-10-10 21:24:00) [37]2 shalex ©
Я протрейссил дальше...
При любом присвоении...ломается на функции TMenu.GetItems. Например: SetItemAccelerator вызывает TMenu.GetItems -> Result := nil. Ошибка!!!
С Уважением MTsv DN
shalex (2005-10-10 20:49:00) [38]Вышла версия 1.03:
1) Теперь шрифт и цвета можно менять в Design mode.
2) Предложение RA реализовано.
2MTsv DN: Буду ставить себе 7-ю версию Delphi и разбираться в чем проблема.
MTsv DN (2005-10-10 19:33:00) [39]С Delphi 7 не работает...
Ошибка при присвоении, в демке:
Result.XPMainMenu1.ItemBitmap[ 1 ] := LoadBmp( hInstance, 'FORM1_N3_BMP_BITMAP', Result.XPMainMenu1 );
А если убрать все картинки, то при присвоении Default'а:
Result.XPMainMenu1.Items[ 9 ].DefaultItem := TRUE;
С Уважением MTsv DN
RA (2005-10-10 16:39:00) [40]Очень хорошо! Но вот не ясно для чего сразу инитить BmpCheck? Т.к. вовсе не факт, что где-то в нашем меню будет использоваться Chek. Поэтому я предлогаю сделать примерно так:
1) в пр-ру InitBmp добавить строки
if BmpCheck<>nil then exit;
BmpCheck:= NewDIBBitmap(12,12,pf32bit);
(И передаваемый параметр не нужен)
2) секция initialization не нужна
3) finalization можно и не изменять, т.к. если даже BmpCheck не проинитился все равно BmpCheck.Free не вызовет ошибки. А можно и поменять на KOL.Free_and_nil(BmpCheck);
4) а в unit_X.inc уже добавлять InitBmp если где-то в меню используется chek.