This seems to be a common problem. I think I've found a good way of doing it and wanted to share to see if anyone notices something wrong.

First create a WinEventHook:
Code:
SetWinEventHook(EVENT_OBJECT_CREATE, EVENT_OBJECT_CREATE, NULL, WinEventProc, 0, 0, WINEVENT_OUTOFCONTEXT);
This will capture alot of things, but what you're interested is when the window associated with your process is created. So in WinEventProc, you can filter out what you don't need. In this example I'm using the classname, but you could use whatever identifier you want.
Code:
void CALLBACK WinEventProc (HWINEVENTHOOK hook, DWORD event, HWND hwnd, LONG idObject, LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime)
{
    if (event == EVENT_OBJECT_CREATE)
    {
        WCHAR classname[1024];
        GetClassName(hwnd, classname, 1024);

        if (wcscmp(classname, AppClassName) == 0)
        {
            // you found it!  hwnd is the pointer you wanted
        }
    }
}
In the above code AppClassName is a LPCWSTR that has the classname of the process (i.e. IEFrame for Internet Explorer).

This has worked well so far and makes it so you don't have to figure out how long to wait before calling EnumWindows or FindWindow. In fact, you don't have to use EnumWindows or FindWindow at all!