| Home | Forums | Reviews | Articles | Register |
![]() |
| Thread Tools | Rate Thread |
|
|
|
| |
|
Nicholas Paldino [.NET/C# MVP]
Guest
Posts: n/a
|
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] - (E-Mail Removed) "Pucca" <(E-Mail Removed)> wrote in message news 7ABEA88-A718-4E5E-A72A-(E-Mail Removed)...>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. |
|
||
|
||||
|
=?Utf-8?B?UHVjY2E=?=
Guest
Posts: n/a
|
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] > - (E-Mail Removed) > > "Pucca" <(E-Mail Removed)> wrote in message > news 7ABEA88-A718-4E5E-A72A-(E-Mail Removed)...> >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. > > > |
|
||
|
||||
|
John Duval
Guest
Posts: n/a
|
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] > > - (E-Mail Removed) > > > > "Pucca" <(E-Mail Removed)> wrote in message > > news 7ABEA88-A718-4E5E-A72A-(E-Mail Removed)...> > >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. > > > > > > |
|
||
|
||||
|
=?Utf-8?B?UHVjY2E=?=
Guest
Posts: n/a
|
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] > > > - (E-Mail Removed) > > > > > > "Pucca" <(E-Mail Removed)> wrote in message > > > news 7ABEA88-A718-4E5E-A72A-(E-Mail Removed)...> > > >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. > > > > > > > > > > > |
|
||
|
||||
|
John Duval
Guest
Posts: n/a
|
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] > > > > - (E-Mail Removed) > > > > > > > > "Pucca" <(E-Mail Removed)> wrote in message > > > > news 7ABEA88-A718-4E5E-A72A-(E-Mail Removed)...> > > > >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. > > > > > > > > > > > > > > > > |
|
||
|
||||
|
=?Utf-8?B?UHVjY2E=?=
Guest
Posts: n/a
|
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<IADs> m_spADObject; ATOM m_cfDSPropSheetConfig; ATOM m_cfDSObjectNames; ATOM m_cfDSDispSpecOptions; CSimpleArray<HPROPSHEETPAGE> m_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] > > > > > - (E-Mail Removed) > > > > > > > > > > "Pucca" <(E-Mail Removed)> wrote in message > > > > > news 7ABEA88-A718-4E5E-A72A-(E-Mail Removed)...> > > > > >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. > > > > > > > > > > > > > > > > > > > > > > > |
|
||
|
||||
|
|
|
| |
![]() |
| Thread Tools | |
| Rate This Thread | |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Web Service calls Queued Component | BillGatesFan | Microsoft C# .NET | 13 | 12th Nov 2007 08:00 PM |
| Re: PInvoke and Unmanaged DLL calls | superchink@gmail.com | Microsoft C# .NET | 0 | 24th Jul 2007 07:21 PM |
| Counting the calls INTO my component? | Robert Hooker | Microsoft Dot NET Framework | 3 | 25th May 2006 06:00 PM |
| Csharp async calls to Web Service that calls C++ :: blocking issue | Brian Parker | Microsoft C# .NET | 10 | 21st Apr 2006 03:12 AM |
| PInvoke and Unmanaged DLL calls | Joe Martin | Microsoft C# .NET | 11 | 18th Oct 2004 02:33 PM |
Powered by vBulletin®. Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2010, Crawlability, Inc. |




