SilverScreen Solid Modeler

Primer for MFC Applications

Primer for MFC Applications

Previous topic Next topic  

Primer for MFC Applications

Previous topic Next topic JavaScript is required for the print function  

SilverEngineEllipse

 

Primer for MFC Applications

 


Up and Running

 

For MFC applications, it is a relatively simple task to get up and running with the SilverScreen engine. The following describes a pretty simple-minded application.

 

Here is what needs be done to integrate SilverEngine:

 

r_point

The first step is to create a new application in Visual C++. It may be SDI or MDI. Next, we will need to make some additions to the wizard-generated code.

r_point

Very important. Next, add the following preprocessor constant to your project: SILVERENGINE_CLIENT_BUILD. From the Project menu, select Settings. Choose the C/C++ tab, and select Preprocessor from the Category listbox. Add SILVERENGINE_CLIENT_BUILD to the Preprocessor Definitions edit box. This ensures that the definitions and declarations used in SILVER.H and its included files are correct for SilverEngine applications.

r_point

Since the CWinApp-derived class serves as a global container for the application, it is a natural place to put SilverEngine initialization code.

r_point

The CView-derived classes are where much of the display is handled, and so it’s natural to handle the SilverScreen Display Context operations there.

 

Note that it is usually not necessary to explicitly add the SilverEngine export library to your link command. The SILVER.H file contains Visual C++ pragmas that cause the compiler to add the appropriate link commands implicitly.

 

 


CWinApp Modifications

 

In the implementation file (.CPP) for your CWinApp-derived class, find the InitInstance method. The following code should be placed at the top:

 

C / C++ Code

 

 EngineInitStruct eis = {0};

 

  eis.bits = EI_USE_ENV;

  strcpy( eis.env_file, "silver" );

 

  engine_initialize( &eis );

 

 

At the bottom, once the main frame window has been created, place the following code:

 

C / C++ Code

 

 CFrameWnd *f = (CFrameWnd *) AfxGetMainWnd();

 engine_set_frame_window( f->m_hWnd );

 

 

Now find the ExitInstance method. Place the following code before the return statement:

 

C / C++ Code

 

 ss_command( "clear" );      // clear all drawings

 ss_command( "quit all" );   // perform cleanup and exit SilverEngine

 

 

 

 


CView Modifications

The CView-derived class is where a lot of the action happens. In its header file, find the Implementation section, and add a bit of code:

 

C / C++ Code

 

  // Implementation

  public:

     SDC SDCHandle;

     HBITMAP refresh_bitmap;

     HBITMAP old_bitmap;

     HDC refresh_dc; 

 

 

Now go to the implementation (.CPP) file.  In the constructor for your CView-derived class, add the following initializations:

 

C / C++ Code

 

  SDCHandle = 0; 

  refresh_bitmap = 0; 

  old_bitmap = 0; 

  refresh_dc = 0;

 

 

These member variables must also be cleaned up on destruction. Therefore, in the CView destructor, add the following code:

 

C / C++ Code

 

  if ( SDCHandle )

     {

     sdc_close( SDCHandle );

 

     ::SelectObject( refresh_dc, old_bitmap );

     ::DeleteObject( refresh_bitmap );

     ::DeleteDC( refresh_dc );

     }

 

 

SilverEngine assumes that device contexts used to render into are persistent, i.e. private to the application window class. In order to ensure this, you would usually create the window using the CS_OWNDC class flag. So you should now create a PreCreateWindow method for the CView class, and place the following code before the return statement:

 

C / C++ Code

 

  cs.lpszClass = 

     AfxRegisterWndClass( CS_HREDRAW|CS_VREDRAW|CS_OWNDC |CS_DBLCLKS,

                          hCursor);

 

 

 

Most likely the best place to manage application/SilverEngine connections is in the CView::OnSize method. This is where we discover the initial size of the SilverEngine window, and the place we need to handle resizing of the refresh bitmap. So create one, and add the following code:

 

C / C++ Code

 

if ( ! cx && ! cy )    // in first call to OnSize, dimensions are 0,0

   return;                

 

// get window dimensions

CRect r;

GetClientRect( &r );

HDC dc = GetDC()->m_hDC;

 

if ( ! SDCHandle )          // engine window hasn’t been created yet

   {

   // initialize engine display context

   SDCInitStruct sdcis;

 

   sdcis.hWnd = m_hWnd;

   sdcis.drawDC = dc;

   sdcis.refreshDC = refresh_dc = ::CreateCompatibleDC( dc );

   refresh_bitmap = ::CreateCompatibleBitmap( dc, r.Width(), r.Height() );

   old_bitmap = (HBITMAP) ::SelectObject( refresh_dc, refresh_bitmap );

 

   SDCHandle = sdc_open( &sdcis );

   }

else        // need to resize the current refresh bitmap

   {

   ::SelectObject( refresh_dc, old_bitmap );

   ::DeleteObject( refresh_bitmap );

   refresh_bitmap = ::CreateCompatibleBitmap( dc, r.Width(), r.Height() );

   old_bitmap = (HBITMAP) ::SelectObject( refresh_dc, refresh_bitmap );

   }

 

// set SilverEngine context

sdc_goto( SDCHandle );

 

// ensure that screen size is properly set

resize_screen( r.left, r.right - 1, r.top, r.bottom - 1, FALSE );

 

// cause SilverEngine to repaint the current screen

ss_command( "refresh on" );

 

// force paint operation

Invalidate( FALSE );

 

 

 

 

See Also

See the SilverEngine sample EngineShell for a complete example