Я бы сделал так:
1) В первую очередь проверил, нельзя ли тоже самое реализовать не перекрывая WndProc, например с помощью TAppEvents.OnMessage.
2) Если нет, то:
Создал отдельный пакет. В нём сделал бы отдельный компонент, позволяющий организовать цепочку вызовов WinProc. Ну собственно, у вас в коде такой класс уже есть. T***(.UnpatchControl_. Если таких классов много, то имеет смысл сделать у них общего наследника. Или изменить класс T*** так, чтобы PatchControl делегировал вызов экземпляру TMyWndProcQueeHandler (прокси).
Класс бы выглядел примерно так:
type
TMyWndProcQueeHandler = class(TComponent)
private
FWndProcsList: array of TWndMethod; // или TList<TWndMethod>
public
// здесь присваиваем контролу MyWndProc в качестве WndProc
// а оригинальный добавлем в FWndProcsList
procedure PatchControl;
// здесь соответственно восстанавливаем оригинальный WndProc
procedure UnpatchControl;
// здесь вызываем WndProc-ы в нужном порядке. (начиная с последнего (кастомного) до 0-го (оригинального))
procedure MyWndProc(var Message: TMessage);
// тут просто добавляем aWndProc в список
procedure AddWndProc(const aWndProc: TWndProc);
// ну и конечно надо ещё сделать конструктор/деструктор. Опционально переопределить Notification, чтобы получать уведомления от освобожденных связанных компонентов.
// И добавить property LinkedControl с setter-ом.
end;
Для каждого WinControl-a в котором нужно что-то переопределять, создавать по экземпляру TMyWndProcQueeHandler.