Инвентаризация меню | |
---|---|
Яковлев Игорь Автор Сообщений: 9 Откуда: Кингисепп Дата регистрации: 20.10.2017 |
Для целей документирования приложения пытаюсь получить структуру меню главного окна. Но для пунктов POPUP меню получаю пустую строку:
*--- API для работы с меню Declare Integer GetMenu In WIN32API ; integer HWnd Declare Integer GetMenuItemInfo In WIN32API ; integer hMenu,; integer uItem,; integer fByPosition,; string @ MENUITEMINFO Declare Integer GetProcessHeap In WIN32API Declare Integer HeapAlloc In WIN32API ; integer iHeap, ; integer uFlags, ; integer dwBytes Declare Integer HeapFree In WIN32API ; integer iHeap, ; integer uFlags, ; integer hGlobal Declare Integer GetMenuItemCount In WIN32API Integer hMenu Declare Integer GetSubMenu In WIN32API ; integer hMenu,; integer nPos *--- API для работы с меню - дополнение Declare Integer GlobalAlloc In WIN32API ; integer uFlags, ; integer dwBytes Declare Integer GlobalFree In WIN32API ; integer hGlobal Declare Integer SendMessage In user32.Dll Integer, Integer, Integer, String @ _hWnd = _vfp.HWnd _hMenu = GetMenu(_hWnd) && Хэндл меню =mm_get_sub_menu(_hMenu,_hWnd) Procedure mm_get_sub_menu Lparameters _hMenu, _hWnd LOCAL _count_item, _i, cCaption *--- количество пунктов меню _count_item = GetMenuItemCount(_hMenu) If _count_item > 0 For _i=0 To _count_item - 1 cCaption = get_item_Caption(_hMenu ,_i, _hWnd) ? cCaption *--- проверка на субменю _hMenu_sub = GetSubMenu(_hMenu, _i) && дескриптор "выскакивающего" меню или подменю, активизированного пунктом меню. *--- Если пункт меню не активизирует "выскакивающее" меню или подменю, величина возвращаемого значения - ПУСТО (NULL) If !Isnull(_hMenu_sub) && If Vartype(_hMenu_sub) = 'N' And _hMenu_sub # 0 mm_get_sub_menu(_hMenu_sub, _hWnd) Endif Endif Endfor Endif Return Procedure get_item_Caption Lparameters hMenu ,_num_item, _hWnd *--- hMenu - дескриптор меню *--- _num_item - номер пункта *--- _hWnd - дескриптор окна, содержащего меню #Define MF_BYCOMMAND 0x00000000 #Define MF_BYPOSITION 0x00000040 #Define MF_STRING 0x00000000 #Define MFT_OWNERDRAW 0x00000100 #Define MFT_SEPARATOR 0x00000800 #Define MIIM_STRING 0x00000040 *--- Retrieves or sets the fType and dwTypeData members. MIIM_TYPE is replaced by MIIM_BITMAP, MIIM_FTYPE, and MIIM_STRING. #Define MIIM_TYPE 0x00000010 *--- fMask с этим значением возвращает значение fType *--- который нужно анализировать #Define MIIM_FTYPE 0x00000100 #Define LEN_MENU_CAPTION 254 *-- для второй вариант #Define GPTR 0x00000040 #Define WM_INITMENUPOPUP 0x0117 Local pCaption, MII, nCaptionLen, cCaption, hMenu _hMenu = hMenu If .T. *--- второй вариант *!* Структура MENUITEMINFO *!* cbSize As Long *!* fMask As Long *!* fType As Long *!* fState As Long *!* wID As Long *!* hSubMenu As Long *!* hbmpChecked As Long *!* hbmpUnchecked As Long *!* dwItemData As Long *!* dwTypeData As String - Это указатель *!* cch As Long *!* hbmpItem As Long *!* struct tagMENUITEMINFOA { *!* UINT cbSize; *!* UINT fMask; *!* UINT fType; *!* UINT fState; *!* UINT wID; *!* HMENU hSubMenu; *!* HBITMAP hbmpChecked; *!* HBITMAP hbmpUnchecked; *!* ULONG_PTR dwItemData; *!* LPSTR dwTypeData; *!* UINT cch; *!* HBITMAP hbmpItem; *!* } MENUITEMINFOA, *LPMENUITEMINFOA; Local cdwTypeData, nlendwTypeData, _nGlobaldwTypeData, MII, cbSize,; fMask,fType,fState, wID,hSubMenu,hbmpChecked,hbmpUnchecked, dwItemData,; dwTypeData, cch,hbmpItem, resMII cdwTypeData = Space(254) nlendwTypeData = Len(cdwTypeData ) _nGlobaldwTypeData = GlobalAlloc(GPTR,nlendwTypeData ) =Sys(2600, _nGlobaldwTypeData , nlendwTypeData, cdwTypeData ) *!* Чтобы получить элемент меню типа MFT_STRING, сначала найдите размер строки, установив член dwTypeData MENUITEMINFO равным NULL, *!* а затем вызовите GetMenuItemInfo. Значение cch+1 - это необходимый размер. *!* Затем выделите буфер такого размера, поместите указатель на буфер в dwTypeData, увеличьте cch на единицу, а затем снова вызовите GetMenuItemInfo, *!* чтобы заполнить буфер строкой. *** !В примерах берется размер с запасом 254 и не аналазируется первым вызовом. *!* !Если извлеченный элемент меню имеет какой-то другой тип, то GetMenuItemInfo устанавливает член dwTypeData в значение, *!* тип которого задается членом fTypefType, и устанавливает cch в 0. *MII - переменная, в которой формируем структуру MENUITEMINFO MII=Space(48) cbSize = 48 && размер структуры 12*4 *--- MIIM_TYPE is replaced by MIIM_BITMAP, MIIM_FTYPE, and MIIM_STRING. fMask = MIIM_TYPE && MIIM_STRING && Retrieves or sets the dwTypeData member fType = MF_STRING && MFT_STRING - 0x00000000L Отображает пункт меню с помощью текстовой строки. Элемент dwTypeData-это указатель на строку с нулевым окончанием, а элемент cch - это длина строки. MFT_STRING заменяется на MIIM_STRING fState =0 wID =0 hSubMenu =0 hbmpChecked =0 hbmpUnchecked =0 dwItemData =0 dwTypeData = _nGlobaldwTypeData cch = 254 hbmpItem =0 MII = BinToC(cbSize , '4RS') &&cbSIZE MII = MII+BinToC(fMask, '4RS' ) MII = MII+BinToC(fType , '4RS' ) MII = MII+BinToC(fState , '4RS' ) MII = MII+BinToC(wID , '4RS' ) MII = MII+BinToC(hSubMenu , '4RS' ) MII = MII+BinToC(hbmpChecked , '4RS' ) MII = MII+BinToC(hbmpUnchecked , '4RS' ) MII = MII+BinToC(dwItemData , '4RS' ) MII = MII+BinToC(dwTypeData , '4RS' ) MII = MII+BinToC(cch , '4RS' ) MII = MII+BinToC(hbmpItem , '4RS' ) *--- неудачная попытка *!* MN_GETHMENU = 0x01E1 *!* SendMessage(_hWnd, WM_INITMENUPOPUP, hMenu, BinToC(_num_item , '2RS')+ BinToC(0, '2RS')) resMII =GetMenuItemInfo(_hMenu ,_num_item ,MF_BYPOSITION ,@MII) If resMII #0 *--- извлечение результата cbSize =CToBin(Substr(MII,1,4),'4RS') fMask =CToBin(Substr(MII,5,4),'4RS') fType =CToBin(Substr(MII,9,4),'4RS') fState =CToBin(Substr(MII,13,4),'4RS') wID =CToBin(Substr(MII,17,4),'4RS') hSubMenu =CToBin(Substr(MII,21,4),'4RS') hbmpChecked =CToBin(Substr(MII,25,4),'4RS') hbmpUnchecked= CToBin(Substr(MII,29,4),'4RS') dwItemData =CToBin(Substr(MII,33,4),'4RS') nGlobaldwTypeData =Strconv( (Substr(MII,37,4)),6) cch =CToBin(Substr(MII,41,4),'4RS') hbmpItem =CToBin(Substr(MII,44,4),'4RS') nGlobaldwTypeData =Alltrim(Sys(2600, CToBin(Substr(MII,37,4),'4RS'), cch )) nCaptionLen = CToBin(Substr(MII,41,4),'4RS') cCaption = Sys( 2600, CToBin( Substr( MII, 37, 4 ), '4RS' ), nCaptionLen ) *--- конец извлечения результата If cch # 0 Return cCaption Else *--- cch = 0 - значит тип отличается от MIIM_STRING DO CASE CASE MFT_SEPARATOR = fType && cCaption = '---- Разделитель ----' CASE MFT_OWNERDRAW = fType && *!* Назначает ответственность за рисование элемента меню окну, которому принадлежит меню. *!* Окно получает сообщение WM_MEASUREITEM перед первым отображением меню, а также сообщение WM_DRAWITEM всякий раз, *!* когда необходимо обновить внешний вид элемента меню. *!* Если это значение указано, то элемент dwTypeData содержит определенное приложением значение. MII=Space(48) cbSize = 48 && размер структуры 12*4 *--- Retrieves the fType and dwTypeData members. MIIM_TYPE is replaced by MIIM_BITMAP, MIIM_FTYPE, and MIIM_STRING. fMask = MIIM_TYPE && MIIM_STRING && Retrieves or sets the dwTypeData member fType = MFT_OWNERDRAW && Назначает ответственность за рисование элемента меню окну, которому принадлежит меню. Окно получает сообщение WM_MEASUREITEM перед первым отображением меню, а также сообщение WM_DRAWITEM всякий раз, когда необходимо обновить внешний вид элемента меню. Если это значение указано, то элемент dwTypeData содержит определенное приложением значение. fState =0 wID =0 hSubMenu =0 hbmpChecked =0 hbmpUnchecked =0 dwItemData =0 dwTypeData = _nGlobaldwTypeData &&CHR(0) &&.null. && cch = 254 hbmpItem =0 MII = BinToC(cbSize , '4RS') &&cbSIZE MII = MII+BinToC(fMask, '4RS' ) MII = MII+BinToC(fType , '4RS' ) MII = MII+BinToC(fState , '4RS' ) MII = MII+BinToC(wID , '4RS' ) MII = MII+BinToC(hSubMenu , '4RS' ) MII = MII+BinToC(hbmpChecked , '4RS' ) MII = MII+BinToC(hbmpUnchecked , '4RS' ) MII = MII+BinToC(dwItemData , '4RS' ) MII = MII+BinToC(dwTypeData , '4RS' ) MII = MII+BinToC(cch , '4RS' ) MII = MII+BinToC(hbmpItem , '4RS' ) resMII =GetMenuItemInfo(_hMenu ,_num_item ,MF_BYPOSITION ,@MII) If resMII #0 cbSize =CToBin(Substr(MII,1,4),'4RS') fMask =CToBin(Substr(MII,5,4),'4RS') fType =CToBin(Substr(MII,9,4),'4RS') fState =CToBin(Substr(MII,13,4),'4RS') wID =CToBin(Substr(MII,17,4),'4RS') hSubMenu =CToBin(Substr(MII,21,4),'4RS') hbmpChecked =CToBin(Substr(MII,25,4),'4RS') hbmpUnchecked= CToBin(Substr(MII,29,4),'4RS') dwItemData =CToBin(Substr(MII,33,4),'4RS') nGlobaldwTypeData =Strconv( (Substr(MII,37,4)),6) cch =CToBin(Substr(MII,41,4),'4RS') hbmpItem =CToBin(Substr(MII,44,4),'4RS') nGlobaldwTypeData =Alltrim(Sys(2600, CToBin(Substr(MII,37,4),'4RS'), cch )) nCaptionLen = CToBin(Substr(MII,41,4),'4RS') cCaption = Sys( 2600, CToBin( Substr( MII, 37, 4 ), '4RS' ), nCaptionLen ) If cch # 0 Return cCaption Else Return 'Не определен' Endif Endif ENDCASE Endif Endif *--- освобождаю память =GlobalFree(_nGlobaldwTypeData) Else *--- тоже рабочий вариант - без анализа *--- выделение памяти внутри процесса pCaption = HeapAlloc(GetProcessHeap(),0, LEN_MENU_CAPTION ) MII = ; BINTOC( 48 , '4RS') + ; && cbSIZE BinToC( MIIM_STRING, '4RS' )+ ; && fMask Replicate( Chr(0), 28 ) + ; BinToC( pCaption, '4RS' ) + ; BinToC( LEN_MENU_CAPTION, '4RS' ) + ; && cch Replicate( Chr(0), 4 ) If GetMenuItemInfo(hMenu ,_num_item ,MF_BYPOSITION ,@MII) <> 0 nCaptionLen = CToBin(Substr(MII,41,4),'4RS') cCaption = Sys( 2600, CToBin( Substr( MII, 37, 4 ), '4RS' ), nCaptionLen ) Else cCaption = "<<error>>" Endif *--- освобождаю память =HeapFree( GetProcessHeap(), 0, pCaption ) Endif Return cCaption VFP меню POPUP создает в MFT_OWNERDRAW и не возвращает названия пунктов. Подскажите пожалуйста - Какими средствами получить структуру системного меню, желательно с содержанием иконок? |
Re: Инвентаризация меню | |
---|---|
po2 Сообщений: 2864 Откуда: Иркутск Дата регистрации: 22.12.2001 |
Я уж забыл все. Помнится, есть одна тонкость. Состоит в том, что позиций меню, до его активизации, считай нет. Только каркас. Проверьте, что вернет ваш код, если вызвать его из пользовательской функции помещенной в секцию skip любой из позиций popup.
|
Re: Инвентаризация меню | |
---|---|
Яковлев Игорь Автор Сообщений: 9 Откуда: Кингисепп Дата регистрации: 20.10.2017 |
Заменив _hWnd на хэндл главного окна приложения запустил код из секции SKIP FOR команды DEFINE BAR. Результат тот же - наименования пунктов линейки главного меню возвращаются, наименования пунктов POPUP меню нет.
|
Re: Инвентаризация меню | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Зачем такие мучения? Зачем АПИ? Нет исходного кода проекта, где это меню описано?
И, опять же, безотносительно к первому - меню штука совершенно динамическая - там и пункты и подменю могут добавляться/убираться сколь угодно гибко. Открыл форму - добавились пункты для работы с ней, закрыл - пропали. Вполне типичное поведение. Не думаю что "документирование приложения" должно опираться на пункты меню. ------------------ WBR, Igor |
Re: Инвентаризация меню | |
---|---|
Яковлев Игорь Автор Сообщений: 9 Откуда: Кингисепп Дата регистрации: 20.10.2017 |
Абсолютно объективное, профессиональное рассуждение. Спасибо, что обратили внимание. «Мучения» – в моем случае это точное и емкое определение. Для чего мне они нужны? Да конечно не в получении результата, выраженного в виде текста с картинками в HTL формате. Тактическое решение, не претендующее на оригинальность, при наличии времени «заглянуть за горизонт своих познаний». Какие Win Msg необходимо связывать?
|
Re: Инвентаризация меню | |
---|---|
Crispy Сообщений: 18571 Дата регистрации: 16.05.2005 |
Добавлю немного для пояснения сказанного выше. Просто в фокспро меню - вещь несколько специфическая. В широком смсле слова - это вообще не виндовский объект. Для его создания не используются никакие библиотеки, как это обычно делается где-то в других средах. А свои собственные, встроенные средства. Создается же оно при этом в программе через определенный набор команд, выполняемых в рантайме. Т.е. отсюда видимо и нестоятельность попыток его "считывания" как стандартного виндовского объекта. Как выше уже и было упомянуто, если есть рабочие коды запускаемой программы, можно например попытаться автоматизировать выборку его создания из них. Но только, если оно не создается там динамически, иначе придется анализировать код его создания-изменения уже вручную. ------------------ В действительности все иначе, чем на самом деле. (Антуан де Сент-Экзюпери) |
Re: Инвентаризация меню | |
---|---|
Яковлев Игорь Автор Сообщений: 9 Откуда: Кингисепп Дата регистрации: 20.10.2017 |
Извинюсь заранее, если настойчивость в достижении понимания предмета вопроса выглядит как спор неразумного пятиклассника с учителем математики.
В результате работы приведенного кода очевидно, что «в фокспро меню - вещь несколько специфическая.» А именно: fType = MFT_OWNERDRAW «Assigns responsibility for drawing the menu item to the window that owns the menu. The window receives a WM_MEASUREITEM message before the menu is displayed for the first time, and a WM_DRAWITEM message whenever the appearance of the menu item must be updated. If this value is specified, the dwTypeData member contains an application-defined value.» Назначает ответственность за рисование элемента меню окну, которому принадлежит меню. Окно получает сообщение WM_MEASUREITEM перед первым отображением меню, а также сообщение WM_DRAWITEM всякий раз, когда необходимо обновить внешний вид элемента меню. Если это значение указано, то элемент dwTypeData содержит определенное приложением значение. Но VFP не позаботился определить это значение или я его неправильно определяю. Экспертное мнение могло бы прояснить «смутные сомнения». Но даже если текстового вида извлечь невозможно, то «нарисованный» пункт меню потенциально извлекаем. |
Re: Инвентаризация меню | |
---|---|
ssa Сообщений: 13008 Откуда: Москва Дата регистрации: 23.03.2005 |
А вот и нет. Наоборот, это чисто виндовый объект, к тому же как бы "системный", создаваемый самой виндой. Цитата:Угу, непосредственное обращение к API. Цитата:Не так. Несостоятельность попыток читать его как фоксовый объект. А это таки объект операционной системы. И читать его надо из ресурсов операционной системы. Ибо куда-то туда она его пихает по командам от прикладной проги. ------------------ Лень - это неосознанная мудрость. |
Re: Инвентаризация меню | |
---|---|
lulgu Сообщений: 1838 Дата регистрации: 30.11.2016 |
Красиво сказано. Только не похож ваш копипаст на горизонт. |
Re: Инвентаризация меню | |
---|---|
Яковлев Игорь Автор Сообщений: 9 Откуда: Кингисепп Дата регистрации: 20.10.2017 |
Свои горизонты я открываю на этом форум. копипаст по мотиву автора beobachter |
Re: Инвентаризация меню | |
---|---|
lulgu Сообщений: 1838 Дата регистрации: 30.11.2016 |
Сейчас не 2006 год. Вынесите свои Api-функции и структуры в отдельные обертки, и с каждой разбирайтесь отдельно. Если хотите расширить свои познания, возьмите их описания в MSDN, там все есть. |
Re: Инвентаризация меню | |
---|---|
Crispy Сообщений: 18571 Дата регистрации: 16.05.2005 |
Может конечно и так. Специально в эту тему не углублялся, не было нужды. Хотя у меня всегда, когда доводилось иметь дело с фоксовским меню, складывалось впечатление, что оно какое-то "не настоящее". Как и форма, и грид, и еще ряд фоксовских контролов. Но те хотя бы визуальны. Меню же и близко не визуально на этапе разработке. Т.е. это всего лишь тупо набор команд. Причем почти не изменившихся со времен DOS-а. ------------------ В действительности все иначе, чем на самом деле. (Антуан де Сент-Экзюпери) |
Re: Инвентаризация меню | |
---|---|
Яковлев Игорь Автор Сообщений: 9 Откуда: Кингисепп Дата регистрации: 20.10.2017 |
Это как-то отразилось на VFP 9.0? Освежите в свой памяти дату релиза Api-функции и структуры в отдельных обертках. См. правила конференции: "Старайтесь создавать репро, которое спокойно запускается из .PRG файла без изменений" Без комментария ... Копипаст содержит выдержки из MSDN. Вы вероятно не прочитали Исправлено 1 раз(а). Последнее : Яковлев Игорь, 17.06.20 19:37 |
Re: Инвентаризация меню | |
---|---|
PaulWist Сообщений: 14625 Дата регистрации: 01.04.2004 |
2Яковлев Игорь
Не надо дальше ;) ------------------ Есть многое на свете, друг Горацио... Что и не снилось нашим мудрецам. (В.Шекспир Гамлет) |
Re: Инвентаризация меню | |
---|---|
lulgu Сообщений: 1838 Дата регистрации: 30.11.2016 |
+ |
Re: Инвентаризация меню | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Не думаю что кто либо из тут присутствующих занимался декомпиляцией кода собственно VFP для глубокого понимания как же именно он обрабатывает команды DEFINE PAD/BAR/MENU, ON [SELECTION], ACTIVATE MENU и всё прочее Это попросту не нужно никому и никогда. В фоксе есть все команды необходимые для управления меню и есть некоторый набор функции для "получения его структуры" - всякие CNTBAR()/PRMBAR()/GETBAR() Но т.к. эти возможности не симметричны (не всё что можно задать/создать в меню можно потом прочитать) то иногда в программах используют те или иные объектные или ещё какие-то (на основе массивов, или таблиц с метаданными) обёртки - чтобы иметь возможность во время исполнения программы как поменять что-либо в системе меню (добавить/убрать/спрятать пункт, поменять надпись или картинку) так и "прочитать структуру" - т.е. определить какие пункты и подменю активны, какие у них картинки, надписи, условия пропуска и т.п. И ни одно из этих решений не спускается до уровня АПИ функций - просто потому что это не нужно В фоксе есть и "классическое" досовское меню - при том управляемое/создаваемое теми же самыми командами. Так что далеко не всегда меню в фоксе это "виндовое меню" (хотя использовать этот унаследованный ужас FPD-BAR меню в здравом уме вряд ли кто-то будет). Не знаю про какие именно "ресурсы ОС" ты тут написал, фоксовое меню никогда не было статическим, как во многих сишных программах, где оно хранится как "ресурс" в специальной секции exe файла... Но в общем-то АПИ функции GetMenu и т.д. и позволяют получить доступ к тому "виндовому меню" которое фокс делает на основе фоксовых команд управления меню. Но т.к. подменю у фокса "саморисованные", то как таковых их по простому не вынуть - с чем и столкнулся автор темы. ------------------ WBR, Igor |
Re: Инвентаризация меню | |
---|---|
lulgu Сообщений: 1838 Дата регистрации: 30.11.2016 |
Интересно, кроме ссылки на ТС, как вы еще можете подтвердить это утверждение? |
Re: Инвентаризация меню | |
---|---|
lulgu Сообщений: 1838 Дата регистрации: 30.11.2016 |
ТС в рамках своей задачи получил ответ еще в первом же совете (второй пост сверху) и в принципе, тему на этом можно было и закрывать. (Признаюсь, я не сразу обратил на него внимание). ИК это важное замечание проигнорировал и начал привычно выдумывать "саморисованную" теорию. Хотя кроме GetMenu() есть еще функции для работы с меню. И, конечно, практическая ценность тематики довольно специфична. Исправлено 2 раз(а). Последнее : lulgu, 19.06.20 12:21 |
Re: Инвентаризация меню | |
---|---|
Яковлев Игорь Автор Сообщений: 9 Откуда: Кингисепп Дата регистрации: 20.10.2017 |
Встав на твердые основания MSDN появилось ощущение похожее на понимание. Огромная благодарность всем, принявших участие в обсуждении.
*--- API для работы с меню
Declare Integer GetMenu In WIN32API ;
integer HWnd
Declare Integer GetMenuItemInfo In WIN32API ;
integer hMenu,;
integer uItem,;
integer fByPosition,;
string @ MENUITEMINFO
Declare Integer GetProcessHeap In WIN32API
Declare Integer HeapAlloc In WIN32API ;
integer iHeap, ;
integer uFlags, ;
integer dwBytes
Declare Integer HeapFree In WIN32API ;
integer iHeap, ;
integer uFlags, ;
integer hGlobal
Declare Integer GetMenuItemCount In WIN32API Integer hMenu
Declare Integer GetSubMenu In WIN32API ;
integer hMenu,;
integer nPos
_hWnd = _vfp.HWnd
_hMenu = GetMenu(_hWnd) && Хэндл меню
=mm_get_sub_menu(_hMenu,_hWnd)
Procedure mm_get_sub_menu
Lparameters _hMenu, _hWnd
LOCAL _count_item, _i, cCaption
*--- количество пунктов меню
_count_item = GetMenuItemCount(_hMenu)
If _count_item > 0
For _i=0 To _count_item - 1
cCaption = get_item_Caption(_hMenu ,_i, _hWnd)
? cCaption
*--- проверка на субменю
_hMenu_sub = GetSubMenu(_hMenu, _i) && дескриптор "выскакивающего" меню или подменю, активизированного пунктом меню.
*--- Если пункт меню не активизирует "выскакивающее" меню или подменю, величина возвращаемого значения - ПУСТО (NULL)
If !Isnull(_hMenu_sub) &&
If Vartype(_hMenu_sub) = 'N' And _hMenu_sub # 0
mm_get_sub_menu(_hMenu_sub, _hWnd)
Endif
Endif
Endfor
Endif
Return
Procedure get_item_Caption
Lparameters hMenu ,_num_item, _hWnd
*--- hMenu - дескриптор меню
*--- _num_item - номер пункта
*--- _hWnd - дескриптор окна, содержащего меню
#Define MF_BYCOMMAND 0x00000000
#Define MF_BYPOSITION 0x00000040
#Define MF_STRING 0x00000000
#Define MFT_OWNERDRAW 0x00000100
#Define MFT_SEPARATOR 0x00000800
#Define MIIM_STRING 0x00000040
*--- Retrieves or sets the fType and dwTypeData members. MIIM_TYPE is replaced by MIIM_BITMAP, MIIM_FTYPE, and MIIM_STRING.
#Define MIIM_TYPE 0x00000010
#Define MIIM_FTYPE 0x00000100 && Retrieves or sets the fType member.
#Define MIIM_DATA 0x00000020
*--- fMask с этим значением возвращает значение fType
*--- который нужно анализировать
#Define MIIM_FTYPE 0x00000100
#Define LEN_MENU_CAPTION 254
*-- для второй вариант
#Define GPTR 0x00000040
#Define WM_INITMENUPOPUP 0x0117
Local pCaption, MII, nCaptionLen, cCaption, hMenu
_hMenu = hMenu
If .T.
Local cdwTypeData, nlendwTypeData, _nGlobaldwTypeData, MII, cbSize,;
fMask,fType,fState, wID,hSubMenu,hbmpChecked,hbmpUnchecked, dwItemData,;
dwTypeData, cch,hbmpItem, resMII
cdwTypeData = Space(254)
nlendwTypeData = Len(cdwTypeData )
_nGlobaldwTypeData = HeapAlloc(GetProcessHeap(),0, LEN_MENU_CAPTION ) &&GlobalAlloc(GPTR,nlendwTypeData )
=Sys(2600, _nGlobaldwTypeData , nlendwTypeData, cdwTypeData )
MII=Space(48)
cbSize = 48 && размер структуры 12*4
*--- MIIM_TYPE is replaced by MIIM_BITMAP, MIIM_FTYPE, and MIIM_STRING.
fMask = MIIM_TYPE && MIIM_STRING && Retrieves or sets the dwTypeData member
fType = MF_STRING && MFT_STRING - 0x00000000L Отображает пункт меню с помощью текстовой строки. Элемент dwTypeData-это указатель на строку с нулевым окончанием, а элемент cch - это длина строки. MFT_STRING заменяется на MIIM_STRING
fState =0
wID =0
hSubMenu =0
hbmpChecked =0
hbmpUnchecked =0
dwItemData = 0
dwTypeData = _nGlobaldwTypeData
cch = 254
hbmpItem =0
MII = BinToC(cbSize , '4RS') &&cbSIZE
MII = MII+BinToC(fMask, '4RS' )
MII = MII+BinToC(fType , '4RS' )
MII = MII+BinToC(fState , '4RS' )
MII = MII+BinToC(wID , '4RS' )
MII = MII+BinToC(hSubMenu , '4RS' )
MII = MII+BinToC(hbmpChecked , '4RS' )
MII = MII+BinToC(hbmpUnchecked , '4RS' )
MII = MII+BinToC(dwItemData , '4RS' )
MII = MII+BinToC(dwTypeData , '4RS' )
MII = MII+BinToC(cch , '4RS' )
MII = MII+BinToC(hbmpItem , '4RS' )
resMII =GetMenuItemInfo(_hMenu ,_num_item ,MF_BYPOSITION ,@MII)
If resMII #0
*--- извлечение результата
cbSize =CToBin(Substr(MII,1,4),'4RS')
fMask =CToBin(Substr(MII,5,4),'4RS')
fType =CToBin(Substr(MII,9,4),'4RS')
fState =CToBin(Substr(MII,13,4),'4RS')
wID =CToBin(Substr(MII,17,4),'4RS')
hSubMenu =CToBin(Substr(MII,21,4),'4RS')
hbmpChecked =CToBin(Substr(MII,25,4),'4RS')
hbmpUnchecked= CToBin(Substr(MII,29,4),'4RS')
dwItemData =CToBin(Substr(MII,33,4),'4RS')
nGlobaldwTypeData =Strconv( (Substr(MII,37,4)),6)
cch =CToBin(Substr(MII,41,4),'4RS')
hbmpItem =CToBin(Substr(MII,44,4),'4RS')
nGlobaldwTypeData =Alltrim(Sys(2600, CToBin(Substr(MII,37,4),'4RS'), cch ))
nCaptionLen = CToBin(Substr(MII,41,4),'4RS')
cCaption = Sys( 2600, CToBin( Substr( MII, 37, 4 ), '4RS' ), nCaptionLen )
*--- конец извлечения результата
If cch # 0
Return cCaption
Else
DO CASE
CASE MFT_SEPARATOR = fType &&
cCaption = '---- Разделитель ----'
CASE MFT_OWNERDRAW = fType &&
*!* Назначает ответственность за рисование элемента меню окну, которому принадлежит меню.
*!* Окно получает сообщение WM_MEASUREITEM перед первым отображением меню, а также сообщение WM_DRAWITEM всякий раз,
*!* когда необходимо обновить внешний вид элемента меню.
*!* Если это значение указано, то элемент dwTypeData содержит определенное приложением значение.
MII=Space(48)
cbSize = 48 && размер структуры 12*4
fMask = MIIM_DATA
fType = 0 &&MF_STRING
fState =0
wID =0
hSubMenu =0
hbmpChecked =0
hbmpUnchecked =0
dwItemData = 0
dwTypeData = _nGlobaldwTypeData
cch = 254
hbmpItem =0
MII = BinToC(cbSize , '4RS') &&cbSIZE
MII = MII+BinToC(fMask, '4RS' )
MII = MII+BinToC(fType , '4RS' )
MII = MII+BinToC(fState , '4RS' )
MII = MII+BinToC(wID , '4RS' )
MII = MII+BinToC(hSubMenu , '4RS' )
MII = MII+BinToC(hbmpChecked , '4RS' )
MII = MII+BinToC(hbmpUnchecked , '4RS' )
MII = MII+BinToC(dwItemData , '4RS' )
MII = MII+BinToC(dwTypeData , '4RS' )
MII = MII+BinToC(cch , '4RS' )
MII = MII+BinToC(hbmpItem , '4RS' )
resMII =GetMenuItemInfo(_hMenu ,_num_item ,MF_BYPOSITION ,@MII)
If resMII #0
cbSize =CToBin(Substr(MII,1,4),'4RS')
fMask =CToBin(Substr(MII,5,4),'4RS')
fType =CToBin(Substr(MII,9,4),'4RS')
fState =CToBin(Substr(MII,13,4),'4RS')
wID =CToBin(Substr(MII,17,4),'4RS')
hSubMenu =CToBin(Substr(MII,21,4),'4RS')
hbmpChecked =CToBin(Substr(MII,25,4),'4RS')
hbmpUnchecked= CToBin(Substr(MII,29,4),'4RS')
dwItemData =CToBin(Substr(MII,33,4),'4RS')
nGlobaldwTypeData =Strconv( (Substr(MII,37,4)),6)
cch =CToBin(Substr(MII,41,4),'4RS')
hbmpItem =CToBin(Substr(MII,44,4),'4RS')
nGlobaldwTypeData =Alltrim(Sys(2600, CToBin(Substr(MII,37,4),'4RS'), cch ))
nCaptionLen = CToBin(Substr(MII,41,4),'4RS')
cCaption = Sys( 2600, CToBin( Substr( MII, 37, 4 ), '4RS' ), nCaptionLen )
IF !EMPTY(dwItemData) && ?
_cCaption = STRCONV(SUBSTR(Sys(2600, dwItemData, 80),15),6)
_len = LEN(_cCaption)
IF AT(CHR(4),_cCaption) > 0
_len = MIN(_len,AT(CHR(4),_cCaption))
ENDIF
IF AT(CHR(63),_cCaption) > 0
_len = MIN(_len,AT(CHR(63),_cCaption))
ENDIF
cCaption = SUBSTR(_cCaption,1,_len-1)
_len = _len
Else
Return 'Не определен'
Endif
Endif
ENDCASE
Endif
Endif
*--- освобождаю память
=HeapFree( GetProcessHeap(), 0, _nGlobaldwTypeData )
Endif
Return cCaption
[code][/code] |
© 2000-2024 Fox Club  |