Since there are several "layers" of error-prevention and feedback-loop, there isn't any single answer to your question.
You need to consider each issue individually and choose the appropriate error prevention / feedback model. (Yeah. And you should also consider each issue to each other.)
Error prevention:
- Hide option
- Disable option
- Enable option (and raise an error)
- Enable option (and ignore consequences)
Sometimes it is appropriate to actually hide input fields, menu items and buttons, but in other situations it is better to show the UI elements, but to disable them. If they are visible and disabled, it must be clear why it is disabled. If that's not clear, then it might be better to enable the UI element and give a proper feedback if the users uses this.
The "Print" action is an example of an action that could be enabled, and give error message if there is no printer available.
The "Cut" and "Copy" actions should not be enabled all the time, only when you have chosen something you actually can cut/copy.
"Table tools" and "Image correction tools" etc should only be visible when you are actually working with such an element.
Feedback:
- Passive feedback (hint/instruction)
- Immediate feedback (timely hints related to what you're doing)
- Interruptive feedback (dialog that interrupts your work-flow)
- Batch feedback (Submit info and get feedback on everything)
Sometimes it is enough to just give some discrete hints or instructions. "Fill out every field marked with *)" or "No decimals needed". But in other situations, it might be nice to give a clearer message to the user, but avoid to interrupt the work-flow. Eg. invalid e-mail or invalid social security number. The important issue here is whether the information is helpful to the user at that moment, and not a disturbing element. You can validate on field exit or while the user is editing. It depends. Event the latter one can be aggressive or subtle. If you enter an e-mail, there is no need to yell out "invalid e-mail" right after the first character is entered, because the user will probably fill in the rest of the e-mail address. You could wait until you know that the e-mail really will be invalid. Eg the moment he enters two @'s or an invalid char.
For some situations (especially intersection validation), it might be better to let the user complete the form and submit the form and then provide a proper list of errors.