Like mgb_phys mentioned, VB6, Java and C# programs are easily decompiled. For C# there's Spices.Net, and Salamander even has a web-based decompiler, they're both pretty good, but for example they don't handle switch statements very well - they tend to generate a mix of goto and if/else which is less readable. From the point of view of the decompiler there's some ambiguity as to what the original source of the code was, which varies from languages that run on a VM, or are interpreted to languages that compile to machine code.
Decompiling a C/C++ program is much harder. In Java you can interpret the Virtual Machine byte code, and in C# or any .NET language you can interpret the IL (intermediate language) that the compiler generates. For example, you can use ildasm.exe (which comes with visual studio) to browse any .NET assembly and actually look at the IL - you can see in ildasm just how much data a decompiler has available (the IL is not very far away from the original source). In C/C++ the compiled code has much less information regarding the original source, so it's much more ambiguous. You're able to get the Assembly level code using programs like ADA or OLLY, but to get any further than that you'll need to be a pro, or have some knowledge of the original code.
For VB6 I've use VB Decompiler with good results.