There is no simple good and easy thing you can do. It greatly depends on what you do, who (and what medium) you target, and how much time and money you have (or are willing to spend).
Generally, it is a lot more economical to accept that some people will crack your program after 3-4 months, if you can sell enough copies during that time. Let them have it, you will soon release an update anyway.
Generally, when fighting reverse engineering, you are fighting a battle that you cannot win. Although many "crackers" are just 13 year old lamers who want to impress their girlfriend as would-be hackers, there are others who read machine code like you read English, and they have tools at hand that are outright scary. Also, they are many and you are one. They can spend many man-years in a only a few weeks, if your program is only interesting enough. You cannot win.
What you can do to stop the most stupid noobs is to use an executable packer/encryptor. That will prevent at least the unexperienced lamers from disassembling and editing the executable in a hex editor, but it won't cost anyone else more than a minute.
Similarly, detecting breakpoints may help to stop your 8 year old sister, but it is not a serious obstacle to anybody else. The simplest thing (which does not even require any special tools) to get around the protection in your above code snippet would for example be to put a breakpoint into MessageBoxA.
Also, there are various techniques which you can find on the internet to detect one or the other debugger, or to crash one or the other debugger, but quite a few are rather outdated and you can safely assume that these exploits are well-known by people who have a little bit of experience, anyway.
Other common techniques to prevent debugging and cracking are to perform senseless calculations. First off, this does not prevent debugging at all, and as far as cracking is concerned, against any serious cracker, it is useless. Nevertheless, throwing in some chaff can fend off a few bloody noobs.
But: You have to be aware that this makes debugging harder for you, too! Probably the best solution for chaff is to define a set of macros that evaluate to nothing in debug build and to chaff in release.
Speaking of debug and release builds... it should be clear that you must *never* distribute a debug build (or a non-stripped executable) or a "preview" that has no protection if you are serious about all this reverse-engineering stuff.
Checksums still don't prevent people from debugging your code, but it makes it a lot harder to patch it, if you do it correctly. The most important thing about it is to not give out any hints of what is happening. If you display a MessageBox saying "code incorrect" or "hey, don't debug this program" then you give out a very valuable clue that can be and will be exploited.
On the other hand, if you build a couple of checksums (starting at different offsets, running from different parts of the application) and use the results of these checksums to look up data or to look up a jump table, then your program may behave odd at some random point later or may crash unexpectedly, which is hard to track and reproduce. The important thing is that you don't compare the value (this can be found and patched easily), but you make other things (which are not immediately obvious) depend on it.
Yes, this is nowhere near easy, but it is nowhere near easy to track and tamper with, either.
If you are particularly sadistic, you can build in a hysteresis such as everything works OK for three or four days, even if your program is modified. Unless someone is willing to test for at least a week, he risks that after boasting with his great crack and spreading it everywhere, all his friends will call him a loser because the crack keeps crashing all the time.
If you're writing a game, you might have it crash only in the 3rd or 4th level. If the game is good, that might actually get some people addicted enough so they buy a copy, who knows. In that case, cracking may even be a form of free advertising
If you do something like a shareware program that has save disabled in the non-registered version, then the non-registered version should not disable the menu item or check for a registration number to enable it. It should not have the code to save. If a cracker needs to patch 2 bytes to enable a menu item, then all your valuable protection is good for nothing.
Requiring validation via internet is annoying to the end user (a bad thing, look at MS), but may be a viable and very effective measure.
The list is endless, and there is no one and only good thing, sorry.