MFC DLL being called from Win 32 App

Posted on 2007-08-02
Last Modified: 2013-12-14
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:

2. My MFC Application
CCsdEft *lpeftpos = NULL;

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

      lpeftpos = new CCsdEft;

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

void InitialisePCEftpos(HWND hParent)

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

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

3. My MFC Application Class
class CPCEftposApp : public CWinApp

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


4. The EFTPOS class which is copied from a sample demo program
class CCsdEft : public CWnd
      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
      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
      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();

Question by:philsmicronet
    LVL 22

    Expert Comment

    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.

    CoInitialize(NULL);  // Initializes the COM Runtime


    CoUninitialize(); // Uninitialize COM Runtime

    LVL 22

    Expert Comment

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

    LVL 1

    Author Comment

    So this is in the vc++ application or the MFC Dll?
    LVL 1

    Author Comment

    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?
    LVL 22

    Expert Comment

    Header: Declared in objbase.h.
    LVL 86

    Expert Comment

    With MFC, you should actually use

    #include <afxdisp.h>


    LVL 22

    Expert Comment

    with win32 :

    #ifndef _WIN32_DCOM
    #define _WIN32_DCOM

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


    LVL 22

    Expert Comment

    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)

    LVL 1

    Author Comment

    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
    LVL 22

    Expert Comment

    >>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.

    LVL 1

    Author Comment

    Silly question really. What i meant was how to do it. Has anyone got some code that I can use to do it.
    LVL 22

    Accepted Solution

    CoCreateInstance() -- construct an instance of the control and its a win32 API function. You may create object of your control using this.

    Following may be relavant for you :
    How to create/use COM components in plain C, without MFC, ATL, WTL, or any other framework.

    However you have option to use ATL without MFC.

    LVL 22

    Expert Comment

    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.

    LVL 1

    Author Comment

    The code is as above but with the following change

    LVL 1

    Author Comment

    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.
    LVL 22

    Expert Comment

    >> it locks up completely in some MFC code.

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

    LVL 1

    Author Comment

    When I trace the cleanup its in ~CWnd()

    The line is

    delete m_pCtrlCont

    Also my code is

          lpeftpos->Create(NULL,WS_VISIBLE, eftrect, &window, EFTID);

    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
    LVL 22

    Expert Comment

    Try to call CoFreeUnusedLibraries() after finish using your control.

    LVL 1

    Author Comment

    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.
    LVL 22

    Expert Comment

    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.

    LVL 1

    Author Comment

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

    Featured Post

    IT, Stop Being Called Into Every Meeting

    Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

    Join & Write a Comment

    Suggested Solutions

    Introduction: Database storage, where is the exe actually on the disc? Playing a game selected randomly (how to generate random numbers).  Error trapping with try..catch to help the code run even if something goes wrong. Continuing from the seve…
    Entering time in Microsoft Access can be difficult. An input mask often bothers users more than helping them and won't catch all typing errors. This article shows how to create a textbox for 24-hour time input with full validation politely catching …
    THe viewer will learn how to use NetBeans IDE 8.0 for Windows to perform CRUD operations on a MySql database.
    This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.

    745 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    16 Experts available now in Live!

    Get 1:1 Help Now