[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

MFC DLL being called from Win 32 App

Posted on 2007-08-02
22
Medium Priority
?
521 Views
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:
                  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();
};

0
Comment
Question by:philsmicronet
  • 11
  • 9
21 Comments
 
LVL 22

Expert Comment

by:mahesh1402
ID: 19616375
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
0
 
LVL 22

Expert Comment

by:mahesh1402
ID: 19616390
Better to put  CoInitialize(NULL); on your application's InitInstance() function and CoUninitialize(); on ExitInstance().

-MAHESH
0
 
LVL 1

Author Comment

by:philsmicronet
ID: 19616505
So this is in the vc++ application or the MFC Dll?
0
Veeam Disaster Recovery in Microsoft Azure

Veeam PN for Microsoft Azure is a FREE solution designed to simplify and automate the setup of a DR site in Microsoft Azure using lightweight software-defined networking. It reduces the complexity of VPN deployments and is designed for businesses of ALL sizes.

 
LVL 1

Author Comment

by:philsmicronet
ID: 19616534
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?
0
 
LVL 22

Expert Comment

by:mahesh1402
ID: 19616559
Header: Declared in objbase.h.
0
 
LVL 86

Expert Comment

by:jkr
ID: 19616692
With MFC, you should actually use

#include <afxdisp.h>

AfxOleInit();

instead.
0
 
LVL 22

Expert Comment

by:mahesh1402
ID: 19616760
with win32 :

#ifndef _WIN32_DCOM
#define _WIN32_DCOM
#endif

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

-MAHESH

0
 
LVL 22

Expert Comment

by:mahesh1402
ID: 19616952
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
0
 
LVL 1

Author Comment

by:philsmicronet
ID: 19621505
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
0
 
LVL 22

Expert Comment

by:mahesh1402
ID: 19622597
>>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
0
 
LVL 1

Author Comment

by:philsmicronet
ID: 19622685
Silly question really. What i meant was how to do it. Has anyone got some code that I can use to do it.
0
 
LVL 22

Accepted Solution

by:
mahesh1402 earned 1500 total points
ID: 19622710
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.
http://www.codeproject.com/com/com_in_c1.asp

However you have option to use ATL without MFC.

-MAHESH
0
 
LVL 22

Expert Comment

by:mahesh1402
ID: 19623326
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
0
 
LVL 1

Author Comment

by:philsmicronet
ID: 19623503
The code is as above but with the following change

0
 
LVL 1

Author Comment

by:philsmicronet
ID: 19623504
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.
0
 
LVL 22

Expert Comment

by:mahesh1402
ID: 19623518
>> 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
0
 
LVL 1

Author Comment

by:philsmicronet
ID: 19624084
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
0
 
LVL 22

Expert Comment

by:mahesh1402
ID: 19624651
Try to call CoFreeUnusedLibraries() after finish using your control.

-MAHESH
0
 
LVL 1

Author Comment

by:philsmicronet
ID: 19628938
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.
0
 
LVL 22

Expert Comment

by:mahesh1402
ID: 19636398
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
0
 
LVL 1

Author Comment

by:philsmicronet
ID: 19658171
Hi. Its still doing the same thing. Any ideas?
0

Featured Post

How to Use the Help Bell

Need to boost the visibility of your question for solutions? Use the Experts Exchange Help Bell to confirm priority levels and contact subject-matter experts for question attention.  Check out this how-to article for more information.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A theme is a collection of property settings that allow you to define the look of pages and controls, and then apply the look consistently across pages in an application. Themes can be made up of a set of elements: skins, style sheets, images, and o…
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.
The viewer will learn how to use and create new code templates in NetBeans IDE 8.0 for Windows.

873 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