Export (0) Print
Expand All

COM Interop Sample: .NET Client and COM Server

This sample demonstrates how a .NET client, built to access a COM server, creates an instance of a COM coclass and calls class members to perform mortgage calculations.

In this example, the client creates and calls an instance of the Loan coclass, passes four arguments (one of those four being equal to zero) to the instance, and displays the computations. Code fragments from this sample appear throughout this section.

using System;
using LoanLib;

public class LoanApp {
   public static void Main(String[] Args) {

      Loan ln = new Loan();
      
      if (Args.Length < 4) 
      {
         Console.WriteLine("Usage: ConLoan Balance Rate Term Payment");
         Console.WriteLine("    Either Balance, Rate, Term, or Payment 
            must be 0");
         return;
      }

      ln.OpeningBalance = Convert.ToDouble(Args[0]);
      ln.Rate = Convert.ToDouble(Args[1])/100.0;
      ln.Term = Convert.ToInt16(Args[2]);
      ln.Payment = Convert.ToDouble(Args[3]);
      
      if (ln.OpeningBalance == 0.00) ln.ComputeOpeningBalance();
      if (ln.Rate == 0.00) ln.ComputeRate();
      if (ln.Term == 0) ln.ComputeTerm();
      if (ln.Payment == 0.00) ln.ComputePayment();

      Console.WriteLine("Balance = {0,10:0.00}", ln.OpeningBalance);
      Console.WriteLine("Rate    = {0,10:0.0%}", ln.Rate);
      Console.WriteLine("Term    = {0,10:0.00}", ln.Term);
      Console.WriteLine("Payment = {0,10:0.00}\n", ln.Payment);

      bool MorePmts;
      double Balance = 0.0;
      double Principal = 0.0;
      double Interest = 0.0;

      Console.WriteLine("{0,4}{1,10}{2,12}{3,10}{4,12}", "Nbr", "Payment",
        "Principal", "Interest", "Balance");
      Console.WriteLine("{0,4}{1,10}{2,12}{3,10}{4,12}", "---", "-------",
        "---------", "--------", "-------");

      MorePmts = ln.GetFirstPmtDistribution(ln.Payment, out Balance, 
        out Principal, out Interest);

      for (short PmtNbr = 1; MorePmts; PmtNbr++) {
         Console.WriteLine("{0,4}{1,10:0.00}{2,12:0.00}{3,10:0.00}
           {4,12:0.00}", PmtNbr, ln.Payment, Principal, Interest,
            Balance);
         MorePmts = ln.GetNextPmtDistribution(ln.Payment, ref Balance, 
           out Principal, out Interest); 
      }
    }
}

// Loan.cpp : Implementation of CLoan
#include "stdafx.h"
#include "math.h"
#include "LoanLib.h"
#include "Loan.h"

static double Round(double value, short digits); 

STDMETHODIMP CLoan::get_OpeningBalance(double *pVal)
{
    *pVal = OpeningBalance;
    return S_OK;
}

STDMETHODIMP CLoan::put_OpeningBalance(double newVal)
{
    OpeningBalance = newVal;
    return S_OK;
}

STDMETHODIMP CLoan::get_Rate(double *pVal)
{
    *pVal = Rate;
    return S_OK;
}

STDMETHODIMP CLoan::put_Rate(double newVal)
{
    Rate = newVal;
    return S_OK;
}

STDMETHODIMP CLoan::get_Payment(double *pVal)
{
    *pVal = Payment;
    return S_OK;
}

STDMETHODIMP CLoan::put_Payment(double newVal)
{
    Payment = newVal;
    return S_OK;
}

STDMETHODIMP CLoan::get_Term(short *pVal)
{
    *pVal = Term;
    return S_OK;
}

STDMETHODIMP CLoan::put_Term(short newVal)
{
    Term = newVal;
    return S_OK;
}

STDMETHODIMP CLoan::ComputePayment(double *pVal)
{
    Payment = Round(OpeningBalance * (Rate / 
        (1 - pow((1 + Rate), -Term))),2);
    *pVal = Payment;
    return S_OK;
}

STDMETHODIMP CLoan::ComputeOpeningBalance(double *pVal)
{
    OpeningBalance = Round(Payment / (Rate / 
        (1 - pow((1 + Rate), -Term))),2);
    *pVal = OpeningBalance ;
    return S_OK;
}

STDMETHODIMP CLoan::ComputeRate(double *pVal)
{
    double DesiredPayment = Payment;

    for (Rate = 0.001; Rate < 28.0; Rate += 0.001)
    {
        Payment = Round(OpeningBalance * (Rate / 
         (1 - pow((1 + Rate), -Term))),2);

        if (Payment >= DesiredPayment)
            break;
    }

    *pVal = Rate;   
    return S_OK;
}

STDMETHODIMP CLoan::ComputeTerm(short *pVal)
{
    double DesiredPayment = Payment;
    for (Term = 1; Term < 480 ; Term ++)
    {
        Payment = Round(OpeningBalance * (Rate / 
         (1 - pow((1 + Rate), -Term))),2);
        if (Payment <= DesiredPayment)
            break;
    }
    *pVal = Term;   
    return S_OK;
}

STDMETHODIMP CLoan::GetFirstPmtDistribution(double PmtAmt, double *Balance, double *PrinPortion, double *IntPortion, VARIANT_BOOL *pVal)
{
    *Balance = OpeningBalance;
    GetNextPmtDistribution(PmtAmt, Balance, PrinPortion, IntPortion, 
      pVal);
    return S_OK;
}

STDMETHODIMP CLoan::GetNextPmtDistribution(double PmtAmt, double *Balance, double *PrinPortion, double *IntPortion, VARIANT_BOOL *pVal)
{
    *IntPortion = Round(*Balance * Rate, 2);
    *PrinPortion = Round(PmtAmt - *IntPortion, 2);
    *Balance = Round(*Balance - *PrinPortion, 2);

    if (*Balance <= 0.0)
        *pVal = FALSE;
    else
        *pVal = TRUE;
    return S_OK;
}

STDMETHODIMP CLoan::get_RiskRating(BSTR *pVal)
{
    *pVal = (BSTR)RiskRating;
    return S_OK;
}

STDMETHODIMP CLoan::put_RiskRating(BSTR newVal)
{
    RiskRating = newVal;
    return S_OK;
}
static double Round(double value, short digits) 
{
    double factor = pow(10, digits);
    return floor(value * factor + 0.5)/factor;
}
Show:
© 2014 Microsoft