Solved

Controling Netscape from my own application

Posted on 1998-05-13
22
285 Views
Last Modified: 2013-12-03
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??
0
Comment
Question by:agirrab
  • 11
  • 9
  • 2
22 Comments
 
LVL 11

Accepted Solution

by:
alexo earned 100 total points
ID: 1401454
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
 
LVL 1

Expert Comment

by:rocket96
ID: 1401455
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
 

Author Comment

by:agirrab
ID: 1401456
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
3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

 
LVL 11

Expert Comment

by:alexo
ID: 1401457
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
 
LVL 11

Expert Comment

by:alexo
ID: 1401458
0
 

Author Comment

by:agirrab
ID: 1401459
Alexo:

I'll check what you say, thanks. On the other hand, DDE won't work, I'm completely sure.
0
 
LVL 11

Expert Comment

by:alexo
ID: 1401460
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
 

Author Comment

by:agirrab
ID: 1401461
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
 
LVL 11

Expert Comment

by:alexo
ID: 1401462
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
 
LVL 1

Expert Comment

by:rocket96
ID: 1401463
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
 

Author Comment

by:agirrab
ID: 1401464
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
 
LVL 11

Expert Comment

by:alexo
ID: 1401465
>> 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
 

Author Comment

by:agirrab
ID: 1401466
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
 

Author Comment

by:agirrab
ID: 1401467
Alexo:

Thanks a lot.

agirrab
0
 
LVL 11

Expert Comment

by:alexo
ID: 1401468
>> 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
 

Author Comment

by:agirrab
ID: 1401469
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
 

Author Comment

by:agirrab
ID: 1401470
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
 
LVL 11

Expert Comment

by:alexo
ID: 1401471
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
 

Author Comment

by:agirrab
ID: 1401472
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
 
LVL 11

Expert Comment

by:alexo
ID: 1401473
I use VC++.  Just drag the executable into the editor.
0
 

Author Comment

by:agirrab
ID: 1401474
Alexo:

Thanks a lot.
0
 

Author Comment

by:agirrab
ID: 1401475
Alexo:

Thanks a lot.

agirrab
0

Featured Post

Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

zlib is a free compression library (a DLL) on which the popular gzip utility is built.  In this article, we'll see how to use the zlib functions to compress and decompress data in memory; that is, without needing to use a temporary file.  We'll be c…
Whether you've completed a degree in computer sciences or you're a self-taught programmer, writing your first lines of code in the real world is always a challenge. Here are some of the most common pitfalls for new programmers.
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
The Email Laundry PDF encryption service allows companies to send confidential encrypted  emails to anybody. The PDF document can also contain attachments that are embedded in the encrypted PDF. The password is randomly generated by The Email Laundr…

803 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question