| Tenouk C & C++ | MFC Home | ActiveX Doc Servers & Internet 1 | ActiveX Doc Servers & Internet 3 | Download | Site Index |


 

 

 

 

ActiveX Document Servers and the Internet Part 2

 

 

 

 

Program examples compiled using Visual C++ 6.0 compiler on Windows XP Pro machine with Service Pack 2 and some Figure screen snapshots have been taken on Windows 2000 server. The Internet Information Services version is IIS 4.x/5.x/6.x on Windows 2000 Server SP 4 and Windows XP Pro SP 2. The Internet Explorer is 6.x. Topics and sub topics for this tutorial are listed below. A complete information about IIS installation, configuration and testing a Web site is dumped HERE and how to setup FTP server also included HERE. Both Web and FTP servers were done on Windows 2000 Server SP4. Don’t forget to read Tenouk’s small disclaimer.

  1. Debugging an ActiveX Document Server

  2. MYEX35A: Phase 2 - Adding More Functionality

  3. The Coding Part

  4. CMainFrame Class

  5. CMyex35aApp Class

  6. CMyex35aDoc Class

  7. CMyex35aView Class

 

Debugging an ActiveX Document Server

 

If you want to debug your program in ActiveX document server mode, click on the Debug tab in the Project Settings dialog. Set Program Arguments to /Embedding, and then start the program. Now start the container program and use it to "start" the server, which has in fact already started in the debugger and is waiting for the container.

 

ActiveX document and Internet - Figure 22: Changing the Visual C++ project setting for debugging process.

 

Figure 22: Changing the Visual C++ project setting for debugging process.

 

MYEX35A: Phase 2 - Adding More Functionality

 

Let continue our task by adding more functionalities to MYEX35A. Add two bitmaps, with ID IDB_GREEN and IDB_RED for the start and stop button. Select and right click the root folder in ResourceView and choose Insert context menu. Select Bitmap and click New.

 

ActiveX document and Internet - Figure 23: Inserting new bitmap.

 

Figure 23: Inserting new bitmap.

 

Create two bitmaps as shown below.

 

ActiveX document and Internet - Figure 24:  IDB_GREEN bitmap for Start button.

 

Figure 24:  IDB_GREEN bitmap for Start button.

 

ActiveX document and Internet - Figure 25: IDB_RED bitmap for Stop button.

 

Figure 25: IDB_RED bitmap for Stop button.

 

Add new dialog, IDD_DIALOGBAR for dialog bar. De-select the Title bar; choose Child for Styles and None for Border in Styles page as shown below.

 

ActiveX document and Internet - Figure 26:  IDD_DIALOGBAR property page.

 

Figure 26:  IDD_DIALOGBAR property page.

 

Add Static text, Edit control and two buttons with the following properties. It is better for you to adjust the button size to fit the bitmap size later.

 

ActiveX document and Internet - Figure 27: IDC_URL Edit control property page.

 

Figure 27: IDC_URL Edit control property page.

 

ActiveX document and Internet - Figure 28: IDC_START button property page.

 

Figure 28: IDC_START button property page.

 

ActiveX document and Internet - Figure 29:  IDC_START button, Styles property page.

 

Figure 29:  IDC_START button, Styles property page.

 

ActiveX document and Internet - Figure 30: IDC_STOP button property page.

 

Figure 30: IDC_STOP button property page.

 

ActiveX document and Internet - Figure 31: IDC_STOP button, Styles property page.

 

Figure 31: IDC_STOP button, Styles property page.

 

Add context menu, IDR_MENUCONTEXT as shown below.

 

ActiveX document and Internet - Figure 32: IDR_MENUCONTEXT, new context menu.

 

Figure 32: IDR_MENUCONTEXT, new context menu.

 

Then add the menu item, Clear All with ID ID_EDIT_CLEAR_ALL.

 

ActiveX document and Internet - Figure 33: Adding menu item Clear All to the context menu.

 

Figure 33: Adding menu item Clear All to the context menu.

 

The Coding Part

 

Add new header and source files named Urlthread.h and Urlthread.cpp respectively.

 

ActiveX document and Internet - Figure 34: Adding new files to project.

 

Figure 34: Adding new files to project.

 

ActiveX document and Internet - Figure 35: Selecting and entering the new file name.

 

Figure 35: Selecting and entering the new file name.

 

Copy the codes as shown in the following Listing.

 

URLTHREAD.H

 

// urlthread.h

 

extern CString g_strURL;

extern volatile BOOL g_bThreadStarted;

extern CEvent g_eKill;

 

extern UINT UrlThreadProc(LPVOID pParam);

extern void LogInternetException(LPVOID pParam, CInternetException* pe);

 

 

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

 

 

 

 

 

URLTHREAD.CPP

 

// urlthread.cpp

 

#include <stdafx.h>

#include "urlthread.h"

#define MAXBUF 100

 

CString g_strURL = "https://";

volatile BOOL g_bThreadStarted = FALSE;

CEvent g_eKill;

 

UINT UrlThreadProc(LPVOID pParam)

{

       g_bThreadStarted = TRUE;

       CString strLine;

       CInternetSession session;

       CStdioFile* pFile1 = NULL;

 

       Try

       {

          pFile1 = session.OpenURL(g_strURL, 0, INTERNET_FLAG_TRANSFER_BINARY |

          INTERNET_FLAG_KEEP_CONNECTION); // needed for Windows NT c/r authentication

          // Keep displaying text from the URL until the Kill event is received

          while(::WaitForSingleObject(g_eKill.m_hObject, 0) != WAIT_OBJECT_0) {

              // one line at a time

              if(pFile1->ReadString(strLine) == FALSE) break;

              strLine += '\n';

              ::SendMessage((HWND) pParam, EM_SETSEL, (WPARAM) 999999, 1000000);

              ::SendMessage((HWND) pParam, EM_REPLACESEL, (WPARAM) 0,  (LPARAM) (const char*) strLine);

              Sleep(250); // Deliberately slow down the transfer

         }

       }

       catch(CInternetException* e) {

              LogInternetException(pParam, e);

              e->Delete();

       }

       if(pFile1 != NULL) delete pFile1; // closes the file -- prints a warning

       g_bThreadStarted = FALSE;

       // Post any message to update the toolbar buttons

       ::PostMessage((HWND) pParam, EM_SETSEL, (WPARAM) 999999, 1000000);

       TRACE("Post thread exiting normally\n");

       return 0;

}

 

void LogInternetException(LPVOID pParam, CInternetException* pe)

{     

       CString strGmt = CTime::GetCurrentTime().FormatGmt("%m/%d/%y %H:%M:% GMT");

       char text1[300], text2[100];

       wsprintf(text1, "\r\nERROR: WinInet error #%d -- %s\r\n   ", pe->m_dwError, (const char*) strGmt);

       pe->GetErrorMessage(text2, 99);

       strcat(text1, text2);

       if(pe->m_dwError == 12152) {

              strcat(text1, "  URL not found?\r\n");

       }

       ::SendMessage((HWND) pParam, EM_SETSEL, (WPARAM) 999999, 1000000);

       ::SendMessage((HWND) pParam, EM_REPLACESEL, (WPARAM) 0, (LPARAM) text1);

}

 

 

Listing 1.

 

Add the following #include in StdAfx.h.

 

#include <afxinet.h>

#include <afxmt.h>

 

Listing 2 - ActiveX document and Internet, C++ and MFC code snippet.

 

Listing 2.

 

CMainFrame Class

 

Add the following public member variables.

CBitmap     m_bitmapGreen;

CBitmap     m_bitmapRed;

Then, change the:

CToolBar    m_wndToolBar;

variable to

CDialogBar  m_wndDialogBar;

And change the class access type as shown below. We need to access the public variable later.

 

Listing 3 - ActiveX document and Internet, C++ and MFC code snippet.

 

Listing 3

 

Add the following #include directive to MainFrm.cpp.

#include "urlthread.h"

Listing 4 - ActiveX document and Internet, C++ and MFC code snippet.

 

Listing 4.

 

Change the OnCreate() as shown below.

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)

{

      if (CFrameWnd::OnCreate(lpCreateStruct) == -1)

            return -1;

 

      if (!m_wndStatusBar.Create(this) || !m_wndStatusBar.SetIndicators(indicators,

              sizeof(indicators)/sizeof(UINT)))

      {

            TRACE0("Failed to create status bar\n");

            return -1;      // fail to create

      }

 

      if (!m_wndDialogBar.Create(this, IDD_DIALOGBAR, CBRS_TOP, 0xE810))

      {

            TRACE0("Failed to create dialog bar\n");

            return -1;      // fail to create

      }

      m_wndDialogBar.SetDlgItemText(IDC_URL, g_strURL);

      // attach the color bitmaps to the dialog bar buttons

      m_bitmapGreen.LoadBitmap(IDB_GREEN);

      HBITMAP hBitmap = (HBITMAP) m_bitmapGreen.GetSafeHandle();

      ((CButton*) m_wndDialogBar.GetDlgItem(IDC_START))->SetBitmap(hBitmap);

      m_bitmapRed.LoadBitmap(IDB_RED);

      hBitmap = (HBITMAP) m_bitmapRed.GetSafeHandle();

      ((CButton*) m_wndDialogBar.GetDlgItem(IDC_STOP))->SetBitmap(hBitmap);

      return 0;

}

 

And PreCreateWindow() as shown below.

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)

{

      // TODO: Modify the Window class or styles here by modifying

      //  the CREATESTRUCT cs

      return CFrameWnd::PreCreateWindow(cs);

}

CMyex35aApp Class

 

Using ClassWizard, add ExitInstance() virtual function to CMyex35aApp class.

 

ActiveX document and Internet - Figure 36: Adding ExitInstance() virtual function.

 

Figure 36: Adding ExitInstance() virtual function.

 

Click the Edit Code button and modify the code as shown below.

int CMyex35aApp::ExitInstance()

{

      // TODO: Add your specialized code here and/or call the base class

      g_eKill.SetEvent();

      Sleep(500);

      return CWinApp::ExitInstance();

}

 

Listing 5 - ActiveX document and Internet, C++ and MFC code snippet.

 

Listing 5.

 

Add the following #include directive to myex35a.cpp.

 

#include "urlthread.h"

 

 

 

Add the following code in InitInstance().

 

AfxEnableControlContainer();

 

Listing 6 - ActiveX document and Internet, C++ and MFC code snippet.

 

Listing 6

 

Delete the following lines of code in InitInstance().

 

      // The one and only window has been initialized, so show and update it.

      m_pMainWnd->ShowWindow(SW_SHOW);

      m_pMainWnd->UpdateWindow();

 

Remove the following code of the OnDraw() in SrvrItem.cpp.

 

// Remove this if you use rSize

UNREFERENCED_PARAMETER(rSize);

 

Add variables, delete and change the class access type as shown below in lpFrame.h.

 

Listing 7 - ActiveX document and Internet, C++ and MFC code snippet.

 

Listing 7.

 

Add the #include "urlthread.h" directive and modify the OnCreateControlBars() in lpFrame.cpp as shown below.

BOOL CInPlaceFrame::OnCreateControlBars(CFrameWnd* pWndFrame, CFrameWnd* pWndDoc)

{

      m_wndDialogBar.SetOwner(this); // for commands

      if (!m_wndDialogBar.Create(pWndFrame, IDD_DIALOGBAR, CBRS_TOP, 0xE810))

      {

            TRACE0("Failed to create dialog bar\n");

            return -1;      // fail to create

      }

      m_wndDialogBar.SetDlgItemText(IDC_URL, g_strURL);

      // attach the color bitmaps to the dialog bar buttons

      m_bitmapGreen.LoadBitmap(IDB_GREEN);

      HBITMAP hBitmap = (HBITMAP) m_bitmapGreen.GetSafeHandle();

      ((CButton*) m_wndDialogBar.GetDlgItem(IDC_START))->SetBitmap(hBitmap);

      m_bitmapRed.LoadBitmap(IDB_RED);

      hBitmap = (HBITMAP) m_bitmapRed.GetSafeHandle();

      ((CButton*) m_wndDialogBar.GetDlgItem(IDC_STOP))->SetBitmap(hBitmap);

 

      return TRUE;

}

 

Listing 8 - ActiveX document and Internet, C++ and MFC code snippet.

 

Listing 8.

 

CMyex35aDoc Class

 

Change the GetDocObjectServer() virtual function to public in myex35aDoc.h.

 

Listing 9 - ActiveX document and Internet, C++ and MFC code snippet.

 

Listing 9.

 

CMyex35aView Class

 

Using ClassWizard delete OnDestroy(). Go to ResourceView, select the IDD_DIALOGBAR, right click and select the ClassWizard context menu.

 

ActiveX document and Internet - Figure 37: Invoking ClassWizard from dialog editor.

 

Figure 37: Invoking ClassWizard from dialog editor.

 

For the Adding a Class dialog prompt, choose Select an existing class.

 

ActiveX document and Internet - Figure 38: Adding dialog to an existing class.

 

Figure 38: Adding dialog to an existing class.

 

Select the CMyex35aView class.

 

ActiveX document and Internet - Figure 39: Selecting an existing class.

 

Figure 39: Selecting an existing class.

 

Just click Yes for the following dialog prompt.

 

ActiveX document and Internet - Figure 40: Dialog prompt for the class to dialog linking.

 

Figure 40: Dialog prompt for the class to dialog linking.

 

Add the following message map command and update command handler functions.

 

ID

Command

ID_EDIT_CLEAR_ALL

Command

IDC_START

Command and update command

IDC_STOP

Command and update command

 

Table 2.

 

You may add those commands and update commands manually if needed.

 

 

 

 

 

 

Listing 10 - ActiveX document and Internet, C++ and MFC code snippet.

 

Listing 10.

 

Add the following #include directives to myex35aView.cpp.

#include "Urlthread.h"

#include "MainFrm.h"

#include "IpFrame.h"

 

Listing 11 - ActiveX document and Internet, C++ and MFC code snippet.

 

Listing 11.

 

If you add some of the previous handlers manually make sure message map in myex35aView.cpp as shown below.

 

Listing 12 - ActiveX document and Internet, C++ and MFC code snippet.

 

Listing 12.

 

Don’t forget to delete the OnDestroy() implementation and complete the message handler implementations as shown below.

void CMyex35aView::OnEditClearAll()

{

      // Not so useable here, coz of the save as...

      SetWindowText("");

}

 

void CMyex35aView::OnStart()

{

      CWnd* pFrm = GetParent(); // SDI only

      CWnd* pBar;

      if(pFrm->IsKindOf(RUNTIME_CLASS(CMainFrame))) {

            pBar = &((CMainFrame*) pFrm)->m_wndDialogBar;

      }

      else {

            pBar = &((CInPlaceFrame*) pFrm)->m_wndDialogBar;

      }

      // g_strURL: thread sync?

      pBar->GetDlgItemText(IDC_URL, g_strURL);

      TRACE("CMyex35aView::OnRequest -- URL = %s\n", g_strURL);

      AfxBeginThread(UrlThreadProc, GetSafeHwnd(), THREAD_PRIORITY_NORMAL);

}

 

void CMyex35aView::OnStop()

{

      g_eKill.SetEvent();

}

 

void CMyex35aView::OnUpdateStop(CCmdUI* pCmdUI)

{

      pCmdUI->Enable(g_bThreadStarted);

}

 

void CMyex35aView::OnUpdateStart(CCmdUI* pCmdUI)

{

      pCmdUI->Enable(!g_bThreadStarted);

}

 

Build and run. Type the localhost address or any other address if you are online and click the green button. You can stop the progress anytime by pressing the red button that only visible when the program is in progress.

 

ActiveX document and Internet - Figure 41: MYEX35A phase 2 program output in action, testing the localhost.

 

Figure 41: MYEX35A phase 2 program output in action, testing the localhost.

 

ActiveX document and Internet - Figure 42: MYEX35A phase 2 program output in action, testing the google.com.

 

Figure 42: MYEX35A phase 2 program output in action, testing the google.com.

 

Use the File Open menu to open the previous test.35a file.

 

ActiveX document and Internet - Figure 43: MYEX35A phase 2 program output in action, opening test.35a file.

 

Figure 43: MYEX35A phase 2 program output in action, opening test.35a file.

 

Create a text file, let name it test.txt. Write some content and put it under the wwwroot directory and type the address of the text file as shown below. Press the green button.

 

ActiveX document and Internet - Figure 44: MYEX35A phase 2 program output in action, opening text file.

 

Figure 44: MYEX35A phase 2 program output in action, opening text file.

 

It seems very useful and fun isn’t it? Let have some story for what we have done.

 

 

 

 

 

Further reading and digging:

  1. Win32 process, thread and synchronization story can be found starting from Module R.

  2. MSDN MFC 7.0 class library online documentation.

  3. MSDN MFC 9.0 class library online documentation - latest version.

  4. Porting & Migrating your older programs.

  5. MSDN Library

  6. DCOM at MSDN.

  7. COM+ at MSDN.

  8. COM at MSDN.

  9. Windows data type.

  10. Win32 programming Tutorial.

  11. The best of C/C++, MFC, Windows and other related books.

  12. Unicode and Multi-byte character set: Story and program examples.

 

 


| Tenouk C & C++ | MFC Home | ActiveX Doc Servers & Internet 1 | ActiveX Doc Servers & Internet 3 | Download | Site Index |