There are a few ways to do this with the standard WebBrowser control.
For HTML: If you want to fillout a textbox and then click submit then don't even bother with a keypress. Do this:
webbrowser1.Navigate("javascript:function%20E(){f0=document.forms[0];f0['login'].value='foo';}E()")
webbrowser1.Navigate("javascript:document.forms[0].submit()")
This will be much more reliable then trying to send keypresses for HTML.
For Flash:If there's a flash element on the webpage that needs clicking then it won't work. In that case SendKeys is reliable but only sends to the active application so it won't work in the background. You can send windows messages like this (example will press the letter "f"):
Dim c as char = "f"c
Dim classname As New System.Text.StringBuilder(100)
Dim ExplorerHandle As IntPtr = webbrowser1.Handle
GetClassNameA(ExplorerHandle, classname, classname.Capacity)
Do While classname.ToString <> "Internet Explorer_Server"
ExplorerHandle = GetWindow(GetExplorerHandle, GetWindow_Cmd.GW_CHILD)
GetClassNameA(ExplorerHandle, classname, classname.Capacity)
Loop
PostMessageA(ExplorerHandle, WM_Constants.WM_KEYDOWN, IntPtr.Zero, IntPtr.Zero)
PostMessageA(ExplorerHandle, WM_Constants.WM_KEYUP, CType(VkKeyScanA(CType(Asc(c), Byte)), IntPtr), IntPtr.Zero)
You can find the definitions for PostMessage, GetClassName, GetWindow, etc, online at pinvoke.net. Notice that the WM_KEYUP uses c but the WM_KEYDOWN sends a dummy key (0). KEYDOWN and KEYUP have to go in pairs or else the key won't be registered, but if you hold down Control while sending, for example, KEYDOWN "p", it will activate IE's print function. For all the letters and digits you can send 0 for KEYDOWN and the correct letter for KEYUP. Backspace seems to need a real KEYDOWN, not 0, but Control-Backspace doesn't seem to do much in IE so if c = vbBack, KEYDOWN needs to be different.
The keypresses aren't very accurate, either, and 1 time in about 500 it misses. But you can do it with the window minimized, no problem, and a standard WebBrowser control.
Another option is to use AxWebBrowser. The ActiveX control seems to avoid the Control-P problem but it's not as easy to manipluate because it isn't a nice .Net control.