Вопрос как узнать на каком крестике делается разворот темы(именно нажатие на крест разворота) и как перенести туда подсветку на эту тему разворота?
TreeGadget()
Сообщений 1 страница 10 из 10
Поделиться214.11.2022 16:46:17
Дело в том что функция Getgadgetstate(),возвращает правильный индекс который можно использовать в GetGadgetItemText) для возвращения текста когда подсвечена строка,
но она остаётся не подсвечена когда клик по крестику разворота!=соответственно текст невозможно прочитать да и подсветка остаётся в другом месте.
Поделиться314.11.2022 21:42:45
Это не оптимальный пример, я подсмотрел в AutoIt3. Но я сделал просто перечисление всех пунктов, а их же может быть несколько тысяч. А в коде AutoIt3, там с помощью функций GetParentHandle проверяем есть ли родитель и если есть то делаем перечисление дочерних GetFirstChild + цикл с GetNextSibling, а если нет родителя то GetNextSibling для корня. То есть более экономично.
EnableExplicit #Tree = 0 Global htree Define i Procedure WinCallback(hWnd, uMsg, WParam, LParam) ; Protected *NMHDR.NMHDR Protected *NM_TREEVIEW.NM_TREEVIEW Protected i Select uMsg Case #WM_NOTIFY ; *NMHDR = LParam *NM_TREEVIEW = LParam Select *NM_TREEVIEW\hdr\hwndFrom Case htree Select *NM_TREEVIEW\hdr\code ; Case #NM_CLICK ; Debug 222 ; Debug *NM_TREEVIEW\itemNew\hItem Case #TVN_ITEMEXPANDED ; Debug *NM_TREEVIEW\itemNew\hItem For i = 0 To CountGadgetItems(#Tree) If *NM_TREEVIEW\itemNew\hItem = GadgetItemID(#Tree, i) ; Debug i Debug GetGadgetItemText(#Tree, i) EndIf Next ; Case #TVN_ITEMEXPANDING ; Debug 111 ; Debug *NM_TREEVIEW\itemNew\hItem EndSelect EndSelect EndSelect ProcedureReturn #PB_ProcessPureBasicEvents EndProcedure If OpenWindow(0, 0, 0, 280, 500, "Событие Expand", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) htree = TreeGadget(#Tree, 10, 10, 260, 480) For i = 0 To 10 AddGadgetItem(#Tree, -1, "обычный элемент " + Str(i), 0, 0) AddGadgetItem(#Tree, -1, "Узел " + Str(i), 0, 0) AddGadgetItem(#Tree, -1, "Sub-элемент 1", 0, 1) AddGadgetItem(#Tree, -1, "Sub-элемент 2", 0, 1) AddGadgetItem(#Tree, -1, "Sub-элемент 3", 0, 1) AddGadgetItem(#Tree, -1, "Sub-элемент 4", 0, 1) AddGadgetItem(#Tree, -1, "Файл " + Str(i), 0, 0) Next SetWindowCallback(@WinCallback()) Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow EndIf
Оптимизация, вместо поиска по дескриптору разворачивание пункта сопровождается его выбором и соответственно функция получения текста работает правильно.
EnableExplicit #Tree = 0 Global htree Define i Procedure WinCallback(hWnd, uMsg, WParam, LParam) ; Protected *NMHDR.NMHDR Protected *NM_TREEVIEW.NM_TREEVIEW Protected i Select uMsg Case #WM_NOTIFY ; *NMHDR = LParam *NM_TREEVIEW = LParam Select *NM_TREEVIEW\hdr\hwndFrom Case htree Select *NM_TREEVIEW\hdr\code ; Case #NM_CLICK ; Debug 222 ; Debug *NM_TREEVIEW\itemNew\hItem Case #TVN_ITEMEXPANDED ; Debug *NM_TREEVIEW\itemNew\hItem SendMessage_(htree, #TVM_SELECTITEM, #TVGN_CARET, *NM_TREEVIEW\itemNew\hItem) Debug GetGadgetText(#Tree) ; Debug SendMessage_(htree, #TVM_GETITEM, #TVGN_CARET, *NM_TREEVIEW\itemNew\hItem) ; For i = 0 To CountGadgetItems(#Tree) ; If *NM_TREEVIEW\itemNew\hItem = GadgetItemID(#Tree, i) ; ; Debug i ; Debug GetGadgetItemText(#Tree, i) ; EndIf ; Next ; Case #TVN_ITEMEXPANDING ; Debug 111 ; Debug *NM_TREEVIEW\itemNew\hItem EndSelect EndSelect EndSelect ProcedureReturn #PB_ProcessPureBasicEvents EndProcedure If OpenWindow(0, 0, 0, 280, 500, "Событие Expand", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) htree = TreeGadget(#Tree, 10, 10, 260, 480) For i = 0 To 10 AddGadgetItem(#Tree, -1, "обычный элемент " + Str(i), 0, 0) AddGadgetItem(#Tree, -1, "Узел " + Str(i), 0, 0) AddGadgetItem(#Tree, -1, "Sub-элемент 1", 0, 1) AddGadgetItem(#Tree, -1, "Sub-элемент 2", 0, 1) AddGadgetItem(#Tree, -1, "Sub-элемент 3", 0, 1) AddGadgetItem(#Tree, -1, "Sub-элемент 4", 0, 1) AddGadgetItem(#Tree, -1, "Файл " + Str(i), 0, 0) Next SetWindowCallback(@WinCallback()) Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow EndIf
Отредактировано AZJIO (14.11.2022 22:18:46)
Поделиться415.11.2022 07:49:43
Ну да с родителем бывает печалька,по идее в родителя он тоже должен слать сообщения
Только вот как я замечал нет функции на установку родителя.
Надо api попробовать что то вроде setwindowlong()
указать треегаджету родителя допустим окна windows и в нём посмотреть сообщения попробовать.
А в целом ,по логике я сделал проще,раз клик правой устанавливает подсветку значит в калбаке
на левый клик имитировал сначала клик правой
ну и взятие текста.
Отредактировано Sergeihik (15.11.2022 07:50:40)
Поделиться515.11.2022 18:25:02
Только вот как я замечал нет функции на установку родителя
TVGN_PARENT
Поделиться615.11.2022 21:10:11
Да норм вроде бы работает!
#Tree=99 Procedure WinCallback(hWnd, uMsg, WParam, LParam) Protected *NM_TREEVIEW.NM_TREEVIEW Select uMsg Case #WM_NOTIFY;сообщение с дочернего окна *NM_TREEVIEW = LParam Select *NM_TREEVIEW\hdr\idFrom Case #Tree Select *NM_TREEVIEW\hdr\code Case #TVN_ITEMEXPANDING;Уведомляет родительское окно элемента управления в виде дерева о том ;что список дочерних элементов родительского элемента будет развернут или свернут. Debug *NM_TREEVIEW\hdr\idFrom Debug *NM_TREEVIEW\hdr\hwndFrom SendMessage_(*NM_TREEVIEW\hdr\hwndFrom, #TVM_SELECTITEM, #TVGN_CARET, *NM_TREEVIEW\itemNew\hItem) Debug GetGadgetText(*NM_TREEVIEW\hdr\idFrom) Case #TVN_ITEMEXPANDED;это вроде бы когда все сразу разварачиваются? EndSelect EndSelect EndSelect ProcedureReturn #PB_ProcessPureBasicEvents EndProcedure If OpenWindow(0, 0, 0, 280, 500, "Событие Expand", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) TreeGadget(#Tree, 10, 10, 260, 480) For i = 0 To 10 AddGadgetItem(#Tree, -1, "обычный элемент " + Str(i), 0, 0) AddGadgetItem(#Tree, -1, "Узел " + Str(i), 0, 0) AddGadgetItem(#Tree, -1, "Sub-элемент 1", 0, 1) AddGadgetItem(#Tree, -1, "Sub-элемент 2", 0, 1) AddGadgetItem(#Tree, -1, "Sub-элемент 3", 0, 1) AddGadgetItem(#Tree, -1, "Sub-элемент 4", 0, 1) AddGadgetItem(#Tree, -1, "Файл " + Str(i), 0, 0) Next SetWindowCallback(@WinCallback()) Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow EndIf
Поделиться716.11.2022 01:42:09
TVN_ITEMEXPANDING - собирается развернуться или свернуться.
TVN_ITEMEXPANDED - событие после того как элемент уже развернут или свернут.
тут разница как WM_SIZE и WM_SIZING, одна работает в процессе изменения размера, другая когда изменение только что закончено и мышка отпущена.
ING - инговая форма, когда процесс происходит сейчас
ED - прошедшее время, событие уже произошло
Пример added - добавлен, adding - добавление
процесс разворачивания может занимать время, например при чтении диска если файлов в папке много как в System32, поэтому и разделяется на событие на до и после окончания, что-то можно сделать сразу, а что-то требует сначала показ всех пунктов иначе какой-то не обработается так как появился позже.
Отредактировано AZJIO (16.11.2022 02:05:38)
Поделиться801.12.2022 03:00:48
Ещё вопросик ,как я понял для сообщения #WM_NOTIFY устанавливается формат сообщения #NOTIFYFORMAT так вот как его установить в юникод что бы не был в ansi? а то как бы кракозябры...
Debug PeekS(*NM_TREEVIEW\itemOld\pszText,-1,#PB_Unicode) Debug PeekS(*NM_TREEVIEW\itemNew\pszText,-1,#PB_Ascii) For i=0 To 100 Debug PeekA(*NM_TREEVIEW\itemnew\pszText+i) Next
Поделиться901.12.2022 04:36:50
Sergeihik
Может проблема в том как он там появился? Как я понимаю текст ограничивается Null, значит он там может быть в любом формате.
Поделиться1001.12.2022 16:46:05
Да интересно стало,ведь в сообщение для чего то есть эти строки?
нашёл какой то древний исходник там типа в обработчике это
Case #WM_NOTIFYFORMAT ProcedureReturn TREEVIEW_NotifyFormat(*infoPtr,wParam,lParam);(HWND)wParam,
ну и прыгает сюда
Procedure.i TREEVIEW_NotifyFormat (*infoPtr.TREEVIEW_INFO,hwndFrom, nCommand.l) Protected format.i; ;TRACE("(hwndFrom=%p, nCommand=%d)\n", hwndFrom, nCommand); If (nCommand <> #NF_REQUERY) ProcedureReturn 0; EndIf format = SendMessage_(hwndFrom,#NOTIFYFORMAT,*infoPtr\hwnd, #NF_QUERY);(WPARAM)*infoPtr\hwnd ;TRACE("format=%d\n", format); ;/;* Invalid format procedureReturned by NF_QUERY defaults To ANSI;*/ If (format <> #NFR_ANSI And format <> #NFR_UNICODE) format = #NFR_ANSI; *infoPtr\bNtfUnicode = (format = #NFR_UNICODE); ProcedureReturn format; EndProcedure
Похоже на проверку ,вот и подумал наверное значит можно как то его устанавливать?
Вот что пишут
NOTIFYFORMAT = 0x0055,
Определяет, принимает ли окно структуры ANSI или Unicode в сообщении уведомления WM_NOTIFY. Сообщения WM_NOTIFYFORMAT отправляются из общего элемента управления в его родительское окно и из родительского окна в общий элемент управления.
PS: В сам гаджет устанавливает формат,правда при ansi не работает клик по кресту а вот с сообщением #WM_NOTIFY как установить формат?
#NFR_ANSI = 1 #NFR_UNICODE = 2 #NF_QUERY = 3 #NF_REQUERY = 4 ;Commctrl.h #CCM_FIRST = $2000 #CCM_SETUNICODEFORMAT = (#CCM_FIRST+5) #TVM_SETUNICODEFORMAT = #CCM_SETUNICODEFORMAT #CCM_GETUNICODEFORMAT = (#CCM_FIRST+6) #TVM_GETUNICODEFORMAT = #CCM_GETUNICODEFORMAT #WM_NOTIFYFORMAT;=85;$0055 ;Debug SendMessage_(GadgetID(#Tree),#TVM_GETUNICODEFORMAT,0,0) ;Debug SendMessage_(GadgetID(#Tree),#TVM_SETUNICODEFORMAT,#False,0);ansi ;Debug SendMessage_(GadgetID(#Tree),#TVM_GETUNICODEFORMAT,0,0) ;Debug SendMessage_(GadgetID(#Tree),#TVM_SETUNICODEFORMAT,#True,0);unicod ;Debug SendMessage_(GadgetID(#Tree),#TVM_GETUNICODEFORMAT,0,0)
Отредактировано Sergeihik (01.12.2022 22:24:13)