Click here to Skip to main content
15,867,704 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
i have beginners on ATL programming.
i created a example program TipServer as per suggested in Inside ATL book. but while running my program its give runtime error
actually its not finding interface provided by component.

my clint program is also in VC++ and i am properlly registered my component.

please see the client code below. and please let me know where i am doing mistake.

//-----------
//TipDlg.cpp
//-----------

#include "stdafx.h"#include "resource.h"
// CG: This file added by 'Tip of the Day' component.
#include <winreg.h>
#include <sys\stat.h>
#include <sys\types.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CTipDlg dialog
#define MAX_BUFLEN 1000
static const TCHAR szSection[] = _T("Tip");
static const TCHAR szIntFilePos[] = _T("FilePos");
static const TCHAR szTimeStamp[] = _T("TimeStamp");
static const TCHAR szIntStartup[] = _T("StartUp");
static const TCHAR szCookie[] = _T("Cookie");

CTipDlg::CTipDlg(CWnd* pParent /*=NULL*/)
: CDialog(IDD_TIP, pParent)
{
//{{AFX_DATA_INIT(CTipDlg)
m_bStartup = TRUE;
//}}AFX_DATA_INIT
// We need to find out what the startup and file position parameters are
// If startup does not exist, we assume that the Tips on startup is checked TRUE.
CWinApp* pApp = AfxGetApp();
m_bStartup = !pApp->GetProfileInt(szSection, szIntStartup, 0);
vtCookie = (long)pApp->GetProfileInt(szSection, szCookie, 0);
HRESULT hResult =
m_tipOfDay.CreateInstance("TipServer.TipOfTheDay");
if(SUCCEEDED(hResult))
GetNextTipString(m_strTip);
}
CTipDlg::~CTipDlg()
{
// This destructor is executed whether the user had pressed the escape key
// or clicked on the close button. If the user had pressed the escape key,
// it is still required to update the filepos in the ini file with the
// latest position so that we don't repeat the tips!

// But make sure the tips file existed in the first place....
CWinApp* pApp = AfxGetApp();
::VariantChangeType(&vtCookie, &vtCookie, 0, VT_I4);
pApp->WriteProfileInt(szSection, szCookie, vtCookie.lVal);
}

void CTipDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CTipDlg)
DDX_Check(pDX, IDC_STARTUP, m_bStartup);
DDX_Text(pDX, IDC_TIPSTRING, m_strTip);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CTipDlg, CDialog)
//{{AFX_MSG_MAP(CTipDlg)
ON_BN_CLICKED(IDC_NEXTTIP, OnNextTip)
ON_WM_CTLCOLOR()
ON_WM_PAINT()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CTipDlg message handlers
void CTipDlg::OnNextTip()
{
GetNextTipString(m_strTip);
UpdateData(FALSE);
}
void CTipDlg::GetNextTipString(CString& strNext)
{
strNext = (BSTR)(m_tipOfDay->GetNextTip(&vtCookie));
}
HBRUSH CTipDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
if (pWnd->GetDlgCtrlID() == IDC_TIPSTRING)
return (HBRUSH)GetStockObject(WHITE_BRUSH);
return CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
}
void CTipDlg::OnOK()
{
CDialog::OnOK();

// Update the startup information stored in the INI file
CWinApp* pApp = AfxGetApp();
pApp->WriteProfileInt(szSection, szIntStartup, !m_bStartup);
}
BOOL CTipDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// If Tips file does not exist then disable NextTip
if (m_pStream == NULL)
GetDlgItem(IDC_NEXTTIP)->EnableWindow(FALSE);
return TRUE; // return TRUE unless you set the focus to a control
}
void CTipDlg::OnPaint()
{
CPaintDC dc(this); // device context for painting
// Get paint area for the big static control
CWnd* pStatic = GetDlgItem(IDC_BULB);
CRect rect;
pStatic->GetWindowRect(&rect);
ScreenToClient(&rect);
// Paint the background white.
CBrush brush;
brush.CreateStockObject(WHITE_BRUSH);
dc.FillRect(rect, &brush);
// Load bitmap and get dimensions of the bitmap
CBitmap bmp;
bmp.LoadBitmap(IDB_LIGHTBULB);
BITMAP bmpInfo;
bmp.GetBitmap(&bmpInfo);
// Draw bitmap in top corner and validate only top portion of window
CDC dcTmp;
dcTmp.CreateCompatibleDC(&dc);
dcTmp.SelectObject(&bmp);
rect.bottom = bmpInfo.bmHeight + rect.top;
dc.BitBlt(rect.left, rect.top, rect.Width(), rect.Height(),
&dcTmp, 0, 0, SRCCOPY);
// Draw out "Did you know..." message next to the bitmap
CString strMessage;
strMessage.LoadString(CG_IDS_DIDYOUKNOW);
rect.left += bmpInfo.bmWidth;
dc.DrawText(strMessage, rect, DT_VCENTER | DT_SINGLELINE);
// Do not call CDialog::OnPaint() for painting messages
}


//---------
//TipDlg.h
//---------
#if !defined(TIPDLG_H_INCLUDED_)
#define TIPDLG_H_INCLUDED_
// CG: This file added by 'Tip of the Day' component.
/////////////////////////////////////////////////////////////////////////////
// CTipDlg dialog
#import "../TipServer/TipServer.tlb" no_namespace

class CTipDlg : public CDialog
{
protected:
variant_t vtCookie;
ITipOfTheDayPtr m_tipOfDay;
// Construction
public:
CTipDlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(CTipDlg)
// enum { IDD = IDD_TIP };
BOOL m_bStartup;
CString m_strTip;
//}}AFX_DATA
FILE* m_pStream;
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CTipDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CTipDlg();
protected:
// Generated message map functions
//{{AFX_MSG(CTipDlg)
afx_msg void OnNextTip();
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
virtual void OnOK();
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
void GetNextTipString(CString& strNext);
};
#endif // !defined(TIPDLG_H_INCLUDED_)

Note: TipDlg.h is having class defination and interface import

Thanks for the help and quick responce but still i didnt get the answer
as per your suggestion i already checked registry and in registry the
"TipServer.TipOfTheDay" string is availble

for more information after debuging the program i am getting null pointer
for interface when i call my component API as below
strNext = (BSTR)(m_tipOfDay->GetNextTip(&vtCookie));

my component code is shown below
XML
// TipOfTheDay.h : Declaration of the CTipOfTheDay

#ifndef __TIPOFTHEDAY_H_
#define __TIPOFTHEDAY_H_

#include "resource.h"       // main symbols

/////////////////////////////////////////////////////////////////////////////
// CTipOfTheDay

class ATL_NO_VTABLE CTipOfTheDay : 
    public CComObjectRootEx<CComMultiThreadModel>,
    public CComCoClass<CTipOfTheDay, &CLSID_TipOfTheDay>,
    public IDispatchImpl<ITipOfTheDay, &IID_ITipOfTheDay, &LIBID_TIPSERVERLib>
{
public:
    CTipOfTheDay()
    {
    }

DECLARE_REGISTRY_RESOURCEID(IDR_TIPOFTHEDAY)

DECLARE_PROTECT_FINAL_CONSTRUCT()

BEGIN_COM_MAP(CTipOfTheDay)
    COM_INTERFACE_ENTRY(ITipOfTheDay)
    COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()

// ITipOfTheDay
public:
    STDMETHOD(GetNextTip)(/*[in, out]*/ VARIANT* pvCookie, /*[out,retval]*/ BSTR* pbstrText);
};

#endif //__TIPOFTHEDAY_H_



//------------------
// TipOfTheDay.cpp : Implementation of CTipOfTheDay
#include "stdafx.h"
#include "TipServer.h"
#include "TipOfTheDay.h"
/////////////////////////////////////////////////////////////////////////////
// CTipOfTheDay
#define TIP_COUNT 7
static LPWSTR gTipText[TIP_COUNT] =
{
L"You should avoid strangers",
L"Good things come to those who wait",
L"Lay off the code; your love life is hurting",
L"Do a good turn today",
L"You win some, you lose some",
L"COM is love?",
L"All's fair in love and war"
};

STDMETHODIMP CTipOfTheDay::GetNextTip(VARIANT *pvCookie, BSTR * pbstrText)
{
if(!pvCookie || !pbstrText)
return E_POINTER;
::VariantChangeType(pvCookie, pvCookie, 0, VT_I4);
if(pvCookie->lVal < 0 || pvCookie->lVal >= TIP_COUNT)
return E_INVALIDARG;
*pbstrText = SysAllocString(gTipText[pvCookie->lVal]);
if(++(pvCookie->lVal) == TIP_COUNT)
pvCookie->lVal = 0;
return S_OK;
}


Hi,

I have debuged it.
CreateInstance defination is provided by VC98\Include\COMIP.H file
looks like below

HRESULT CreateInstance(LPCSTR clsidStringA, IUnknown* pOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) throw()
{
if (clsidStringA == NULL) {
return E_INVALIDARG;
}
int size = lstrlenA(clsidStringA) + 1;
LPOLESTR clsidStringW = static_cast<LPOLESTR>(_alloca(size * 2));
clsidStringW[0] = '\0';
if (MultiByteToWideChar(CP_ACP, 0, clsidStringA, -1, clsidStringW, size) == 0) {
return HRESULT_FROM_WIN32(GetLastError());
}
return CreateInstance(clsidStringW, pOuter, dwClsContext);
}

CreateInstance function internally calling CoCreateInstance as shown below.

hr = CoCreateInstance(rclsid, pOuter, dwClsContext, __uuidof(IUnknown), reinterpret_cast<void**>(&pIUnknown));

here i am getting correct class ID (i.e. rclsid) but the function is failed to get the instance of class that why its not calling QueryInterface and i am not getting the interface pointer.
but issue is why i am not getting the instance?
may be i am doing some silly mistake.

Thanks again for help ;)


-----------------

CoCreateInstance returned hr = 0x800401F0 (CoInitialize has not been called. )
Posted
Updated 24-Feb-10 0:03am
v7

1 solution

Please analyze or post here
the value of hr after the call :)
 
Share this answer
 
v4

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900