Controling Netscape from my own application

My win95 app should be able to control Netscape, in other words, activate its menus, close Netscape, etc as if you click with the mouse on the menu bar, etc. OLE, DDE, ActiveX controls, don't work. I can't find any API function that could be useful. How do I get Netscape windows' and menus' handles? Someone told me to send win messages to the Netscape message queue, how do I put a message in other application message queue??
agirrabAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

alexoCommented:
You find the window handle of netscape (at least two easy methods: FindWindow() and EnumWindows().  One "advanced" method - hooks) and SendMessage() to that handle.

You can send keysrokes to netscape either using SenMessage() or using keybd_event().

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
rocket96Commented:
Hi

If you look at the source for netscape, netscape isn't a COM server (like IE) so it really can't be programmatically controlled by your program.

Instead, consider IE3.x or IE4, which is a COM control. Check IWEBBROWSER on MSDN, and check the newest INETSDK. I mean, DEVSTUDIO's infoviewer is basically the IE engine, as with the outlook express client, and other programs. Just use SPY++ and see the window classes of various programs.

thanks.

Tim
0
agirrabAuthor Commented:
Alexo:
Thanks for your ideas, but I think that there is a problem. If I use FindWindow I have to send two parameters to that function. The first parameter could be NULL in my case. But the second should be the window's title/caption (I'm not sure if you call it title or caption) and Netscape changes it depending on which document it has opened. How can I solve that problem? Anyway, if it's true what rocket96 says, I can't do anything.  
0
OWASP: Avoiding Hacker Tricks

Learn to build secure applications from the mindset of the hacker and avoid being exploited.

alexoCommented:
If you have only one instance of Netscape running, you can search by class.  In my version of Navigator 4.05 the class is "Afx:400000:b:10008:6:110037", but you can check it yourself with a spy application.

>>Anyway, if it's true what rocket96 says, I can't do anything.  
Nonsense, you can do lots of things.
- You can send keystrokes using keybd_event().
- You can send keystrokes using SendMessage() with WM_KEYDOWN and WM_KEYDOWN.
- You can send WM_COMMAND messages to simulate menu selections.

0
alexoCommented:
0
agirrabAuthor Commented:
Alexo:

I'll check what you say, thanks. On the other hand, DDE won't work, I'm completely sure.
0
alexoCommented:
Check the URL I gave you even if you're completely sure.  The worst thing that can happen is a waste of 5 minutes...
0
agirrabAuthor Commented:
Alexo:
 
I said that I was completely sure because I have tried to solve the problem using DDE. I had checked that URL sometime ago, thanks anyway.
On the other hand, I have tried to use SendMessage and it hasn't worked. I've got the handle of the Netscape window using FindWindow and searching by class. I launch Netscape from my app, so its window class is "NetscapeSlaveClass", maybe that's why it doesn't work, could it be? If I open Netscape first and them my app the class of Netscape window (Communicator 4.02) is Afx:400000:b:1526:6:X, where X it's an hexadecimal number of three or four numbers, depending on the number of windows that you have already opened. It's not a constant value, how do you get the window class then?            
0
alexoCommented:
OK, let's try a different approach.
Use EnumWindows(EnumWindowsProc, NULL);  In the EnumWindowsProc() function you supply, check the title/class (as substrings) and set a global HWND variable when you find the correct window).

Using SendMessage may not work.
A different approach is bringing the window to the foreground using SetForegroundWindow() and feeding it keystrokes using keybd_event().

0
rocket96Commented:
Using sendmessage might might not because when you send messages to netscape, you're sending it to the main netscape window. Maybe (i'm not totally sure, checking out netscape source will verfiy this) netscape doesn't handle keyboard hits in its main window proc. Maybe it sets up a keyboard hook (I usually do this) and in this case, it is almost impossible to send keystrokes to netscape.

In all honestly, the IE control is much easier to use, is well documented, and there are numerous examples which use the ie control.

Tim
0
agirrabAuthor Commented:
Alexo:

I must apologize for my delay answering. I made I mistake, the class of Netscape windows is always Afx:400000:b:1526:6:X (X hexadecimal number, not constant). Anyway I still have the problem of how to find the handle. EnumWindowsProc needs the handle of a parent window, my app is not Netscape window´s parent.
Thanks and one more time, sorry for the delay.

agirrab.

Tim,
 You can send messages using SendMessage and PostMessage to Netscape and to IE. So you can simulate keystrokes. The problem is the handle. It´s very easy to get IE window´s handle, but not Netscape´s. Using a Spy you can get the window´s class (and so the handle), but only for the current Netscape windows (and them you can try to send keystrokes, and it works), the next time you execute Netscape, the class will vary: Problem.

agirrab.
0
alexoCommented:
>> EnumWindowsProc needs the handle of a parent window, my app is not Netscape window´s parent.

Huh?  EnumWindowsProc() is a placeholder for a user supplied callback function.  It is repatedly called with handles to all the top-level windows.

Example:

HWND hNetscapeWnd = NULL;

void main()
{
    EnumWindows(MyEnumProc, NULL);
    // ...
}

BOOL CALLBACK MyEnumProc(HWND hwnd, LPARAM dummy)
{
    char buff[1024];

    GetWindowText(hwnd, buff, sizeof buff);
    if (strstr(buff, " - Netscape"))
    {
        hNetscapeWnd = hwnd;
        return FALSE; // found!
    }

    return TRUE;
}
0
agirrabAuthor Commented:
Hi Alexo,

First, I want to say that I am begining to study programming in Windows 95, so I ignore some basic things, sorry.

Second, what you have said in your last comment it´s almost the perfect answer. It works if you put the Desktop handle instead of NULL as the second parameter for EnumWindows. And, in the CallBack function, when you use GetWindowText, the title needs an exact match. In other words, if you open Netscape in the blank page, its title will be simply "Netscape". Using that in the comparison (strstr(buff,"Netscape")), you get the desired and slippery handle. The only drawback is that you need to start Netscape in a known page to get the exact window´s title, that´s acceptable.


 
0
agirrabAuthor Commented:
Alexo:

Thanks a lot.

agirrab
0
alexoCommented:
>> It works if you put the Desktop handle instead of NULL as the second parameter for EnumWindows.

Duh!  The second parameter is an application defined value that is passed to the MyEnumProc() function as is (binds with the "dummy" argument).  You can put whatever you want there, it won't make a difference.

Here's what the docs say:

--- quote ---

The EnumWindows function enumerates all top-level windows on the screen by passing the handle of each window, in turn, to an application-defined callback function. EnumWindows continues until the last top-level window is enumerated or the callback function returns FALSE.

BOOL EnumWindows(
    WNDENUMPROC lpEnumFunc,      // pointer to callback function
    LPARAM lParam       // application-defined value
   );      
 
lpEnumFunc - Points to an application-defined callback function. For more information, see the EnumWindowsProc callback function.

lParam - Specifies a 32-bit, application-defined value to be passed to the callback function.

--- and ---

The EnumWindowsProc function is an application-defined callback function that receives top-level window handles as a result of a call to the EnumWindows or EnumDesktopWindows function.

BOOL CALLBACK EnumWindowsProc(
    HWND hwnd,      // handle to parent window
    LPARAM lParam       // application-defined value
   );      
 
hwnd - Identifies a top-level window.

lParam - Specifies the application-defined value given in EnumWindows or EnumDesktopWindows.
 
Return Values - To continue enumeration, the callback function must return TRUE; to stop enumeration, it must return FALSE.

--- end quote ---

You can do anything in the enumeration procedure.  I chose to use a substring comparison with strstr(), you can force an exact comparison with strcmp(), whatever...

strstr(buff, "Netscape")) will catch anything that contains the substring "Netscape" in it.
0
agirrabAuthor Commented:
Alexo:

I´ve read the same in the on-line help (Windows SDK) and in a book (Windows NT Win32 API Superbible). Maybe I did something wrong, but with NULL it didn´t work and with the DeskTopWindow´s handle it did. I´ll check again. I wasn´t questioning what you had said.
Anyway, given Netscape window´s  handle, I can´t activate its menus. I can do what I want with the window (move it, resize it, close it, etc...), but it doesn´t obey to my WM_SYSKEY* commands. I´ve tried with IE and it worked.
agirrab
0
agirrabAuthor Commented:
Alexo:

You were right, it works with NULL. Surely I made a mistake somewhere. But, you can´t access to Netscape window´s menus.

agirrab
0
alexoCommented:
The menus send WM_COMMAND messages.  You can check the numeric IDs by openning netscape in a resource editor and checking the menu resources.
0
agirrabAuthor Commented:
Alexo:
Could you tell me the name of any resources editor? I think that you can´t do what you say using Visual C++ or C++ Builder (Borland), their editors aren´t resource editors.

Thanks,
 agirrab
0
alexoCommented:
I use VC++.  Just drag the executable into the editor.
0
agirrabAuthor Commented:
Alexo:

Thanks a lot.
0
agirrabAuthor Commented:
Alexo:

Thanks a lot.

agirrab
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Development

From novice to tech pro — start learning today.