If MVP vs. MVC is your main problem, you can probably choose freely.
There are three factors affecting that decision: your previous experience, support of your framework/libraries, and which fits the existing code base better.
In my epxerience both patterns fit on C++ legacy applications like cat puke on a wedding cake. Your main challenges will be:
- Not breaking anything. Heck, it's probably not breaking everything
- Noticing that you are actually moving forward
- Doing that with small changes that don't require a three month rewrite of some components
The remainder is very generic to dealing with legacy applications, not related to the specifics of your question. I'll leave it here since you also have a generic part.
Rewrite vs. Refactor You already stated your decision, so I just put forward the pro rewrite arguments to consider: if you have a clear spec and understand how current users use this app, a rewrite might be faster and cheaper when 30% or more of the code need changes. (This doesn't mean "rewrite everything", this might also mean cutting back the application to logic-only, then planting a new presentation layer on top of it)
Assuming you go for refactor:
Define your goals Why do you need to refactor the app at all? Good reasons could be a lot of new features to be implemented, presentation layer needs to be replaced, or to buggy to remain sane. From that, decide what needs to change, and what can stay the way it is.
You have already picked your goal: MV*. I just want you to think about the benefits for the client and the code owner in the long run.
Read the code. No, really, take your time to get used to the code base. Step through it with the debugger. Try to understand the things involved. Take notes on improvements you think you should make.
Create tests - mostly regression tests for the currently desired behavior. With legacy code bases, they are more often than not manual, so create test protocols that a moron can follow, and try to get hold of a not-so-moron that can run these tests for your from time to time. Try to get some use cases from existing users.
Stick to small, reversible changes If a refactoring step goes wrong, it should be small enough to be thrown away without hesitation. Sometimes, this is not easy, my typical worst case steps are:
- decide which functionality to replace. Make plans how the new code should look like.
- move the existing code behind an interface that also works for the new code
- test
- replace the functionality with your new code
- test
- sometimes, the interface is "final", somethimes you can remove/reduce it
Always improve Don't accept functionality setbacks tha "can be fixed later".