Link to home
Start Free TrialLog in
Avatar of philsmicronet
philsmicronetFlag for Australia

asked on

MFC DLL being called from Win 32 App

I need to use an Active X control (one that interfaces with an EFTPOS pinpad) from a Win32 application (written in vc++). I decided the best way was to create an MFC DLL and call this from my application. However, I am getting an error. By single stepping the dll I found that when I am calling Create function, the system is returning an error message saying CoInitialize function had not been called. I have never programmed in MFC so I think I havent set something up or called something. I have included some of the code below

1. Code from my vc application (as a test I just used the app wizard to create the windows applications).

            case ID_FILE_TESTEFTPOS:
                  InitialisePCEftpos(hWnd);
                  break;


2. My MFC Application
CCsdEft *lpeftpos = NULL;


BOOL CPCEftposApp::InitInstance()
{
      CWinApp::InitInstance();
      AfxOleInitModule( );
      AfxEnableControlContainer ();

      lpeftpos = new CCsdEft;
      return(TRUE);
}

int CPCEftposApp::ExitInstance()
{
      delete lpeftpos;
      return CWinApp::ExitInstance();
}

void InitialisePCEftpos(HWND hParent)
{
      AFX_MANAGE_STATE(AfxGetStaticModuleState());

      CWnd window;
    CRect eftrect(175,130,375,150);
    CRect wrect(175,130,375,150);

      window.Attach(hParent);
      lpeftpos->Create(NULL,WS_VISIBLE, eftrect, &window, EFTID); // This is where it fails.
      window.Detach();
}

3. My MFC Application Class
class CPCEftposApp : public CWinApp
{
public:
      CPCEftposApp();

// Overrides
public:
      virtual BOOL InitInstance();
      virtual int ExitInstance();

      DECLARE_MESSAGE_MAP()
};

4. The EFTPOS class which is copied from a sample demo program
class CCsdEft : public CWnd
{
protected:
      DECLARE_DYNCREATE(CCsdEft)
public:
      CLSID const& GetClsid()
      {
            static CLSID const clsid
                  = { 0xd548a364, 0x6579, 0x11d0, { 0x91, 0x3c, 0x44, 0x45, 0x53, 0x54, 0x0, 0x0 } };
            return clsid;
      }
      virtual BOOL Create(LPCTSTR lpszClassName,
            LPCTSTR lpszWindowName, DWORD dwStyle,
            const RECT& rect,
            CWnd* pParentWnd, UINT nID,
            CCreateContext* pContext = NULL)
      { return CreateControl(GetClsid(), lpszWindowName, dwStyle, rect, pParentWnd, nID); }

    BOOL Create(LPCTSTR lpszWindowName, DWORD dwStyle,
            const RECT& rect, CWnd* pParentWnd, UINT nID,
            CFile* pPersist = NULL, BOOL bStorage = FALSE,
            BSTR bstrLicKey = NULL)
      { return CreateControl(GetClsid(), lpszWindowName, dwStyle, rect, pParentWnd, nID,
            pPersist, bStorage, bstrLicKey); }

// Attributes
public:
      CString GetResponseText();
      void SetResponseText(LPCTSTR);
      CString GetResponseCode();
      void SetResponseCode(LPCTSTR);
      CString GetTxnType();
      void SetTxnType(LPCTSTR);
      long GetStan();
      void SetStan(long);
      CString GetPanSource();
      void SetPanSource(LPCTSTR);
      CString GetPan();
      void SetPan(LPCTSTR);
      CString GetNii();
      void SetNii(LPCTSTR);
      long GetMerchant();
      void SetMerchant(long);
      CString GetTrack2();
      void SetTrack2(LPCTSTR);
      CString GetTrack1();
      void SetTrack1(LPCTSTR);
      long GetDialogX();
      void SetDialogX(long);
      long GetDialogY();
      void SetDialogY(long);
      CString GetDateSettlement();
      void SetDateSettlement(LPCTSTR);
      CString GetDialogType();
      void SetDialogType(LPCTSTR);
      CString GetAccountType();
      void SetAccountType(LPCTSTR);
      CString GetTxnRef();
      void SetTxnRef(LPCTSTR);
      CString GetPinPadVersion();
      void SetPinPadVersion(LPCTSTR);
      CString GetPinPadSerialNumber();
      void SetPinPadSerialNumber(LPCTSTR);
      CString GetDataField();
      void SetDataField(LPCTSTR);
      CString GetReceipt();
      void SetReceipt(LPCTSTR);
      long GetTimeout();
      void SetTimeout(long);
      BOOL GetConfigLocked();
      void SetConfigLocked(BOOL);
      BOOL GetCutReceipt();
      void SetCutReceipt(BOOL);
      BOOL GetLoggedOn();
      void SetLoggedOn(BOOL);
      CString GetDateExpiry();
      void SetDateExpiry(LPCTSTR);
      CY GetTotalPurchase();
      void SetTotalPurchase(const CY&);
      CY GetTotalCash();
      void SetTotalCash(const CY&);
      CY GetTotalRefund();
      void SetTotalRefund(const CY&);
      long GetTotalPurchaseCount();
      void SetTotalPurchaseCount(long);
      long GetTotalCashCount();
      void SetTotalCashCount(long);
      long GetTotalRefundCount();
      void SetTotalRefundCount(long);
      CString GetCaid();
      void SetCaid(LPCTSTR);
      CString GetCatid();
      void SetCatid(LPCTSTR);
      BOOL GetSuccess();
      void SetSuccess(BOOL);
      CString GetDate();
      void SetDate(LPCTSTR);
      CString GetTime();
      void SetTime(LPCTSTR);
      BOOL GetEnableTip();
      void SetEnableTip(BOOL);
      long GetResponseType();
      void SetResponseType(long);
      CString GetChqSerialNumber();
      void SetChqSerialNumber(LPCTSTR);
      CString GetChqBranch();
      void SetChqBranch(LPCTSTR);
      CString GetChqAccount();
      void SetChqAccount(LPCTSTR);
      CString GetDialogPosition();
      void SetDialogPosition(LPCTSTR);
      long GetMessageType();
      void SetMessageType(long);
      CString GetEftposNetwork();
      void SetEftposNetwork(LPCTSTR);
      BOOL GetPrintJournal();
      void SetPrintJournal(BOOL);
      CString GetPosVendor();
      void SetPosVendor(LPCTSTR);
      CString GetPosProductId();
      void SetPosProductId(LPCTSTR);
      CString GetPosVersion();
      void SetPosVersion(LPCTSTR);
      CString GetLicenseId();
      void SetLicenseId(LPCTSTR);
      CY GetSettleTotal();
      void SetSettleTotal(const CY&);
      CY GetSettleTotalDebit();
      void SetSettleTotalDebit(const CY&);
      CY GetSettleTotalCredit();
      void SetSettleTotalCredit(const CY&);
      BOOL GetReceiptAutoPrint();
      void SetReceiptAutoPrint(BOOL);
      CString GetCardType();
      void SetCardType(LPCTSTR);
      BOOL GetReady();
      void SetReady(BOOL);
      BOOL GetInstalled();
      void SetInstalled(BOOL);
      long GetVersionMajor();
      void SetVersionMajor(long);
      long GetVersionMinor();
      void SetVersionMinor(long);
      long GetVersionRevision();
      void SetVersionRevision(long);
      BOOL GetEnableErrorDialog();
      void SetEnableErrorDialog(BOOL);
      CString GetFilename();
      void SetFilename(LPCTSTR);
      CString GetAiic();
      void SetAiic(LPCTSTR);
      CY GetSettleTotalPurchase();
      void SetSettleTotalPurchase(const CY&);
      CY GetSettleTotalRefund();
      void SetSettleTotalRefund(const CY&);
      CString GetAuthCode();
      void SetAuthCode(LPCTSTR);
      BOOL GetLastTxnSuccess();
      void SetLastTxnSuccess(BOOL);
      CY GetSettleTotalCash();
      void SetSettleTotalCash(const CY&);
      CString GetSettleCardTotals();
      void SetSettleCardTotals(LPCTSTR);
      long GetSettleCountCash();
      void SetSettleCountCash(long);
      long GetSettleCount();
      void SetSettleCount(long);
      long GetSettleCountCredit();
      void SetSettleCountCredit(long);
      long GetSettleCountDebit();
      void SetSettleCountDebit(long);
      long GetSettleCountPurchase();
      void SetSettleCountPurchase(long);
      long GetSettleCountRefund();
      void SetSettleCountRefund(long);
      BOOL GetEnableManualPan();
      void SetEnableManualPan(BOOL);
      BOOL GetEnableTopmost();
      void SetEnableTopmost(BOOL);
      CString GetDialogTitle();
      void SetDialogTitle(LPCTSTR);
      BOOL GetEnableCashoutDuplicate();
      void SetEnableCashoutDuplicate(BOOL);
      CString GetPinPadPort();
      void SetPinPadPort(LPCTSTR);
      CString GetPinPadPortList();
      void SetPinPadPortList(LPCTSTR);
      long GetCsdReservedProperty1();
      void SetCsdReservedProperty1(long);
      long GetCsdReservedProperty2();
      void SetCsdReservedProperty2(long);
      long GetCsdReservedProperty3();
      void SetCsdReservedProperty3(long);
      long GetCsdReservedProperty4();
      void SetCsdReservedProperty4(long);
      long GetSettleCardCount();
      void SetSettleCardCount(long);
      CString GetCsdReservedString1();
      void SetCsdReservedString1(LPCTSTR);
      CString GetCsdReservedString2();
      void SetCsdReservedString2(LPCTSTR);
      CString GetTotalsData();
      void SetTotalsData(LPCTSTR);
      CString GetPhoneNumber();
      void SetPhoneNumber(LPCTSTR);
      CString GetKvc();
      void SetKvc(LPCTSTR);
      CString GetPurchaseAnalysisData();
      void SetPurchaseAnalysisData(LPCTSTR);
      BOOL GetCsdReservedBool1();
      void SetCsdReservedBool1(BOOL);
      BOOL GetCsdReservedBool2();
      void SetCsdReservedBool2(BOOL);
      BOOL GetCsdReservedBool3();
      void SetCsdReservedBool3(BOOL);
      BOOL GetCsdReservedBool4();
      void SetCsdReservedBool4(BOOL);
      BOOL GetCsdReservedBool5();
      void SetCsdReservedBool5(BOOL);
      BOOL GetResetTotals();
      void SetResetTotals(BOOL);
      CString GetSvrPhoneNumber();
      void SetSvrPhoneNumber(LPCTSTR);
      CString GetSvrPhonePrefix();
      void SetSvrPhonePrefix(LPCTSTR);
      CString GetSvrTcpipAddress();
      void SetSvrTcpipAddress(LPCTSTR);
      CString GetSvrTcpipPort();
      void SetSvrTcpipPort(LPCTSTR);
      CString GetPinPadComPort();
      void SetPinPadComPort(LPCTSTR);
      CString GetPrinterName();
      void SetPrinterName(LPCTSTR);
      CString GetJournalDirectory();
      void SetJournalDirectory(LPCTSTR);
      CString GetJournalFilename();
      void SetJournalFilename(LPCTSTR);
      BOOL GetCsdReservedBool6();
      void SetCsdReservedBool6(BOOL);
      CString GetCsdReservedString3();
      void SetCsdReservedString3(LPCTSTR);
      CString GetCsdReservedString4();
      void SetCsdReservedString4(LPCTSTR);
      CString GetCsdReservedString5();
      void SetCsdReservedString5(LPCTSTR);
      long GetTraceFileSizeLimit();
      void SetTraceFileSizeLimit(long);
      CString GetTraceFileName();
      void SetTraceFileName(LPCTSTR);
      CString GetPrintSystem();
      void SetPrintSystem(LPCTSTR);
      CString GetCsdReservedString6();
      void SetCsdReservedString6(LPCTSTR);
      CString GetRrn();
      void SetRrn(LPCTSTR);
      CString GetAddress();
      void SetAddress(LPCTSTR);
      CString GetCardName();
      void SetCardName(LPCTSTR);
      CY GetAmtCash();
      void SetAmtCash(const CY&);
      CY GetAmtCreditLimit();
      void SetAmtCreditLimit(const CY&);
      CY GetAmtTip();
      void SetAmtTip(const CY&);
      CY GetAmtPurchase();
      void SetAmtPurchase(const CY&);

// Operations
public:
      void DoReset();
      void DoCardSwipe();
      void DoChequeVerify();
      void DoControlPanel();
      void DoDisplayStatus();
      void DoGetLastReceipt();
      void DoGetLastTransaction();
      void CsdReservedMethod1();
      void CsdReservedMethod2();
      void DoInvokeApplet(LPCTSTR Applet);
      void DoLogon();
      void DoQueryCard();
      void DoReprintReceipt();
      void CsdReservedMethod3();
      void CsdReservedMethod4();
      void DoSelfTest();
      void DoSettlementCutover();
      void DoSettlementEnquiry();
      void DoSettlementReconcile();
      void DoStatus();
      void DoTransaction();
      void CsdReservedMethod5();
      void CsdReservedMethod6();
      void DoSoftwareDownload();
      void DoSoftwareActivate();
      void DoJournalViewer();
      void DoSetupPinPad();
      void DoShowDialog(BOOL Show);
      void DoSettlement();
      void DoDisplaySettlement();
      void CsdReservedMethod7();
      void CsdReservedMethod8();
      void CsdReservedMethod9();
      void DoConfigMerchant();
      void DoSetFocus(BOOL EnableFocus);
      void DoSetAutoLogonTime();
      void DoTestComms();
      void DoGetPending();
      void AboutBox();
};

Avatar of mahesh1402
mahesh1402
Flag of India image

Before creating / using any controls in your win32 app make a call to CoInitialize(NULL) in your application. This initializes the COM library on the current thread.

http://msdn2.microsoft.com/en-us/library/ms678543.aspx
e.g.

CoInitialize(NULL);  // Initializes the COM Runtime

//Code....

CoUninitialize(); // Uninitialize COM Runtime

-MAHESH
Better to put  CoInitialize(NULL); on your application's InitInstance() function and CoUninitialize(); on ExitInstance().

-MAHESH
Avatar of philsmicronet

ASKER

So this is in the vc++ application or the MFC Dll?
I added

      CoInitialize(NULL);  // Initializes the COM Runtime
 into my InitInstance but it failed to compile

Identifier unknown. Is there a .h file i need?
Header: Declared in objbase.h.
Avatar of jkr
With MFC, you should actually use

#include <afxdisp.h>

AfxOleInit();

instead.
with win32 :

#ifndef _WIN32_DCOM
#define _WIN32_DCOM
#endif

#include <objbase.h>  // CoInitializeEx, CoUninitialize

-MAHESH

if you receive any linker errors add ole32.lib to your libraries to link

- #include <objbase.h> in your stdafx.h file.

- Define _WIN32_DCOM in your list of Preprocessor definitions.
  (Project Settings->C/C++ : Preprocess definitions)

- If you have link problems, be sure to add ole32.lib in your list of libraries to link  
  to. (Project Settings->Link : Object/Library modules)

-MAHESH
Cool. That all worked properly. Thanks

My problem now is that after creating the activex control and sending it an instruction, when I return back to my C app, the program locks up (just in the end of the MFC function). Is it possible to use activex controls without mfc
>>Is it possible to use activex controls without mfc

Yes it is ! MFC is mostly a wrapper around Win32 functions.

Just thing is it is much easier to do with MFC.

-MAHESH
Silly question really. What i meant was how to do it. Has anyone got some code that I can use to do it.
ASKER CERTIFIED SOLUTION
Avatar of mahesh1402
mahesh1402
Flag of India image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
however before goin with this long way first you may just look into why your application fails. Post some more details about code line on which this actually fails along with runtime errors if any.

-MAHESH
The code is as above but with the following change

I added

lpeftpos->DoLogon() which tells the pinpad to log onto the bank.

This returns straight away, but when this function exits, it locks up completely in some MFC code.
>> it locks up completely in some MFC code.

Have you tried to debug, or able to locate exactly which line it locksup....you may also set MessageBoxes in your code to trace that.

-MAHESH
When I trace the cleanup its in ~CWnd()

The line is

delete m_pCtrlCont

Also my code is

      window.Attach(hParent);
      lpeftpos->Create(NULL,WS_VISIBLE, eftrect, &window, EFTID);
      lpeftpos->DoLogon();
      window.Detach();

I do this because to create the ActiveX control I am using the Create command which takes a CWnd class as the first parameter. But from the C applications I am passing in a window handle hParent. Is this correct? I do the detach cause otherwise the function would crash before returning
Try to call CoFreeUnusedLibraries() after finish using your control.

-MAHESH
I havent finished with them yet. I wanted to leave the control open and continue to use it. The control is used to access an eftpos pinpad. So we would create the control, then logon to the bank, then send the purchase amount and wait for a result code.
My assumption was that as you are using DLL then if in case your DLL remains active in the memory you may have run time errors.. So you may use CoFreeUnusedLibraries() to free them.

-MAHESH
Hi. Its still doing the same thing. Any ideas?