It works fine if I get QueryDragDropTypes to return dragDrop_reorder only. Combining with dragDrop_external breaks internal reordering.
If possible, I'd like to get both working. I guess it means overriding some methods myself but I'm stuck. 
For completeness, I'm deriving from CListControlComplete and I have the actual reordering / inserting external items working fine, it's just the scroll I'm struggling with.
class QueueList : public CListControlComplete
{
public:
dragDropAccept_t DragDropAccept2(IDataObject* obj) final
{
dragDropAccept_t accept;
metadb_handle_list handles;
if (get_dd_handles(obj, handles))
{
accept.dwEFfect = DROPEFFECT_COPY;
accept.showDropMark = true;
}
return accept;
}
uint32_t QueryDragDropTypes() const final
{
return dragDrop_reorder | dragDrop_external;
}
void OnDrop(IDataObject* obj, CPoint pt) final
{
this->ScreenToClient(&pt);
const size_t idx = InsertIndexFromPoint(pt);
if (idx == SIZE_MAX) return;
// do stuff
}
void RequestReorder(const size_t* order, size_t count) final
{
// do stuff
}
};