Итак, есть код на гитаб для примера
__declspec(dllexport) int CALLBACK test5(const HWND hWnd, TOOL_EXEC_INFO *tei, TOOL_DATA_INFO *tdi)
{
DATA_INFO *di;
TCHAR buf[BUF_SIZE];
// ビューアの選択アイテム取得
// Get selected items in the viewer
if ((di = (DATA_INFO *)SendMessage(hWnd, WM_VIEWER_GET_SELECTION, 0, 0)) != NULL) {
// 選択アイテムのタイトルを表示
// Show title of selected item
SendMessage(hWnd, WM_ITEM_GET_TITLE, (WPARAM)buf, (LPARAM)di);
MessageBox(hWnd, buf, TEXT("sel item"), 0);
}
// 履歴の取得
// Get history
if ((di = (DATA_INFO *)SendMessage(hWnd, WM_HISTORY_GET_ROOT, 0, 0)) == NULL) {
return TOOL_SUCCEED;
}
for (di = di->child; di != NULL; di = di->next) {
// アイテムのタイトルを取得
// Get the title of the item
SendMessage(hWnd, WM_ITEM_GET_TITLE, (WPARAM)buf, (LPARAM)di);
if (MessageBox(hWnd, buf, TEXT("title"), MB_OKCANCEL) == IDCANCEL) {
// ビューアでアイテムを選択状態にする
// Select an item in the viewer
SendMessage(hWnd, WM_VIEWER_SELECT_ITEM, 0, (LPARAM)di);
break;
}
}
return TOOL_SUCCEED;
}на данный момент у меня процедура
ProcedureDLL Conv(hWnd, *tei.TOOL_EXEC_INFO, *tdi.TOOL_DATA_INFO)
Protected *di.DATA_INFO
Protected *history_di.DATA_INFO
Protected buf.s = Space(256)
If *tdi = 0
ProcedureReturn #TOOL_SUCCEED
EndIf
; di = *tdi\di
If *tdi\di\struct_size = 0 Or (*tdi\di\type <> #TYPE_ITEM And *tdi\di\type <> #TYPE_DATA)
ProcedureReturn #TOOL_ERROR
EndIf
; до этой точки всё работает
*di = *di\child
While *di <> 0
*di = *di\next
; получить заголовок
SendMessage_(hWnd, #WM_ITEM_GET_TITLE, buf, *di)
OutputDebugString_(buf)
; If MessageRequester("Далее?", buf, #PB_MessageRequester_YesNo) = #PB_MessageRequester_No
; ; выберите элемент истории
; SendMessage_(hWnd, #WM_VIEWER_SELECT_ITEM, 0, *di);
; EndIf
Wend
ProcedureReturn #TOOL_SUCCEED
EndProcedureНемного абсурда код di = di->child, итак di это объявленная структура, в PureBasic она с указателем *di.DATA_INFO, так как только так можно выполнить приравнивание *di = *di\child (аналогично при передачи в функцию), но *di\child это часть структуры *tdi.TOOL_DATA_INFO в которой есть поле *di.DATA_INFO при чём в ней есть элемент *child.DATA_INFO. Я не понимаю как присвоить *di не всю структуру *tdi, а только его часть. В итоге этот код приводит к падению CLCL. Далее в цикле я проверяю что присвоенная структура не равна нулю *di <> 0 внутри цикла она присваивается через *di = *di\next. В Си коде это в одной строке for (di = di->child; di != NULL; di = di->next) { то есть присваивание при запуске цикла di = di->child далее условие что di != NULL не равен нулю и далее di = di->next назначается следующая структура (следующего элемента истории). Это как List у каждого элемента структуры есть указатель на следующий элемент. Чтобы не проверять далее я закоментировал строки и просто получаю пункт в буфер buf, тут легко из вида SendMessage(hWnd, WM_ITEM_GET_TITLE, (WPARAM)buf, (LPARAM)di); где di понятный следующуй элемент, строка buf объявленная ранее как TCHAR buf[BUF_SIZE]; и вывожу строку в отладчик OutputDebugString_(buf), но в отладчик ничего не приходит, а CLCL падает.
Победил, вот рабочий цикл. Проблема была в структуре, BOOL не ".b", а ".i" из-за чего смещение поля next было неверное.
; *di = SendMessage_(hWnd, #WM_HISTORY_GET_ROOT, 0, 0)
*di = *tdi\di
While *di
; получить заголовок
SendMessage_(hWnd, #WM_ITEM_GET_TITLE, buf, *di)
OutputDebugString_(buf)
*di = *di\next
If MessageRequester("Далее?", buf, #PB_MessageRequester_YesNo) = #PB_MessageRequester_Yes
; выберите элемент истории
SendMessage_(hWnd, #WM_VIEWER_SELECT_ITEM, 0, *di);
Else
Break
EndIf
WendОтредактировано AZJIO (21.08.2025 04:18:38)