Итак, есть код на гитаб для примера
__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)