Thanks for the quick answer!
TWAIN is still active since the TWAIN working group has recently churned out versions 2.0 through 2.3 and is currently working on version 2.4. Because it's been around so long, it's still the most popular standard on Windows by far, warts and all. There's not so much use on Mac anymore---most scanner manufacturer's just provide a proprietary interface and their own application but I think the ICA standard is starting to pick up there.
An aspect of TWAIN that can be difficult to deal with is that the scanner driver (data source) displays it's own user interface which means it needs to get messages from the application for button presses and other GUI events. That's why you normally need to hook the main message loop. And it uses the window handle of the app's main window to post messages back to the app. That's not a problem when using a different thread's message queue like in the post I linked to. But the other purpose of the window handle is to act as the parent window of the driver's GUI so the driver's GUI is always displayed in front of the app. So if the window handle comes from the hidden window, as it would in the linked-to post, the driver's GUI won't neccessarily be displayed in front of the app's main window. That's the problem with that method. Perhaps there's a way to chain the windows together, I don't know. I'll have to look into that.