|
Hello,
I have a class that contains a Shell Folder and PIDL. The class instances live in the .Tag of TreeView and ListView items. When a Drag containing file/directory information (as in dragged from Windows Explorer) is over or drops on one of the TreeViewNodes, I want to respond using the IDropTarget Interface of the Folder represented by my class instance.
My problem is that I cannot get the IDropTarget Interface to work. I suspect that I have either mis-defined it or have omitted some vital step prior to using it.
Specifics:
<ComImportAttribute(), _
InterfaceType(ComInterfaceType.InterfaceIsIUnknown), _
Guid("00000122-0000-0000-C000-000000000046")> _
Public Interface IDropTarget
<PreserveSig()> _
Function DragEnter( _
ByVal pDataObj As System.Windows.Forms.IDataObject, _
ByVal grfKeyState As Integer, _
ByVal pt As POINT, _
ByRef pdwEffect As System.Windows.Forms.DragDropEffects) _
As Integer
<PreserveSig()> _
Function DragOver( _
ByVal grfKeyState As Integer, _
ByRef pt As POINT, _
ByRef pdwEffect As System.Windows.Forms.DragDropEffects) _
As Integer
<PreserveSig()> _
Function DragLeave()
<PreserveSig()> _
Function DragDrop( _
ByVal pDataObj As System.Windows.Forms.IDataObject, _
ByVal grfKeyState As Integer, _
ByRef pt As POINT, _
ByRef pdwEffect As System.Windows.Forms.DragDropEffects) _
As Integer
End Interface
Note: I am only calling DragEnter so far in my code.
Where POINT is declared:
<StructLayout(LayoutKind.Sequential)> _
Public Structure POINT
Dim x As Integer
Dim y As Integer
End Structure
The part that seems to work:
... code that sets up relPidl ...
Dim apidl(0) as IntPtr
apidl(0) = relPidl
Dim Eff As Integer
Dim theInterface As IDropTarget
Dim HR As Integer
HR = Me.Parent.m_Folder.GetUIObjectOf(IntPtr.Zero, 1, apidl, ShellDll.IID_IDropTarget, Eff, theInterface)
If HR <> 0 Then
Marshal.ThrowExceptionForHR(HR)
End If
Note: m_Folder is the shell Folder interface of the Folder that contains the Folder of interest. Folder & PIDL code has been working for months, though this is the first time I've used GetUIObjectOf. In any event the returned item is a System_ComObject, just like I expect.
The part that doesn't work:
... e is a System.Windows.Forms.DragEventArgs with valid data..
for example the DragEventArgs generated by dragging from Windows Explorer ...
...The target is a normal Windows directory reporting .IsDropTarget among its attributes ...
Dim IDrop As IDropTarget = target.GetDropTargetOf()
If Not IsNothing(IDrop) Then
Dim scrpt As New ShellDll.POINT()
scrpt.x = e.X
scrpt.y = e.Y
Dim eff As DragDropEffects = e.AllowedEffect
Try
Dim res As Integer = IDrop.DragEnter(CType(e.Data, IDataObject), e.KeyState, scrpt, eff)
Catch ex As Exception
Debug.WriteLine(ex.ToString)
End Try
System.Runtime.InteropServices.Marshal.ReleaseComObject(IDrop)
End If
Always throws a NullReference exception after reporting:
A first chance exception of type 'System.NullReferenceException' occurred in exptreelib.dll
Additional information: Object reference not set to an instance of an object.
I strongly suspect some kind of Marshalling problem on the return from IDropTarget, but I will believe any explanation that works.
Thanks
Jim Parsells
|
|
|
|
|
I have a custom ActiveX control that serves as a container for a store-bought ActiveX control. My problem is that I need to access the properties and methods of the store-bought control (call it an instrument) from the parent application.
The sequence of events is that the parent application creates instances of my container (basically just a jazzy group box) and then sends a message telling my group box which instrument to create. This works fine, but now I need to "control" the instrument.
I have successfully gotten an IDispatch* for the instrument and returned it to the parent application, but I see no clean way to invoke methods or set properties on the instrument. The issue is that I want to make legible calls of the form
(Instrument*)p->InstrumentMethod(). I have found no way to avoid some horiffic canned mapping of the numeric DISPID's of the instrument. The main application is extremely large, and legibility and maintainability will go to zero if I have to use Invoke() instead of just calling the instrument method.
As an alternative, I have tried to pass a CWnd* property, but I have two worries about this. First, I see no obvious way (other than trickery) to pass a CWnd* as a COM Property. Second, I am highly doubtful that the CWnd* will be valid throughout the lifetime of my group box.
HHHEEEEEEEEEEEEEEEEEEEEELLLLLLLLLLLLLLLLLLLLLLLLLLLLPPPPPPPPPPPPPPPPPPPPPPPPPPP!
Regards,
David Hamilton
|
|
|
|
|
Urgent Bump.
Regards,
David Hamilton
|
|
|
|
|
Hey everyone, I'm a little stuck with this and this is my fist question on these boards, and any advice anyone could give would be greatly appreciated
So basically, I have these two COM components that share memory using a MapViewOfFile object... like so:
-----------------------------------------------------------------
In the "server" component:
HANDLE hBlockMap;
...
hBlockMap = CreateFileMapping((HANDLE)0xFFFFFFFF, NULL,
PAGE_READWRITE, 0,
sizeof(Block), "SharedBlockMemory");
In the "client" component:
HANDLE hBlockMap;
...
hBlockMap = ::OpenFileMapping(FILE_MAP_WRITE, FALSE, "SharedBlockMemory");
-----------------------------------------------------------------
I also have a simple "Block" object, just to test sharing data, which looks like this:
-----------------------------------------------------------------
class Block
{
public:
void Write(char* msg);
char* Read();
int getSize() { return n_size; }
Block();
~Block();
private:
BYTE* data;
int n_size;
};
and just the Write and Read methods:
void Block::Write(char* msg, int size)
{
data = new BYTE[strlen(msg) + 1];
memcpy(data, (BYTE* )msg, strlen(msg));
n_size = size;
}
char* Block::Read(int size)
{
char* result = new char[n_size + 1];
memcpy(result, (char* )data, n_size);
return result;
}
-----------------------------------------------------------------
So basically, my problem is this:
The Write and Read methods both actually "work", and by that I mean I'm not getting any wierd memory access violations... If I expand the write method to check and make sure its writing, like so,
void Block::Write(char* msg)
{
...
n_size = size;
char* check = new char[strlen(msg) + 1];
memcpy(check, (char* )data, strlen(msg));
check[strlen(msg)] = '\0';
cout << check << endl;
delete[] check;
}
It outputs the correct string. However, no matter what I seem to do, the Read method just outputs garbage... I'm completely mystified, because if I change, in the Block class, the definition of data to
BYTE data[250];
and then change my Write and Read method to deal with that accordingly, I get the correct output in the Read method. But if use BYTE* data, I just get garbage...
Am I just missing something small, maybe some syntactical error? I haven't programmed in C++ as much lately, and I wouldn't put that myself, but I'm fairly sure my code dealing with the pointers and copying memory is correct... Or is it something else, could I be using the MapViewOfFile incorrectly?
And also, here is an example of how I read from it, just to demonstrate that access to the shared memory is synchronized (using a seperate mutex)...
-----------------------------------------------------------------
class CMemoryMgr : public IMemoryServer,
public IMemoryClient
{
public:
...
private:
Block* c_Block;
...
};
void __stdcall CMemoryMgr::TPF_PrintMessage()
{
if(::WaitForSingleObject(hBlockMutex, 5000L) == WAIT_OBJECT_0)
{
cout << c_Block->Read(c_Block->getSize());
cout << endl;
::ReleaseMutex(hBlockMutex);
}
}
-----------------------------------------------------------------
Also, the reason I want to dynamically allocate the data array is because I will be developing a customized circular buffer, and I want to be able to allow data of any reasonable size to be enqueued, so thats why I'm trying to stay away from a fixed array size.
Anyway, thank you all for reading my problem!
Like I said, any advice would be greatly appreciated
|
|
|
|
|
I think your problem may be related to different heap spaces used on Read\Write context.
Just change the new\delete operators to a allocator that uses the main process heap like: CoTaskMemAlloc and CoTaskMemFree.
I hope it help.
GuimaSun
www.nexsun.com.br
NEXSUN TechZone
|
|
|
|
|
Look the following code:
hr = pVC->QueryInterface(IID_IPropertyBag, (void **)&pBag);
if(FAILED(hr))
{
MessageBox(NULL,TEXT("Creating IPropertyBag object failed!"),NULL,MB_OK);
return FALSE;
}
The return value shows that pVC doesn't support IPropertyBag interface.Now I just wanna know how can I find the right interface that support the IPropertyBag.Thanks a lot!
My email is siwlyfe@hotmail.com.Please send your idea to me and also we can discuss it by MSN.Thanks again!
pig head xiaoma
|
|
|
|
|
1. Please check the exact HRESULT value returned. Dont just think that if FAILED(hr) suceeded then IPropertyBag is not supported. There could be some other reason for failure as well.
2. If pVC->QueryInterface(IID_IPropertyBag, (void **)&pBag) fails then the component you are accessing pVC doesn't support IPropertyBag interface. Thus even from another interface of this component you will never reach IPropertyBag (Please see the rules for implementing Query Interface)
Have a great day ahead!
Regards,
Sohail Kadiwala
(My Blog - http://blogs.wdevs.com/sohail/[^])
modified 21-Apr-21 21:01pm.
|
|
|
|
|
Look the following code:
hr = pVC->QueryInterface(IID_IPropertyBag, (void **)&pBag);
if(FAILED(hr))
{
MessageBox(NULL,TEXT("Creating IPropertyBag object failed!"),NULL,MB_OK);
return FALSE;
}
The return value shows that pVC doesn't support IPropertyBag interface.Now I just wanna know how can I find the right interface that support the IPropertyBag.Thanks a lot!
My email is siwlyfe@hotmail.com.Please send your idea to me and also we can discuss it by MSN.Thanks again!
判断返回值结果:pPropertyBag不支持IPropertyBag接口,那么我现在想知道如何能查到哪个接口的对象
支持IPropertyBag接口,怎么来查?
打扰,多谢
pig head xiaoma
|
|
|
|
|
I have created a basic MFC ActiveX control using the VS wizard. I added one stock event, the MouseMove event. The problem is that for whatever reason the MouseMoveEvent is constantly fired wether the mouse is actually being moved or not. I have tested this with both VS.NET 2003 and beta 2 of VS.NET 2005. Both with the same weird behaviour.
I have also tried to manually call the FireMouseMove() in COleControl with the same result. As soon as I call FireMouseMove() once I keep getting MouseMoveEvent's. Does anybody have a clue what is going on?
Thanks,
Jan
We are the all singing, all dancing crap of the world. - Tyler Durden
|
|
|
|
|
Without creating a control ,can i provide activex scripting for my
mfc application.please refer the web sites so that i can learn from the
scratch...i need step by step learning with suitable examples
|
|
|
|
|
hi
is it possible to send a BSTR to a method expecting _bstr_t?
thank you?
|
|
|
|
|
Yes. _bstr_t is a c++ wrapper class for handling BSTR.
Please check the _bstr_t constructors documentation in MSDN.
Have a great day ahead!
Regards,
Sohail Kadiwala
(My Blog - http://blogs.wdevs.com/sohail/[^])
modified 21-Apr-21 21:01pm.
|
|
|
|
|
Hello pardis,
Here's a simple example program to illustrate it :
#include <windows.h>
#include <comdef.h>
#include <iostream>
void Function01(_bstr_t bst)
{
std::cout << (char*)bst << "\r\n";
}
int main()
{
BSTR bstr01 = ::SysAllocString(L"Hello World.");
Function01(bstr01);
if (bstr01)
{
::SysFreeString(bstr01);
bstr01 = NULL;
}
return 0;
}
The BSTR defined in main() (i.e. bstr01) is treated by the compiler as a "const wchar_t*" when it enters Function01().
Next, the compiler will take the const wchar_t* and use it as the parameter to the version of the _bstr_t constructor that takes a "const wchar_t*". The resultant _bstr_t object is "bst".
The std::cout stuff is just to demonstrate a usage of the "bst" object.
Hope the above will be helpful,
Bio.
|
|
|
|
|
|
I need to develop an application that will export a DataGrid to Excel. But for compatibility reasons, it can't be anything later than Excel 2000. I have Office XP on my machine. I need to get hold of the Excel.dll version 9 (as far as I know that is the 2000 compatible one). I downloaded one from a sample article I found, but when I try to reference it in my project, I get an error that says 'Only assemblies with extension 'dll' and COM components can be referenced. Strange that, since it is a dll. Does anyone know where I can get hold of a legit version of this dll and how I can make it work. I searched on msdn.microsoft.com – to no avail. I'm also looking for a decent reference about the object's properties, methods etc.
Any help would be greatly appreciated.
|
|
|
|
|
Hello All,
I am trying to develop a VB6 application in which I have used spreadsheet component.Now I want to copy data from an external excel file to the spreadsheet component inside the form. What are the possible ways
|
|
|
|
|
i have developed a VC++ application hosting Dhtml Edit Control inside which i have placed ActiveX control.
Activex control are basically customized buttons in html page that i have loaded in Dhtml edit control.
I have successfuly captured Dhtml Events in VC++ when simple html page is loaded.
when i load the html page with the Activex control my visual applicaiton is unable to capture the events.
I want to capture ActiveX events which is hosted in Dhtml Edit Contol, in my VC++ applications.
BOOL CDOMGeneralSubs::EstablishConnectionPoint
(IDispatch * dom,IDispatch*pHTMLElementEventsHandler)
{
// AfxMessageBox( "in EstablishConnectionPoints" );
BOOL bRet=FALSE;
IConnectionPointContainer*pConnectionPointContainer;
HRESULT Result=dom->QueryInterface(IID_IConnectionPointContainer,(void**)&pConnectionPointContainer);
if(SUCCEEDED(Result))
{
IConnectionPoint*pConnectionPoint;
Result=pConnectionPointContainer->FindConnectionPoint(DIID_HTMLDocumentEvents,&pConnectionPoint);
if(SUCCEEDED(Result))
{
DWORD Cookie=0;
Result=pConnectionPoint->Advise(pHTMLElementEventsHandler,&Cookie);
if(SUCCEEDED(Result))
bRet=TRUE;
pConnectionPoint->Release();
}
pConnectionPointContainer->Release();
}
return bRet;
}
STDMETHODIMP XSZone::CHTMLElementEvents::Invoke(
DISPID dispIdMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS FAR* pDispParams,
VARIANT FAR* pVarResult,
EXCEPINFO FAR* pExcepInfo,
unsigned int FAR* puArgErr
)
{
// AfxMessageBox( "in Invoke" );
switch (dispIdMember)
{
case DISPID_HTMLELEMENTEVENTS_ONMOUSEDOWN:
{
return This()->OnHTMLEventClick();
}
break;
}
return E_NOTIMPL;
}
STDMETHODIMP XSZone::OnHTMLEventClick()
{
//AfxMessageBox("in OnHTMLEventClick" );
MSHTML::IHTMLDocument2Ptr spIHTMLDocument2(m_wndDHTMLEdit.GetDom());
// m_wndDHTMLEdit is a instanse of DHTMLEdit Control
MSHTML::IHTMLElementPtr spElement = spIHTMLDocument2->parentWindow->event->srcElement;
CString strElementId = (LPCTSTR)(spElement->id);
Enjoy programming and pray for me.
|
|
|
|
|
Hello, I'm pretty new to using COM and have run into a problem. I have a large structure, consisting of integers, user defined enumerations, several sub-structures and several dynamic arrays. How can I send this user defined type though COM? I'm trying to write my .idl file now to accept this structure... what needs to be done?
My struct is much larger, but this small example should be enough to get me on the right track.
//Example Struct:
typedef struct
{
int index1;
Image_Struct *Image_List;
} My_Struct;
//Image_Struct definition
typedef struct
{
float pixel_x;
float pixel_y;
float pixel_z;
} Image_Struct;
Thank you!
|
|
|
|
|
Take a look at this article on Code Project.
http://www.codeproject.com/atl/udtdemo.asp
Human beings were not meant to sit in little cubicles staring at computer screens all day, filling out useless forms and listening to eight different bosses drone on about about mission statements. -- Peter Gibbons
|
|
|
|
|
Hello ChemmieBro,
You basically have to define your structs as User-Defined Types (UDT) in your IDL file. Listed below are examples of My_Struct and Image_Struct defined as UDTs :
typedef
[
uuid(C1B33DAB-A011-41ca-83E0-A7F5AEB01E52),
version(1.0),
helpstring("Image_Struct")
]
struct Image_Struct // Image_Struct definition
{
[helpstring("X pixel position.")] float pixel_x;
[helpstring("Y pixel position.")] float pixel_y;
[helpstring("Z pixel position.")] float pixel_z;
} Image_Struct;
typedef
[
uuid(AC11F3A5-855D-495d-B9CF-17EBA35ACC79),
version(1.0),
helpstring("My_Struct")
]
struct My_Struct // Example Struct
{
[helpstring("index.")] int index1;
[helpstring("The Image_Struct struct.")] Image_Struct* Image_List;
} My_Struct;
It is important that the UDT has got a GUID defined for it. This is defined in the "typedef" attribute for the struct.
Also important is that all your fields -should- be (but not necessarily) automation-compatible types. Only so will your UDT be usable in VB.
After this is done, define your interface and methods normally. Include My_Struct and/or Image_Struct types as parameters as per normal.
Listed below is an example interface that refers to My_Struct :
[
object,
uuid(8F75662A-3CC4-42D1-8F2F-0C98E42594A6),
dual,
helpstring("IImageStructProcessor Interface"),
pointer_default(unique)
]
interface IImageStructProcessor : IDispatch
{
[id(1), helpstring("method ProcessMyStruct")] HRESULT ProcessMyStruct([in, out] My_Struct* pMyStruct);
[id(2), helpstring("method FreeMyStructContents")] HRESULT FreeMyStructContents([in] My_Struct* pMyStruct);
};
I have created some working example codes based on My_Struct, Image_Struct and the IImageStructProcessor interface.
Send an email to me if you want a copy of the example codes. My email address is :
bio_lim_2004@yahoo.com
Best Regards,
Bio.
|
|
|
|
|
Hi Bio,
u seem quite activity in this COM section, have seen quite a few of your reply while I was searching for a solution to my problem. Hope you can help me with this.
In your reply earlier,
Lim Bio Liong wrote:
Also important is that all your fields -should- be (but not necessarily) automation-compatible types. Only so will your UDT be usable in VB.
So does this works for enum also? I think the initial question also include enum as on of the data type. I am also hoping to use some enum in my COM DLL. If it works for enum also, can other languages using my DLL be able to use this struct. Because I was hoping my COM DLL will works with as my languages as possible and not just VB only.
Truth is not always popular, but it is always right.
|
|
|
|
|
Hello w_logan,
>> So does this works for enum also?
Yes. It works also for enum. The following is an example of how to define an automation-compatible enum in IDL :
typedef [uuid(B5051CD9-A577-451b-BDD8-17AC68ED27BB)]
enum
{
enum_value_0 = 0,
enum_value_1 = 1,
enum_value_2 = 2,
enum_value_3 = 3
} EnumValue;
Yes, the "typedef" keyword and the "uuid" attribute is necessary for proper definition of the enum type so that it is automation-compatible.
Thereafter, you may include EnumValue as a type that can be used in your automation-compatible struct, e.g. :
typedef
[
uuid(1F2AFC9C-2ACB-4fc3-A415-8E0736B3C4BB),
version(1.0),
helpstring("My_Struct_VB_2")
]
struct My_Struct_VB_2 // Example Struct
{
[helpstring("index.")] int index1;
[helpstring("The Image_Struct struct.")] Image_Struct Image_List;
[helpstring("EnumValue value.")] EnumValue ev1;
} My_Struct_VB_2;
>> can other languages using my DLL be able to use this struct. Because I was hoping my COM DLL will works with as my languages as possible and not just VB only.
This very much depends on the language's IDE. VB and the Visual C# IDE do support most if not all of the automation-compatible IDL constructs. I haven't used Delphi or the other language IDEs yet so I wouldn't be able to comment on those.
Send me an email and I can send you my sample program.
Best Regards,
Bio.
|
|
|
|
|
Is there a function that creates a GUID froma string, similar to what StringFromGUID2 does but the other way round?
|
|
|
|
|
You can use
RPC_STATUS RPC_ENTRY UuidFromString(<br />
unsigned char* StringUuid,<br />
UUID* Uuid<br />
);
taken from Platform SDK Help.
|
|
|
|
|
Hi,
We have a MFC/VC++ application. We are using a active x button control in our application. I want to get control ID/Window ID(not handle) from the activeX control. How it is possible?.
Thanks & Regards,
Gopalakrishnan
" Action without vision is only passing time,
Vision without action is merely day dreaming,
But vision with action can change the world "
- Words from Nelson Mandela
Thanks & Regards,
Gopalakrishnan
|
|
|
|
|