15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


Continuos data acquisition

Keith Vasilakes -- kvasilak@cyberoptics.com
Thursday, December 19, 1996

        Environment: VC++ 4.1, Win 95
     
     
     I have an MFC app that needs to get data as fast as possible during 
     the life of the app. The app contains three OCX's one of which is a 
     graph on a DialogBar. I would like to call a function from within 
     OnInitialUpdate() that just loops as fast as possible untill the 
     program ends. However as we all know the user would be locked out of 
     the app, the UI would never update and the user could not close the 
     App.
     
     The first, and easiest, solution was to use a OnTimer event to allow 
     some idletime processing to be done. This almost works, if the timer 
     interval is too short toolbars etc dont get updated, if the timer 
     interval is too long the app runs too slow. This most problematic when 
     different machine speeds are involved.
     
     The second solution was to add an OnIdle Loop to the timer, like this,
     
              LONG lIdle = 0;
              while (AfxGetApp()->OnIdle(lIdle++));
     
     This allows the view to be updated but if a toolbar is moved I get 
     this OS error,
     
     "This application has performed an illegal operation and will be 
     shutdown"
     
     The debugger shows that this is totally within MFC code not mine, Does 
     anyone have a clue as to why calling OnIdle() from within a OnTimer() 
     would be bad? I got the OnIdle() idea from "Programming Windows95 with 
     MFC" by Prosie so I am surprised it doesn't work.
     
     
     
     Solution three;
     So now I bite the bullet and create a worker thread to handle the 
     looping, this too almost works, Theproblem is that the thread cannot 
     get a handle to the Graph OCX that is on a DialogBar, The thread can 
     however get the handle if the Graph OCX is placed on the FormView ( 
     not an option ) and I can get the Graph OCX's handle if I am within 
     the main thread, like OnTimer().
     
     the code to do this within the worker thread is;
     
     UINT MyThread(LPVOID pParam )
     {
        BOOL *Run = (BOOL *)pParam;
        VARIANT vtRed, vtGreen, vtBlue;
        CMultiApp *pMyApp = ((CMultiApp *)AfxGetApp());
     
        CCSGraph *MyGraph = pMyApp->m_MyDialogBar->GetChart();
     
        while(*Run)
        {
                pMyApp->m_ctlXPG.QuickGrab(nCamera, nTimeout, nInit);
                pMyApp->m_ctlXPG.FetchFilterFrame(nNumLines, &vtRed, 
     &vtGreen, &vtBlue);
     
                pMyApp->m_Graph->SetPlotReadings( vtRed);
                pMyApp->m_Graph->Refresh();
        }
     
     m_MyDialogBar is a pointer to the DialogBar and is valid at the time 
     of the function call.
     
     
     CCSGraph *CBarGraph::GetChart()
     {
        CCSGraph *pGraph = (CCSGraph *)GetDlgItem(IDC_CSGRAPHCTRL);
        return pGraph;
     }
     
     GetDlgItem() Fails if GetChart() is called from the worker thread but 
     succeeds if called from the main thread.
     
     
     
     The thread idea would be the preferred way to run this App, if it 
     worked.
     Any Ideas on how to get a pointer to that darn OCX?
     
     Is there any other way to run this app without either a timer or a 
     worker thread?
     
     If someone can solve this I will nominate them the God of MFC :-)
     
     
     Thanks,
     
     Keith Vasilakes
     Manufacturing Software Engineer, CyberOptics



Kevin Tarn -- kevin@pln.com.tw
Monday, December 23, 1996


You can create a structure that contains any data items you wanted
passing to the worker thread.

	CCardStruct* pCard = new CCardStruct;
	pCard->m_bLaunchCardRecord = FALSE;
	pCard->m_szBeginLunch = dlg.m_szTimeFrom;
	pCard->m_szEndLunch = dlg.m_szTimeTo;
	AfxBeginThread((AFX_THREADPROC)BatchCollectionThread, LPVOID)pCard);


Kevin Tarn
kevin@pln.com.tw


----------
±HҐуЄМ: 	kvasilak@cyberoptics.com[SMTP:kvasilak@cyberoptics.com]
¶З°e¤йґБ: 	1996¦~12¤л19¤й PM 23:16
¦¬ҐуЄМ: 	MFC-L@netcom.com
ҐD¦®: 	Continuos data acquisition

        Environment: VC++ 4.1, Win 95
     
     
     I have an MFC app that needs to get data as fast as possible during 
     the life of the app. The app contains three OCX's one of which is a 
     graph on a DialogBar. I would like to call a function from within 
     OnInitialUpdate() that just loops as fast as possible untill the 
     program ends. However as we all know the user would be locked out of 
     the app, the UI would never update and the user could not close the 
     App.
     
     The first, and easiest, solution was to use a OnTimer event to allow 
     some idletime processing to be done. This almost works, if the timer 
     interval is too short toolbars etc dont get updated, if the timer 
     interval is too long the app runs too slow. This most problematic when 
     different machine speeds are involved.
     
     The second solution was to add an OnIdle Loop to the timer, like this,
     
              LONG lIdle = 0;
              while (AfxGetApp()->OnIdle(lIdle++));
     
     This allows the view to be updated but if a toolbar is moved I get 
     this OS error,
     
     "This application has performed an illegal operation and will be 
     shutdown"
     
     The debugger shows that this is totally within MFC code not mine, Does 
     anyone have a clue as to why calling OnIdle() from within a OnTimer() 
     would be bad? I got the OnIdle() idea from "Programming Windows95 with 
     MFC" by Prosie so I am surprised it doesn't work.
     
     
     
     Solution three;
     So now I bite the bullet and create a worker thread to handle the 
     looping, this too almost works, Theproblem is that the thread cannot 
     get a handle to the Graph OCX that is on a DialogBar, The thread can 
     however get the handle if the Graph OCX is placed on the FormView ( 
     not an option ) and I can get the Graph OCX's handle if I am within 
     the main thread, like OnTimer().
     
     the code to do this within the worker thread is;
     
     UINT MyThread(LPVOID pParam )
     {
        BOOL *Run = (BOOL *)pParam;
        VARIANT vtRed, vtGreen, vtBlue;
        CMultiApp *pMyApp = ((CMultiApp *)AfxGetApp());
     
        CCSGraph *MyGraph = pMyApp->m_MyDialogBar->GetChart();
     
        while(*Run)
        {
                pMyApp->m_ctlXPG.QuickGrab(nCamera, nTimeout, nInit);
                pMyApp->m_ctlXPG.FetchFilterFrame(nNumLines, &vtRed, 
     &vtGreen, &vtBlue);
     
                pMyApp->m_Graph->SetPlotReadings( vtRed);
                pMyApp->m_Graph->Refresh();
        }
     
     m_MyDialogBar is a pointer to the DialogBar and is valid at the time 
     of the function call.
     
     
     CCSGraph *CBarGraph::GetChart()
     {
        CCSGraph *pGraph = (CCSGraph *)GetDlgItem(IDC_CSGRAPHCTRL);
        return pGraph;
     }
     
     GetDlgItem() Fails if GetChart() is called from the worker thread but 
     succeeds if called from the main thread.
     
     
     
     The thread idea would be the preferred way to run this App, if it 
     worked.
     Any Ideas on how to get a pointer to that darn OCX?
     
     Is there any other way to run this app without either a timer or a 
     worker thread?
     
     If someone can solve this I will nominate them the God of MFC :-)
     
     
     Thanks,
     
     Keith Vasilakes
     Manufacturing Software Engineer, CyberOptics



mzsong@aztech.com.sg
Monday, March 24, 1997

Hi, dear kevin and all mfc-member:
	Now it's the last problem I can ask.
	It's about use mfc object in a close-able thread.

	Kevin show the way to use mfc object in thread:

	class CMyDocument:public CDocumnet
	{
	public:
		CString str_Thread_Tmp;
		void OnTest();
	}

	void CMyDocument::OnTest()
	{
>		CCardStruct* pCard =3D new CCardStruct;
>		pCard->m_bLaunchCardRecord =3D FALSE;
>		pCard->m_szBeginLunch =3D str_Thread_Tmp;
>		pCard->m_szEndLunch =3D dlg.m_szTimeTo;
>		AfxBeginThread((AFX_THREADPROC)BatchCollectionThread, (LPVOID)pCard);
	}


	But if I want to use some CString-like class object which is created in
the thread, and because the thread open a dialogbox, it can't
automativally return,

	void CMyDocument::OnTest()
	{
		AfxBeginThread(mythread, this);
		Sleep(1000);
		TerminateThread();
	}

	UINT mythread(LPVOID lParam)
	{
		CString str_Tmp;
		str_Tmp =3D "I'm ";
		MessagBox(NULL,"a", "silly thread.", MB_OK);
		return(0);
	}

	Then I call TerminateThread() in main thread, it will leak some memory.
=09
	My question:
	How can I terminate a thread from outside when it can't response to
message, so can't return by itself?=09
	If there's some memory leap in every ExitThread/TerminateThread(),
it'll hang after running 2~10 hours.
					James	3/23

>----------
>From: 	kevin@pln.com.tw[SMTP:kevin@pln.com.tw]
>Sent: 	Monday, December 23, 1996 4:59 AM
>To: 	'mfc-l@netcom.com'; 'kvasilak@cyberoptics.com'
>Subject: 	Re: Continuos data acquisition
>
>
>You can create a structure that contains any data items you wanted
>passing to the worker thread.
>
>	CCardStruct* pCard =3D new CCardStruct;
>	pCard->m_bLaunchCardRecord =3D FALSE;
>	pCard->m_szBeginLunch =3D dlg.m_szTimeFrom;
>	pCard->m_szEndLunch =3D dlg.m_szTimeTo;
>	AfxBeginThread((AFX_THREADPROC)BatchCollectionThread, LPVOID)pCard);
>
>
>Kevin Tarn
>kevin@pln.com.tw
>
>
>----------
>=B1H=A5=F3=AA=CC: 	=
kvasilak@cyberoptics.com[SMTP:kvasilak@cyberoptics.com]
>=B6=C7=B0e=A4=E9=B4=C1: 	1996=A6~12=A4=EB19=A4=E9 PM 23:16
>=A6=AC=A5=F3=AA=CC: 	MFC-L@netcom.com
>=A5D=A6=AE: 	Continuos data acquisition
>
>        Environment: VC++ 4.1, Win 95
>    =20
>    =20
>     I have an MFC app that needs to get data as fast as possible =
during=20
>     the life of the app. The app contains three OCX's one of which is =
a=20
>     graph on a DialogBar. I would like to call a function from within=20
>     OnInitialUpdate() that just loops as fast as possible untill the=20
>     program ends. However as we all know the user would be locked out =
of=20
>     the app, the UI would never update and the user could not close =
the=20
>     App.
>    =20
>     The first, and easiest, solution was to use a OnTimer event to =
allow=20
>     some idletime processing to be done. This almost works, if the =
timer=20
>     interval is too short toolbars etc dont get updated, if the timer=20
>     interval is too long the app runs too slow. This most problematic =
when=20
>     different machine speeds are involved.
>    =20
>     The second solution was to add an OnIdle Loop to the timer, like =
this,
>    =20
>              LONG lIdle =3D 0;
>              while (AfxGetApp()->OnIdle(lIdle++));
>    =20
>     This allows the view to be updated but if a toolbar is moved I get =

>     this OS error,
>    =20
>     "This application has performed an illegal operation and will be=20
>     shutdown"
>    =20
>     The debugger shows that this is totally within MFC code not mine, =
Does=20
>     anyone have a clue as to why calling OnIdle() from within a =
OnTimer()=20
>     would be bad? I got the OnIdle() idea from "Programming Windows95 =
with=20
>     MFC" by Prosie so I am surprised it doesn't work.
>    =20
>    =20
>    =20
>     Solution three;
>     So now I bite the bullet and create a worker thread to handle the=20
>     looping, this too almost works, Theproblem is that the thread =
cannot=20
>     get a handle to the Graph OCX that is on a DialogBar, The thread =
can=20
>     however get the handle if the Graph OCX is placed on the FormView =
(=20
>     not an option ) and I can get the Graph OCX's handle if I am =
within=20
>     the main thread, like OnTimer().
>    =20
>     the code to do this within the worker thread is;
>    =20
>     UINT MyThread(LPVOID pParam )
>     {
>        BOOL *Run =3D (BOOL *)pParam;
>        VARIANT vtRed, vtGreen, vtBlue;
>        CMultiApp *pMyApp =3D ((CMultiApp *)AfxGetApp());
>    =20
>        CCSGraph *MyGraph =3D pMyApp->m_MyDialogBar->GetChart();
>    =20
>        while(*Run)
>        {
>                pMyApp->m_ctlXPG.QuickGrab(nCamera, nTimeout, nInit);
>                pMyApp->m_ctlXPG.FetchFilterFrame(nNumLines, &vtRed,=20
>     &vtGreen, &vtBlue);
>    =20
>                pMyApp->m_Graph->SetPlotReadings( vtRed);
>                pMyApp->m_Graph->Refresh();
>        }
>    =20
>     m_MyDialogBar is a pointer to the DialogBar and is valid at the =
time=20
>     of the function call.
>    =20
>    =20
>     CCSGraph *CBarGraph::GetChart()
>     {
>        CCSGraph *pGraph =3D (CCSGraph *)GetDlgItem(IDC_CSGRAPHCTRL);
>        return pGraph;
>     }
>    =20
>     GetDlgItem() Fails if GetChart() is called from the worker thread =
but=20
>     succeeds if called from the main thread.
>    =20
>    =20
>    =20
>     The thread idea would be the preferred way to run this App, if it=20
>     worked.
>     Any Ideas on how to get a pointer to that darn OCX?
>    =20
>     Is there any other way to run this app without either a timer or a =

>     worker thread?
>    =20
>     If someone can solve this I will nominate them the God of MFC :-)
>    =20
>    =20
>     Thanks,
>    =20
>     Keith Vasilakes
>     Manufacturing Software Engineer, CyberOptics
>



Mike Blaszczak -- mikeblas@nwlink.com
Wednesday, March 26, 1997

At 17:53 3/24/97 +0800, mzsong@aztech.com.sg wrote:

>	Then I call TerminateThread() in main thread, it will leak some memory.

You bet it will. You're lucky it doesn't crash your whole system, bring
down your whole network, or format your hard drive.

>	How can I terminate a thread from outside when it can't response to
>message, so can't return by itself?	

You can't.  You need to let a thread die when it wants to die.  If you
want to write a program that uses threads, you need to make the threads
able to exit on demand.  That means you can't leave message boxes in
your threads lying around.  That means that you can't let your threads
do things that could go into overtime without checking to see if they've
been asked to terminate. Period.

>If there's some memory leap in every ExitThread/TerminateThread(),
>it'll hang after running 2~10 hours.

That's on a _good_ day.  On a bad day, it'll crash your machine on the
first try.

TerminateThread() is to be avoided at all costs.  It's a bad API.  It's
not to be used.  If someone on my team used TerminateThread() without
discussing it wit hthe rest of the team for a week or two, they'd be 
out of a job.

ExitThread() is unusable in threads that use MFC or the C Runtime
libraries, period.


.B ekiM
http://www.nwlink.com/~mikeblas/
These words are my own. I do not speak on behalf of Microsoft.
       One is too many and a million is not enough.



mzsong@aztech.com.sg
Friday, March 28, 1997

[Mini-digest: 2 responses]

Hi,
	I don't think it's good to ask this question, because no WebMaster
would like to find a lot of Automatically-Browser visiting his homepage
and cause the network problem.
	Question: How to write a homepage downloader?

	If I use CWebBrowser control, it'll generate all kinds of messagebox.
So I have to let the thread wait during the whole night, or close the
poor thread from outside.

	It's a small toy, not a release requirment.

			James 3/28
			This mesasge is my own. Nothing with our "respectfully" Aztech Co. or
others.
			: |


>----------
>From: 	Song Ming Zhang - R&D
>Sent: 	Monday, March 24, 1997 1:53 AM
>To: 	mfc-l@netcom.com
>Cc: 	kevin@pln.com.tw
>Subject: 	RE: Continuos data acquisition
>
>Hi, dear kevin and all mfc-member:
>	Now it's the last problem I can ask.
>	It's about use mfc object in a close-able thread.
>
>	Kevin show the way to use mfc object in thread:
>
>	class CMyDocument:public CDocumnet
>	{
>	public:
>		CString str_Thread_Tmp;
>		void OnTest();
>	}
>
>	void CMyDocument::OnTest()
>	{
>>		CCardStruct* pCard =3D new CCardStruct;
>>		pCard->m_bLaunchCardRecord =3D FALSE;
>>		pCard->m_szBeginLunch =3D str_Thread_Tmp;
>>		pCard->m_szEndLunch =3D dlg.m_szTimeTo;
>>		AfxBeginThread((AFX_THREADPROC)BatchCollectionThread, =
(LPVOID)pCard);
>	}
>
>
>	But if I want to use some CString-like class object which is created =
in
>the thread, and because the thread open a dialogbox, it can't
>automativally return,
>
>	void CMyDocument::OnTest()
>	{
>		AfxBeginThread(mythread, this);
>		Sleep(1000);
>		TerminateThread();
>	}
>
>	UINT mythread(LPVOID lParam)
>	{
>		CString str_Tmp;
>		str_Tmp =3D "I'm ";
>		MessagBox(NULL,"a", "silly thread.", MB_OK);
>		return(0);
>	}
>
>	Then I call TerminateThread() in main thread, it will leak some =
memory.
>=09
>	My question:
>	How can I terminate a thread from outside when it can't response to
>message, so can't return by itself?=09
>	If there's some memory leap in every ExitThread/TerminateThread(),
>it'll hang after running 2~10 hours.
>					James	3/23
>
>>----------
>>From: 	kevin@pln.com.tw[SMTP:kevin@pln.com.tw]
>>Sent: 	Monday, December 23, 1996 4:59 AM
>>To: 	'mfc-l@netcom.com'; 'kvasilak@cyberoptics.com'
>>Subject: 	Re: Continuos data acquisition
>>
>>
>>You can create a structure that contains any data items you wanted
>>passing to the worker thread.
>>
>>	CCardStruct* pCard =3D new CCardStruct;
>>	pCard->m_bLaunchCardRecord =3D FALSE;
>>	pCard->m_szBeginLunch =3D dlg.m_szTimeFrom;
>>	pCard->m_szEndLunch =3D dlg.m_szTimeTo;
>>	AfxBeginThread((AFX_THREADPROC)BatchCollectionThread, LPVOID)pCard);
>>
>>
>>Kevin Tarn
>>kevin@pln.com.tw
>>
>>
>>----------
>>=B1H=A5=F3=AA=CC: 	=
kvasilak@cyberoptics.com[SMTP:kvasilak@cyberoptics.com]
>>=B6=C7=B0e=A4=E9=B4=C1: 	1996=A6~12=A4=EB19=A4=E9 PM 23:16
>>=A6=AC=A5=F3=AA=CC: 	MFC-L@netcom.com
>>=A5D=A6=AE: 	Continuos data acquisition
>>
>>        Environment: VC++ 4.1, Win 95
>>    =20
>>    =20
>>     I have an MFC app that needs to get data as fast as possible =
during=20
>>     the life of the app. The app contains three OCX's one of which is =
a=20
>>     graph on a DialogBar. I would like to call a function from within =

>>     OnInitialUpdate() that just loops as fast as possible untill the=20
>>     program ends. However as we all know the user would be locked out =
of=20
>>     the app, the UI would never update and the user could not close =
the=20
>>     App.
>>    =20
>>     The first, and easiest, solution was to use a OnTimer event to =
allow=20
>>     some idletime processing to be done. This almost works, if the =
timer=20
>>     interval is too short toolbars etc dont get updated, if the timer =

>>     interval is too long the app runs too slow. This most problematic =
when=20
>>     different machine speeds are involved.
>>    =20
>>     The second solution was to add an OnIdle Loop to the timer, like =
this,
>>    =20
>>              LONG lIdle =3D 0;
>>              while (AfxGetApp()->OnIdle(lIdle++));
>>    =20
>>     This allows the view to be updated but if a toolbar is moved I =
get=20
>>     this OS error,
>>    =20
>>     "This application has performed an illegal operation and will be=20
>>     shutdown"
>>    =20
>>     The debugger shows that this is totally within MFC code not mine, =
Does=20
>>     anyone have a clue as to why calling OnIdle() from within a =
OnTimer()=20
>>     would be bad? I got the OnIdle() idea from "Programming Windows95 =
with=20
>>     MFC" by Prosie so I am surprised it doesn't work.
>>    =20
>>    =20
>>    =20
>>     Solution three;
>>     So now I bite the bullet and create a worker thread to handle the =

>>     looping, this too almost works, Theproblem is that the thread =
cannot=20
>>     get a handle to the Graph OCX that is on a DialogBar, The thread =
can=20
>>     however get the handle if the Graph OCX is placed on the FormView =
(=20
>>     not an option ) and I can get the Graph OCX's handle if I am =
within=20
>>     the main thread, like OnTimer().
>>    =20
>>     the code to do this within the worker thread is;
>>    =20
>>     UINT MyThread(LPVOID pParam )
>>     {
>>        BOOL *Run =3D (BOOL *)pParam;
>>        VARIANT vtRed, vtGreen, vtBlue;
>>        CMultiApp *pMyApp =3D ((CMultiApp *)AfxGetApp());
>>    =20
>>        CCSGraph *MyGraph =3D pMyApp->m_MyDialogBar->GetChart();
>>    =20
>>        while(*Run)
>>        {
>>                pMyApp->m_ctlXPG.QuickGrab(nCamera, nTimeout, nInit);
>>                pMyApp->m_ctlXPG.FetchFilterFrame(nNumLines, &vtRed,=20
>>     &vtGreen, &vtBlue);
>>    =20
>>                pMyApp->m_Graph->SetPlotReadings( vtRed);
>>                pMyApp->m_Graph->Refresh();
>>        }
>>    =20
>>     m_MyDialogBar is a pointer to the DialogBar and is valid at the =
time=20
>>     of the function call.
>>    =20
>>    =20
>>     CCSGraph *CBarGraph::GetChart()
>>     {
>>        CCSGraph *pGraph =3D (CCSGraph *)GetDlgItem(IDC_CSGRAPHCTRL);
>>        return pGraph;
>>     }
>>    =20
>>     GetDlgItem() Fails if GetChart() is called from the worker thread =
but=20
>>     succeeds if called from the main thread.
>>    =20
>>    =20
>>    =20
>>     The thread idea would be the preferred way to run this App, if it =

>>     worked.
>>     Any Ideas on how to get a pointer to that darn OCX?
>>    =20
>>     Is there any other way to run this app without either a timer or =
a=20
>>     worker thread?
>>    =20
>>     If someone can solve this I will nominate them the God of MFC :-)
>>    =20
>>    =20
>>     Thanks,
>>    =20
>>     Keith Vasilakes
>>     Manufacturing Software Engineer, CyberOptics
>>
>
-----From: Richard Morris 

Look into the synchronization classes, particularly CEvent.  You can easily
use it as a way to signal a thread that it is time to shutdown, or do a
number of other things.  It will probably take a little restructuring of
your threads, but then they will be well behaved.
If your threads are doing much with the outside world, it is likely you need
to use synchronization anyway.

There is a good treatment of threads and synchronization in "Advanced Windows"
by Jeffrey Richter (Microsoft Press).  It doesn't discuss them in relation
to MFC,
but the leap is a very small one once you understand the APIs and their
application.

Good luck.


At 12:38 AM 3/26/97 -0800, you wrote:
>At 17:53 3/24/97 +0800, mzsong@aztech.com.sg wrote:
>
>>	Then I call TerminateThread() in main thread, it will leak some memory.
>
>You bet it will. You're lucky it doesn't crash your whole system, bring
>down your whole network, or format your hard drive.
>
>>	How can I terminate a thread from outside when it can't response to
>>message, so can't return by itself?	

.............
****************************************************************
Live now.
Make now always the most precious time.
Now will never come again.
	 - Captain Jean-Luc Picard, U.S.S. Enterprise




Andrew L. Snow -- als@fl.net.au
Sunday, March 30, 1997

At 10:01 AM 3/28/97 +0800, you wrote:
>	I don't think it's good to ask this question, because no WebMaster
>would like to find a lot of Automatically-Browser visiting his homepage
>and cause the network problem.

Many have been written before... web whacker for instance. Oh well.

>	Question: How to write a homepage downloader?

It can be written quite simply with Visual C++4.2's CInternetSession
MFC class which has a useful ::OpenURL(..) function, which you can call
to very easily call to open a CFile-type connection to an internet site
(HTTP, FTP, or gopher I believe).  It also has some kind of proxy support,
see the visual C help for more info.

All that remains is to parse the HTML for links-   anchors and then
follow them up.  

Hope that helps.


----
Andrew Snow
als@fl.net.au






Become an MFC-L member | Вернуться в корень Архива |