Но как обнаружилось, через TerminateThread или Exit Sub/Funtion нормально завершить поток нельзя
Использовать TerminateThread действительно нельзя. Однако просто выйти из потоковой процедуры можно, поток умрет, и без всяких глюков. Еще, если вдруг не знаешь, компилировать проект нужно в pcode.
Есть три варианта дальнейших действий.
1. Перепроектировать поток так, чтобы он сам завершался, выполнив свою задачу.
2. Использовать в потоке WaitForSingleObject.
3. Передать в поток ссылку на класс со свойством типа ToStop as Boolean, в потоке его проверять, а извне поставить True, когда надо его вырубить.
У каждого способа есть свои недостатки. В первом случае не всегда представляется возможным переделать поток. Во втором, если пауза поставлена подлиннее, WaitForSingleObject подтормаживает поток, а если поменьше, срабатывает не всегда с первого раза. В третьем теоретически могут возникнуть непредсказуемые глюки, связанные с ошибками доступа к памяти. Однажды мне удалось сделать стабильный поток третьим способом, но, к сожалению, исходники потерялись, в любом случае рекомендую его.
А dll, не dll - абсолютно не важно.
Лучший способ понять что-то самому — объяснить это другому.