How is a service started? The SCM launches the specified executable, in the way it's specified in the service's settings and... that's pretty much it.
However, the service is supposed to support a certain protocol of interaction with SCM. First of all, the service must quickly (within half a minute from the start, IIRC) call the WinAPI function StartServiceCtrlDispatcher() on its main thread. That's basically a pre-written main(): it returns only after the service has been stopped. It takes several function pointers: to the ServiceMain where the service proper is supposed to be, and various event handlers (pause/resume/stop requests, system is shutting down, etc). It creates a separate thread to run the ServiceMain on, and then basically loops processing requests/events from the SCM (event handlers are run on the main thread).
That's basically it. Nothing prevents one to write an application that can run both as a service and stand-alone: put your logic in ServiceMain, call StartServiceCtrlDispatcher with it, if it returns ERROR_FAILED_SERVICE_CONTROLLER_CONNECT (that means you're not being launched by the SCM), call ServiceMain by yourself. Ctrl-C handler and "stop the service" handler are easily unified because on Windows, Ctrl-C handler always runs on a different thread. You just need make sure that your ServiceMain function can be safely signaled that it needs to stop from a different thread, but that's what thread-communication primitives are for.