Вопрос как узнать на каком крестике делается разворот темы(именно нажатие на крест разворота) и как перенести туда подсветку на эту тему разворота?
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)