473,394 Members | 2,020 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,394 software developers and data experts.

Can I use Pinvoke for a dll that calls a COM component?

I have a program that originally compiles into a exe file. I changed the
compile option to generate dll file. This program calls a com component.
Can I use pinvoke in C# to call it? The following is the main dll file.

#include "stdafx.h"

#define MAX_ADSPATH_CHARS 2048

//************************************************** *************************
// local function prototypes
//************************************************** *************************

int LocalToWideChar(LPWSTR pWide, LPCTSTR pLocal, DWORD dwChars);

/************************************************** *************************

_tmain()

************************************************** *************************/
using namespace std;

__declspec(dllexport) void ShowAdProp(WCHAR* inPath)
{
wstring adPath = inPath;

CoInitialize(NULL);

HRESULT hr;

HINSTANCE hInstance = NULL;
HWND hwndConsole = GetConsoleWindow();
if(hwndConsole)
{
hInstance = (HINSTANCE)(LONG_PTR)GetWindowLongPtr(hwndConsole,
GWLP_HINSTANCE);
}

CPropSheetHost *pHost = new CPropSheetHost(hInstance);

// Hold a reference count for the CPropSheetHost object.
pHost->AddRef();

hr = pHost->SetObject(adPath.c_str());
if(FAILED(hr))
{
goto ExitMain;
}

pHost->Run();

/*
Release the CPropSheetHost object. Other components may still hold a
reference to the object, so this cannot just be deleted here. Let
the object delete itself when all references are released.
*/
pHost->Release();
ExitMain:

CoUninitialize();
}

/************************************************** ************************

LocalToWideChar()

************************************************** ************************/

int LocalToWideChar(LPWSTR pWide, LPCTSTR pLocal, DWORD dwChars)
{
*pWide = 0;

#ifdef UNICODE
lstrcpyn(pWide, pLocal, dwChars);
#else
MultiByteToWideChar( CP_ACP,
0,
pLocal,
-1,
pWide,
dwChars);
#endif

return lstrlenW(pWide);
}
--
Thanks.
Jul 17 '06 #1
6 2191
Pucca,

You could, but this seems like really messy design. Why not export the
CPropSheetHost class as a COM object?
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Pucca" <Pu***@discussions.microsoft.comwrote in message
news:D7**********************************@microsof t.com...
>I have a program that originally compiles into a exe file. I changed the
compile option to generate dll file. This program calls a com component.
Can I use pinvoke in C# to call it? The following is the main dll file.

#include "stdafx.h"

#define MAX_ADSPATH_CHARS 2048

//************************************************** *************************
// local function prototypes
//************************************************** *************************

int LocalToWideChar(LPWSTR pWide, LPCTSTR pLocal, DWORD dwChars);

/************************************************** *************************

_tmain()

************************************************** *************************/
using namespace std;

__declspec(dllexport) void ShowAdProp(WCHAR* inPath)
{
wstring adPath = inPath;

CoInitialize(NULL);

HRESULT hr;

HINSTANCE hInstance = NULL;
HWND hwndConsole = GetConsoleWindow();
if(hwndConsole)
{
hInstance = (HINSTANCE)(LONG_PTR)GetWindowLongPtr(hwndConsole,
GWLP_HINSTANCE);
}

CPropSheetHost *pHost = new CPropSheetHost(hInstance);

// Hold a reference count for the CPropSheetHost object.
pHost->AddRef();

hr = pHost->SetObject(adPath.c_str());
if(FAILED(hr))
{
goto ExitMain;
}

pHost->Run();

/*
Release the CPropSheetHost object. Other components may still hold a
reference to the object, so this cannot just be deleted here. Let
the object delete itself when all references are released.
*/
pHost->Release();
ExitMain:

CoUninitialize();
}

/************************************************** ************************

LocalToWideChar()

************************************************** ************************/

int LocalToWideChar(LPWSTR pWide, LPCTSTR pLocal, DWORD dwChars)
{
*pWide = 0;

#ifdef UNICODE
lstrcpyn(pWide, pLocal, dwChars);
#else
MultiByteToWideChar( CP_ACP,
0,
pLocal,
-1,
pWide,
dwChars);
#endif

return lstrlenW(pWide);
}
--
Thanks.

Jul 17 '06 #2
If I do that then do I use COM interop to invoke CPropSheetHost, the COM
object, directly from my C# program?
--
Thanks.
"Nicholas Paldino [.NET/C# MVP]" wrote:
Pucca,

You could, but this seems like really messy design. Why not export the
CPropSheetHost class as a COM object?
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Pucca" <Pu***@discussions.microsoft.comwrote in message
news:D7**********************************@microsof t.com...
I have a program that originally compiles into a exe file. I changed the
compile option to generate dll file. This program calls a com component.
Can I use pinvoke in C# to call it? The following is the main dll file.

#include "stdafx.h"

#define MAX_ADSPATH_CHARS 2048

//************************************************** *************************
// local function prototypes
//************************************************** *************************

int LocalToWideChar(LPWSTR pWide, LPCTSTR pLocal, DWORD dwChars);

/************************************************** *************************

_tmain()

************************************************** *************************/
using namespace std;

__declspec(dllexport) void ShowAdProp(WCHAR* inPath)
{
wstring adPath = inPath;

CoInitialize(NULL);

HRESULT hr;

HINSTANCE hInstance = NULL;
HWND hwndConsole = GetConsoleWindow();
if(hwndConsole)
{
hInstance = (HINSTANCE)(LONG_PTR)GetWindowLongPtr(hwndConsole,
GWLP_HINSTANCE);
}

CPropSheetHost *pHost = new CPropSheetHost(hInstance);

// Hold a reference count for the CPropSheetHost object.
pHost->AddRef();

hr = pHost->SetObject(adPath.c_str());
if(FAILED(hr))
{
goto ExitMain;
}

pHost->Run();

/*
Release the CPropSheetHost object. Other components may still hold a
reference to the object, so this cannot just be deleted here. Let
the object delete itself when all references are released.
*/
pHost->Release();
ExitMain:

CoUninitialize();
}

/************************************************** ************************

LocalToWideChar()

************************************************** ************************/

int LocalToWideChar(LPWSTR pWide, LPCTSTR pLocal, DWORD dwChars)
{
*pWide = 0;

#ifdef UNICODE
lstrcpyn(pWide, pLocal, dwChars);
#else
MultiByteToWideChar( CP_ACP,
0,
pLocal,
-1,
pWide,
dwChars);
#endif

return lstrlenW(pWide);
}
--
Thanks.


Jul 17 '06 #3
Hi Pucca,
Yes, if you create a COM object, you can simply add a reference to it
from your C# program, and then call methods on it directly from C#. No
pinvoke required.
John

Pucca wrote:
If I do that then do I use COM interop to invoke CPropSheetHost, the COM
object, directly from my C# program?
--
Thanks.
"Nicholas Paldino [.NET/C# MVP]" wrote:
Pucca,

You could, but this seems like really messy design. Why not export the
CPropSheetHost class as a COM object?
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Pucca" <Pu***@discussions.microsoft.comwrote in message
news:D7**********************************@microsof t.com...
>I have a program that originally compiles into a exe file. I changed the
compile option to generate dll file. This program calls a com component.
Can I use pinvoke in C# to call it? The following is the main dll file.
>
#include "stdafx.h"
>
#define MAX_ADSPATH_CHARS 2048
>
//************************************************** *************************
// local function prototypes
//************************************************** *************************
>
int LocalToWideChar(LPWSTR pWide, LPCTSTR pLocal, DWORD dwChars);
>
/************************************************** *************************
>
_tmain()
>
************************************************** *************************/
>
>
using namespace std;
>
__declspec(dllexport) void ShowAdProp(WCHAR* inPath)
{
wstring adPath = inPath;
>
CoInitialize(NULL);
>
HRESULT hr;
>
HINSTANCE hInstance = NULL;
HWND hwndConsole = GetConsoleWindow();
if(hwndConsole)
{
hInstance = (HINSTANCE)(LONG_PTR)GetWindowLongPtr(hwndConsole,
GWLP_HINSTANCE);
}
>
CPropSheetHost *pHost = new CPropSheetHost(hInstance);
>
// Hold a reference count for the CPropSheetHost object.
pHost->AddRef();
>
hr = pHost->SetObject(adPath.c_str());
if(FAILED(hr))
{
goto ExitMain;
}
>
pHost->Run();
>
/*
Release the CPropSheetHost object. Other components may still hold a
reference to the object, so this cannot just be deleted here. Let
the object delete itself when all references are released.
*/
pHost->Release();
>
>
ExitMain:
>
CoUninitialize();
}
>
/************************************************** ************************
>
LocalToWideChar()
>
************************************************** ************************/
>
int LocalToWideChar(LPWSTR pWide, LPCTSTR pLocal, DWORD dwChars)
{
*pWide = 0;
>
#ifdef UNICODE
lstrcpyn(pWide, pLocal, dwChars);
#else
MultiByteToWideChar( CP_ACP,
0,
pLocal,
-1,
pWide,
dwChars);
#endif
>
return lstrlenW(pWide);
}
>
>
--
Thanks.
Jul 18 '06 #4
I bought a book on COM and .Net but it looked really complicated and a very
thick book. I thought pinvok would be easier. But from your reply it seems
quite simple. Do you know of any sample code that I can look to see how it's
done?

Thanks.
--
Thanks.
"John Duval" wrote:
Hi Pucca,
Yes, if you create a COM object, you can simply add a reference to it
from your C# program, and then call methods on it directly from C#. No
pinvoke required.
John

Pucca wrote:
If I do that then do I use COM interop to invoke CPropSheetHost, the COM
object, directly from my C# program?
--
Thanks.
"Nicholas Paldino [.NET/C# MVP]" wrote:
Pucca,
>
You could, but this seems like really messy design. Why not export the
CPropSheetHost class as a COM object?
>
>
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com
>
"Pucca" <Pu***@discussions.microsoft.comwrote in message
news:D7**********************************@microsof t.com...
I have a program that originally compiles into a exe file. I changed the
compile option to generate dll file. This program calls a com component.
Can I use pinvoke in C# to call it? The following is the main dll file.

#include "stdafx.h"

#define MAX_ADSPATH_CHARS 2048

//************************************************** *************************
// local function prototypes
//************************************************** *************************

int LocalToWideChar(LPWSTR pWide, LPCTSTR pLocal, DWORD dwChars);

/************************************************** *************************

_tmain()

************************************************** *************************/


using namespace std;

__declspec(dllexport) void ShowAdProp(WCHAR* inPath)
{
wstring adPath = inPath;

CoInitialize(NULL);

HRESULT hr;

HINSTANCE hInstance = NULL;
HWND hwndConsole = GetConsoleWindow();
if(hwndConsole)
{
hInstance = (HINSTANCE)(LONG_PTR)GetWindowLongPtr(hwndConsole,
GWLP_HINSTANCE);
}

CPropSheetHost *pHost = new CPropSheetHost(hInstance);

// Hold a reference count for the CPropSheetHost object.
pHost->AddRef();

hr = pHost->SetObject(adPath.c_str());
if(FAILED(hr))
{
goto ExitMain;
}

pHost->Run();

/*
Release the CPropSheetHost object. Other components may still hold a
reference to the object, so this cannot just be deleted here. Let
the object delete itself when all references are released.
*/
pHost->Release();


ExitMain:

CoUninitialize();
}

/************************************************** ************************

LocalToWideChar()

************************************************** ************************/

int LocalToWideChar(LPWSTR pWide, LPCTSTR pLocal, DWORD dwChars)
{
*pWide = 0;

#ifdef UNICODE
lstrcpyn(pWide, pLocal, dwChars);
#else
MultiByteToWideChar( CP_ACP,
0,
pLocal,
-1,
pWide,
dwChars);
#endif

return lstrlenW(pWide);
}


--
Thanks.
>
>
>

Jul 18 '06 #5
Hi Pucca,
Hopefully you're not starting with Adam Nathan's book. It's a really
good book, mind you, but not for beginners.

Anyway, here are some steps that should get you going. You're going to
create 2 projects -- one that implements a COM object and another that
creates & calls into the object. There's a lot of ways to do this, but
here is one that should work for you.

Hope this helps,
John

To create a sample COM object:

1) In VS2005, pick File -new project
2) Under project types, select Other Languages -Visual C++ -ATL ->
ATL Project
3) Pick a project name like "SampleCOMObject" and click OK
4) When the wizard pops up, just click Finish
(you now have a shell DLL project that you can build)
5) View -Class View
(this shows you the objects in your project)
6) Right-click on SampleCOMObject in the class view pane and pick Add
-Class
7) In the Add Class dialog, pick Visual C++ -ATL -ATL Simple
Object and click Add
8) In the ATL Simple Object Wizard, fill in the short name like
"MyCOMObject" and click Finish
(you will now see CMyCOMObject in the class view pane)
9) Right-click on the IMyCOMObject **interface** (looks like a
lollipop) in the class view pane, and pick Add -Add Method
10) In the Add Method Wizard, enter a method name like "MyTestMethod"
11) In the Add Method Wizard, enter a parameter with type BSTR and a
name like "MyParam"
12) Click Add to add the parameter, then finish to add the method
(you could have added more parameters, but let's do one for
simplicity)
12) You can now add your code inside the MyTestFunction method
(I just added a line that says "Beep(440, 500);" so I know it got
there)
13) Build the project
(this step will build and register a type library (TLB) that can be
referenced from your C# program)
To call the COM object from a C# project:

1) In VS2005 pick File -new project
(you don't need to close the SampleCOMObject C++ project)
2) Pick a project type and name (I chose Visual C# Console
Application, "SampleCOMClient")
3) In the Solution Explorer, go to the SampleCOMClient project,
right-click References -Add Reference
4) Click on the COM tab, select "SampleCOMObject 1.0 Type Library" and
click OK
5) Now you can just call the method directly from C# like this:

using System;
using System.Collections.Generic;
using System.Text;

using SampleCOMObjectLib;

namespace SampleCOMClient
{
class Program
{
static void Main(string[] args)
{
string theParameter = "hi there";
MyCOMObjectClass test = new MyCOMObjectClass();
test.MyTestMethod(theParameter);
}
}
}
Pucca wrote:
I bought a book on COM and .Net but it looked really complicated and a very
thick book. I thought pinvok would be easier. But from your reply it seems
quite simple. Do you know of any sample code that I can look to see how it's
done?

Thanks.
--
Thanks.
"John Duval" wrote:
Hi Pucca,
Yes, if you create a COM object, you can simply add a reference to it
from your C# program, and then call methods on it directly from C#. No
pinvoke required.
John

Pucca wrote:
If I do that then do I use COM interop to invoke CPropSheetHost, the COM
object, directly from my C# program?
--
Thanks.
>
>
"Nicholas Paldino [.NET/C# MVP]" wrote:
>
Pucca,

You could, but this seems like really messy design. Why not export the
CPropSheetHost class as a COM object?


--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Pucca" <Pu***@discussions.microsoft.comwrote in message
news:D7**********************************@microsof t.com...
>I have a program that originally compiles into a exe file. I changed the
compile option to generate dll file. This program calls a com component.
Can I use pinvoke in C# to call it? The following is the main dll file.
>
#include "stdafx.h"
>
#define MAX_ADSPATH_CHARS 2048
>
//************************************************** *************************
// local function prototypes
//************************************************** *************************
>
int LocalToWideChar(LPWSTR pWide, LPCTSTR pLocal, DWORD dwChars);
>
/************************************************** *************************
>
_tmain()
>
************************************************** *************************/
>
>
using namespace std;
>
__declspec(dllexport) void ShowAdProp(WCHAR* inPath)
{
wstring adPath = inPath;
>
CoInitialize(NULL);
>
HRESULT hr;
>
HINSTANCE hInstance = NULL;
HWND hwndConsole = GetConsoleWindow();
if(hwndConsole)
{
hInstance = (HINSTANCE)(LONG_PTR)GetWindowLongPtr(hwndConsole,
GWLP_HINSTANCE);
}
>
CPropSheetHost *pHost = new CPropSheetHost(hInstance);
>
// Hold a reference count for the CPropSheetHost object.
pHost->AddRef();
>
hr = pHost->SetObject(adPath.c_str());
if(FAILED(hr))
{
goto ExitMain;
}
>
pHost->Run();
>
/*
Release the CPropSheetHost object. Other components may still hold a
reference to the object, so this cannot just be deleted here. Let
the object delete itself when all references are released.
*/
pHost->Release();
>
>
ExitMain:
>
CoUninitialize();
}
>
/************************************************** ************************
>
LocalToWideChar()
>
************************************************** ************************/
>
int LocalToWideChar(LPWSTR pWide, LPCTSTR pLocal, DWORD dwChars)
{
*pWide = 0;
>
#ifdef UNICODE
lstrcpyn(pWide, pLocal, dwChars);
#else
MultiByteToWideChar( CP_ACP,
0,
pLocal,
-1,
pWide,
dwChars);
#endif
>
return lstrlenW(pWide);
}
>
>
--
Thanks.

Jul 18 '06 #6
John, thank you so much. That's what I want to know how to do quickly. I
bouth 2 very thick books on this subject and you have summarize what I need
in 2 pages in simple steps. I can't thank you enough for you help. I
followed the steps and the sample worked great!

I have codes from the SDK that originally complie to an application.exe file
and I need to modify it to a COM dll. I would really appreicate it if you or
someone can help me out with this. The program has 1 .cpp file that calls
the COM object and the rest of the .h and .cpp files all belongs to the COM
object. I execluded that .cpp file and modify the project property option to
output dll file however, it's not putting out the type library that I can add
reference to in my other project so I can do COM interop.

//The file that I execulded
//************************************************** *************************
//
//************************************************** *************************

//************************************************** *************************
//
// File: Main.cpp
//
// Description:
//
//************************************************** *************************

//************************************************** *************************
// #include statements
//************************************************** *************************

#include "stdafx.h"

#define MAX_ADSPATH_CHARS 2048

//************************************************** *************************
// local function prototypes
//************************************************** *************************

int LocalToWideChar(LPWSTR pWide, LPCTSTR pLocal, DWORD dwChars);

/************************************************** *************************

_tmain()

************************************************** *************************/
//int _tmain(int argc, _TCHAR* argv[])
//{
// TCHAR szTemp[MAX_ADSPATH_CHARS];
// LPWSTR pwszADsPath = NULL;
//
// CoInitialize(NULL);
//
// if(argc < 2)
// {
// // Prompt the user for the ADsPath.
// _tprintf(TEXT("Enter the ADsPath of the object to display the
property sheet for:\n"));
// _fgetts(szTemp, MAX_ADSPATH_CHARS - 1, stdin);
//
// // Trim the last character, which is the carriage return.
// szTemp[lstrlen(szTemp) - 1] = 0;
// }
// else
// {
// lstrcpyn(szTemp, argv[1], MAX_ADSPATH_CHARS - 1);
// }

using namespace std;

__declspec(dllexport) void ShowAdProp(WCHAR* inPath)
{
wstring adPath = inPath;

CoInitialize(NULL);

HRESULT hr;

HINSTANCE hInstance = NULL;
HWND hwndConsole = GetConsoleWindow();
if(hwndConsole)
{
hInstance = (HINSTANCE)(LONG_PTR)GetWindowLongPtr(hwndConsole,
GWLP_HINSTANCE);
}

CPropSheetHost *pHost = new CPropSheetHost(hInstance);

// Hold a reference count for the CPropSheetHost object.
pHost->AddRef();

hr = pHost->SetObject(adPath.c_str());
if(FAILED(hr))
{
goto ExitMain;
}

pHost->Run();

/*
Release the CPropSheetHost object. Other components may still hold a
reference to the object, so this cannot just be deleted here. Let
the object delete itself when all references are released.
*/
pHost->Release();
ExitMain:

CoUninitialize();
}

/************************************************** ************************

LocalToWideChar()

************************************************** ************************/

int LocalToWideChar(LPWSTR pWide, LPCTSTR pLocal, DWORD dwChars)
{
*pWide = 0;

#ifdef UNICODE
lstrcpyn(pWide, pLocal, dwChars);
#else
MultiByteToWideChar( CP_ACP,
0,
pLocal,
-1,
pWide,
dwChars);
#endif

return lstrlenW(pWide);
}

//The 2 header files
What do I need to do to get the type librarty COM reference? Thank you.
Also, below is the .cpp file I removed and the 2 .h file that came with the
SDK.
#pragma once

//************************************************** *************************
// #include statements
//************************************************** *************************

#include "stdafx.h"
#include <string>
#include <objbase.h>

//************************************************** *************************
// data type definitions
//************************************************** *************************

#define VIEW_POINTER_OFFSET GWLP_USERDATA

#ifndef CFSTR_DS_PARENTHWND
#define CFSTR_DS_PARENTHWND_W L"DsAdminParentHwndClipFormat"
#define CFSTR_DS_PARENTHWND_A "DsAdminParentHwndClipFormat"

#ifdef UNICODE
#define CFSTR_DS_PARENTHWND CFSTR_DS_PARENTHWND_W
#else
#define CFSTR_DS_PARENTHWND CFSTR_DS_PARENTHWND_A
#endif //UNICODE
#endif //CFSTR_DS_PARENTHWND

#ifndef CFSTR_DS_PROPSHEETCONFIG
#define CFSTR_DS_PROPSHEETCONFIG_W L"DsPropSheetCfgClipFormat"
#define CFSTR_DS_PROPSHEETCONFIG_A "DsPropSheetCfgClipFormat"

#ifdef UNICODE
#define CFSTR_DS_PROPSHEETCONFIG CFSTR_DS_PROPSHEETCONFIG_W
#else
#define CFSTR_DS_PROPSHEETCONFIG CFSTR_DS_PROPSHEETCONFIG_A
#endif //UNICODE
#endif //CFSTR_DS_PROPSHEETCONFIG
#ifndef WM_ADSPROP_SHEET_CREATE
#define WM_ADSPROP_SHEET_CREATE (WM_USER + 1108)
#endif
#ifndef WM_DSA_SHEET_CREATE_NOTIFY
#define WM_DSA_SHEET_CREATE_NOTIFY (WM_USER + 6)
#endif
#ifndef WM_DSA_SHEET_CLOSE_NOTIFY
#define WM_DSA_SHEET_CLOSE_NOTIFY (WM_USER + 5)
#endif
#ifndef DSA_SEC_PAGE_INFO
typedef struct _DSA_SEC_PAGE_INFO
{
HWND hwndParentSheet;
DWORD offsetTitle;
DSOBJECTNAMES dsObjectNames;
} DSA_SEC_PAGE_INFO, *PDSA_SEC_PAGE_INFO;
#endif //DSA_SEC_PAGE_INFO

#ifndef PROPSHEETCFG
typedef struct _PROPSHEETCFG
{
LONG_PTR lNotifyHandle;
HWND hwndParentSheet;
HWND hwndHidden;
WPARAM wParamSheetClose;
} PROPSHEETCFG, *PPROPSHEETCFG;
#endif //PROPSHEETCFG

#define PROP_SHEET_HOST_ID 0xCDCDCDCD

#define PROP_SHEET_PREFIX_ADMIN L"admin"
#define PROP_SHEET_PREFIX_SHELL L"shell"

/************************************************** ************************

CPropSheetHost class definition

************************************************** ************************/

class CPropSheetHost : public IDataObject
{
private:
HWND m_hwndParent;
HWND m_hwndHidden;
DWORD m_ObjRefCount;
CComPtr<IADsm_spADObject;
ATOM m_cfDSPropSheetConfig;
ATOM m_cfDSObjectNames;
ATOM m_cfDSDispSpecOptions;
CSimpleArray<HPROPSHEETPAGEm_rgPageHandles;
LPTSTR m_szHiddenWindowClass;
HINSTANCE m_hInst;
LPWSTR m_pwszPrefix;

public:
CPropSheetHost(HINSTANCE hInstance, HWND hwndParent = NULL);
~CPropSheetHost();

public:
HRESULT SetObject(LPCWSTR pwszADsPath);
HRESULT SetObject(IADs *pads);
__declspec(dllexport) void ShowAdProp(WCHAR* inPath);
void Run();

private:
HWND _CreateHiddenWindow();
static LRESULT CALLBACK _HiddenWindowProc(HWND, UINT, WPARAM, LPARAM);
void _CreatePropertySheet();
static BOOL CALLBACK _AddPagesCallback(HPROPSHEETPAGE hPage, LPARAM
lParam);
HRESULT _AddPagesForObject(IADs *padsObject);
void _CreateSecondaryPropertySheet(DSA_SEC_PAGE_INFO *pDSASecPageInfo);
HRESULT _GetDSDispSpecOption(FORMATETC *pFormatEtc, STGMEDIUM
*pStgMedium);
HRESULT _GetDSObjectNames(FORMATETC *pFormatEtc, STGMEDIUM *pStgMedium);
HRESULT _GetDSPropSheetConfig(FORMATETC *pFormatEtc, STGMEDIUM
*pStgMedium);
HRESULT _ExtractSecPageInfo(WPARAM wParam, PDSA_SEC_PAGE_INFO
*ppSecPageInfo);

public:
//IUnknown methods
STDMETHODIMP QueryInterface(REFIID, LPVOID FAR *);
STDMETHODIMP_(DWORD) AddRef();
STDMETHODIMP_(DWORD) Release();

//IDataObject methods
STDMETHODIMP GetData(FORMATETC*, STGMEDIUM*);
STDMETHODIMP GetDataHere(FORMATETC*, STGMEDIUM*);
STDMETHODIMP QueryGetData(FORMATETC*);
STDMETHODIMP GetCanonicalFormatEtc(LPFORMATETC, LPFORMATETC);
STDMETHODIMP SetData(LPFORMATETC, LPSTGMEDIUM, BOOL);
STDMETHODIMP EnumFormatEtc(DWORD, IEnumFORMATETC**);
STDMETHODIMP DAdvise(FORMATETC*, DWORD, IAdviseSink*, LPDWORD);
STDMETHODIMP DUnadvise(DWORD dwConnection);
STDMETHODIMP EnumDAdvise(IEnumSTATDATA** ppEnumAdvise);

};
///////////////////////////////////////

#pragma once
#pragma warning(push,3)

#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>
// C RunTime Header Files
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>

// TODO: reference additional headers your program requires here
#include <commctrl.h>
#include <ole2.h>
#include <atlbase.h>
#include <shlobj.h>
#include <dsclient.h>
#include <vector>
#include <string>
#include <adsprop.h>
#include "PropSheetHost.h"

--
Thanks.
"John Duval" wrote:
Hi Pucca,
Hopefully you're not starting with Adam Nathan's book. It's a really
good book, mind you, but not for beginners.

Anyway, here are some steps that should get you going. You're going to
create 2 projects -- one that implements a COM object and another that
creates & calls into the object. There's a lot of ways to do this, but
here is one that should work for you.

Hope this helps,
John

To create a sample COM object:

1) In VS2005, pick File -new project
2) Under project types, select Other Languages -Visual C++ -ATL ->
ATL Project
3) Pick a project name like "SampleCOMObject" and click OK
4) When the wizard pops up, just click Finish
(you now have a shell DLL project that you can build)
5) View -Class View
(this shows you the objects in your project)
6) Right-click on SampleCOMObject in the class view pane and pick Add
-Class
7) In the Add Class dialog, pick Visual C++ -ATL -ATL Simple
Object and click Add
8) In the ATL Simple Object Wizard, fill in the short name like
"MyCOMObject" and click Finish
(you will now see CMyCOMObject in the class view pane)
9) Right-click on the IMyCOMObject **interface** (looks like a
lollipop) in the class view pane, and pick Add -Add Method
10) In the Add Method Wizard, enter a method name like "MyTestMethod"
11) In the Add Method Wizard, enter a parameter with type BSTR and a
name like "MyParam"
12) Click Add to add the parameter, then finish to add the method
(you could have added more parameters, but let's do one for
simplicity)
12) You can now add your code inside the MyTestFunction method
(I just added a line that says "Beep(440, 500);" so I know it got
there)
13) Build the project
(this step will build and register a type library (TLB) that can be
referenced from your C# program)
To call the COM object from a C# project:

1) In VS2005 pick File -new project
(you don't need to close the SampleCOMObject C++ project)
2) Pick a project type and name (I chose Visual C# Console
Application, "SampleCOMClient")
3) In the Solution Explorer, go to the SampleCOMClient project,
right-click References -Add Reference
4) Click on the COM tab, select "SampleCOMObject 1.0 Type Library" and
click OK
5) Now you can just call the method directly from C# like this:

using System;
using System.Collections.Generic;
using System.Text;

using SampleCOMObjectLib;

namespace SampleCOMClient
{
class Program
{
static void Main(string[] args)
{
string theParameter = "hi there";
MyCOMObjectClass test = new MyCOMObjectClass();
test.MyTestMethod(theParameter);
}
}
}
Pucca wrote:
I bought a book on COM and .Net but it looked really complicated and a very
thick book. I thought pinvok would be easier. But from your reply it seems
quite simple. Do you know of any sample code that I can look to see how it's
done?

Thanks.
--
Thanks.
"John Duval" wrote:
Hi Pucca,
Yes, if you create a COM object, you can simply add a reference to it
from your C# program, and then call methods on it directly from C#. No
pinvoke required.
John
>
Pucca wrote:
If I do that then do I use COM interop to invoke CPropSheetHost, the COM
object, directly from my C# program?
--
Thanks.


"Nicholas Paldino [.NET/C# MVP]" wrote:

Pucca,
>
You could, but this seems like really messy design. Why not export the
CPropSheetHost class as a COM object?
>
>
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com
>
"Pucca" <Pu***@discussions.microsoft.comwrote in message
news:D7**********************************@microsof t.com...
I have a program that originally compiles into a exe file. I changed the
compile option to generate dll file. This program calls a com component.
Can I use pinvoke in C# to call it? The following is the main dll file.

#include "stdafx.h"

#define MAX_ADSPATH_CHARS 2048

//************************************************** *************************
// local function prototypes
//************************************************** *************************

int LocalToWideChar(LPWSTR pWide, LPCTSTR pLocal, DWORD dwChars);

/************************************************** *************************

_tmain()

************************************************** *************************/


using namespace std;

__declspec(dllexport) void ShowAdProp(WCHAR* inPath)
{
wstring adPath = inPath;

CoInitialize(NULL);

HRESULT hr;

HINSTANCE hInstance = NULL;
HWND hwndConsole = GetConsoleWindow();
if(hwndConsole)
{
hInstance = (HINSTANCE)(LONG_PTR)GetWindowLongPtr(hwndConsole,
GWLP_HINSTANCE);
}

CPropSheetHost *pHost = new CPropSheetHost(hInstance);

// Hold a reference count for the CPropSheetHost object.
pHost->AddRef();

hr = pHost->SetObject(adPath.c_str());
if(FAILED(hr))
{
goto ExitMain;
}

pHost->Run();

/*
Release the CPropSheetHost object. Other components may still hold a
reference to the object, so this cannot just be deleted here. Let
the object delete itself when all references are released.
*/
pHost->Release();


ExitMain:

CoUninitialize();
}

/************************************************** ************************

LocalToWideChar()

************************************************** ************************/

int LocalToWideChar(LPWSTR pWide, LPCTSTR pLocal, DWORD dwChars)
{
*pWide = 0;

#ifdef UNICODE
lstrcpyn(pWide, pLocal, dwChars);
#else
MultiByteToWideChar( CP_ACP,
0,
pLocal,
-1,
pWide,
dwChars);
#endif

return lstrlenW(pWide);
}


--
Thanks.
>
>
>
>
>

Jul 19 '06 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Muthiah Samy | last post by:
Hi All, I am trying to call COM Component in .NET using PInvoke. In the following scenario, ( I am getting an exception called SEH - External component has thrown an exception) UnManaged...
2
by: RobJUK66 | last post by:
have a 3rd party .Net dll that wraps a set of further unmanaged dll's. The ..Net DLL basically uses pinvoke to wrap the calls. The low level dlls provide an API to talk to a complex device which...
2
by: Jeff Lederer | last post by:
I have created a simple test C# console program that calls an unmanaged C subroutine in a DLL where one of the arguments is a callback to the C# code. I noticed that when the callback has no...
1
by: cppdev | last post by:
Hello, After reading a few articles, http://blogs.gotdotnet.com/cbrumme/PermaLink.aspx/e55664b4-6471-48b9-b360-f0fa27ab6cc0...
1
by: Roy | last post by:
Have a dll that calls a com object. Can call dll from C program fine, can call dll from C# program in compact framework (i.e. CE/PPC devices), no problem. On XP devices when I pinvoke it gets...
3
by: Beorne | last post by:
I have a propertary library dll (used to drive a device) that I call from my C# code. Calling the functions from C++ is really faster than calling them in C+ +. From C++ the call is almost...
2
by: =?Utf-8?B?VG9tIEFsbGVu?= | last post by:
Hi, TIA for any help. (Thanks, Mattias Sjögren for your help yesterday! ) I am developing a C# wrapper for a 3rd party API. It processes buffers from a video stream (file) and is structured...
11
by: BillGatesFan | last post by:
I have a web service which calls a .NET queued serviced component in COM+. I turned statistics on for the component. I call the component 10 times, 10 objects get created but they do not go away....
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.