Риторический вопрос: Ну вот зачем себя так ограничивать?
Ну тогда как варианты:
1) использовать TApplicationEvents.OnMessage и уже в нём думать, как и что разрулить
2) самому следить за тем, чтобы Unpatch всегда вызывался для всей цепочки в правильном порядке (обратном), чтобы предотвратить потерю того метода.
3) в процедурах кода Unpatch, уведомлять «перехватчиков» об удалении, чтобы те выполнили свой цикл UnPatch/Patch (но скорее всего будет ещё неудобнее чем вариант с новым пакетом)
p.s. я когда-то сам пытался разрулить похожую ситуацию. Только у меня вместо WndProc, куча объектов перехватывали подменяли один и тот же обработчик событий TApplication.OnMessage. А потом всё падало. В моём случае, всё оказалось проще — в VCL-е нашёлся готовый менеджер очереди.