|
hope someone can help
im converting a c dll to an activex control (apparently the users cant figure out how to use a dll in vb) and have managed to get most of it functioning in a skeletal kind of way ... what im stuck with is the data
the code reads data from an external source within the activex and ive made it store it in an internal buffer ... i cant seem to get access to the data from vb ... i keep getting an error along the lines of "data type not supported by visual basic"
my question is ... what data type should i use to read and store raw byte data in the activex such that it can be read by the vb app?
thnx
"there is no spoon" biz stuff about me
|
|
|
|
|
l a u r e n wrote:
what data type should i use to read and store raw byte data in the activex such that it can be read by the vb app?
Basically any type defined by OLE Automation. That includes standard Microsoft types, but also those that you have defined in IDL. This is assuming that your client is Visual Basic, and not VBScript. VBScript is utterly lame and will only handle standard OLE types and enums, AFAIK.
How are you exposing your data? Arrays? Linked lists? Structures?
Good music: In my rosary[^]
|
|
|
|
|
hi jorgen
i looked thru the available types but didnt see a BYTE type thing ... did i miss it? in terms of exposing the data from the control to the VB client app im basically making the data a property of the control ... they can call a ReadData method to "refresh" the data from the source and there will be a WriteData method to send modified data back to the source
essentially it is 256 bytes of raw data
"there is no spoon" biz stuff about me
|
|
|
|
|
VB understands the BYTE type, but it sounds like you are passing a byte array, not a byte. Have you tried declaring the parameter as a SAFEARRAY??
|
|
|
|
|
|
Damn. rwestgraham beat me to it.
You will want to stuff the safearray into a VARIANT though, which you pass between C++ and VB. IDL supports a special safearray syntax, but VB doesn't understand it.
Good music: In my rosary[^]
|
|
|
|
|
ok hmmmmm now u lost me ... i thought variants were single variables so how can i stuff an array into one?
if im being dumb just tell me and i'll stop asking dumb questions
"there is no spoon" biz stuff about me
|
|
|
|
|
Not dumb, this stuff is complicated. I tested the below code in VC++6/VB6 and it worked.
ATL/C++ Server Code:
***************************************************************************
STDMETHODIMP CVBArray::GetVBArray(VARIANT *MyArray)
{
//Create a sample byte array and initialize with zeros
//256 is small, so don't bother creating on the heap
unsigned char bytearray[256] = {0};
//Declare a pointer to the byte array
unsigned char* pbytearray = bytearray;
//Set every other byte to 1
for(int i = 0; i <256; i+=2)
{
bytearray[i] = 1;
}
//Now comes the fun part!!!!
//Call VariantInit to initialize our return parameter
VariantInit(MyArray);
//Set the type of the return paramter to VT_UI1
//VB will recognize VT_UI1 as an unsigned char i.e. byte
MyArray->vt = VT_ARRAY| VT_UI1;
//Declare a pointer for a SAFEARRAY
SAFEARRAY* psa;
//Declare a SAFEARRAYBOUND and initialize it to the correct size
SAFEARRAYBOUND bounds = {sizeof(bytearray), 0};
//Create the SAFEARRAY using the type, dimension, and array length
psa = SafeArrayCreate(VT_UI1, 1, &bounds);
//Declare a null pointer for access to the SAFEARRAY's array
void* pSafeArrayData = NULL;
//Now set the pointer to the SAFEARRAY array (must be cast as void**)
SafeArrayAccessData(psa, (void**)(&pSafeArrayData));
//Let's review: We now have a local byte array populated with data.
//We also now have a SAFEARRAY object with a data buffer the size of our byte array.
//We have created a pointer for the SAFEARRAY's data buffer.
//We have "unlocked" the SAFEARRAY's data buffer and set our pointer to it
// by calling SafeArrayAccessData.
//Now all we need to do is copy our local data into the SAFEARRAY data buffer
// the clean up and return.
//Copy bytearray into SAFEARRAY buffer
memcpy(pSafeArrayData, pbytearray, sizeof(bytearray));
pbytearray = NULL;
//"Lock" the SAFEARRAY.
SafeArrayUnaccessData(psa);
//Set the SAFEARRAY we just created and populated to the return parameter.
MyArray->parray = psa;
//Now we are ready to return
return S_OK;
}
**************************************************************************
VB Code:
**************************************************************************
Private Sub GetArrayFromCOM()
Dim oServer As New vbArray
Dim testItems() As Byte
Dim i As Long
Dim count As Long
Dim strShow As String
testItems = oServer.GetVBArray
count = UBound(testItems)
For i = 0 To count
strShow = strShow & " " & CStr(testItems(i))
Next i
MsgBox strShow
End Sub
*****************************************************************************
|
|
|
|
|
|
And he beat me to it again! Jeez, I need to stop seeing women, because obviously they're taking up too much of my time..
To make rwestgraham's story short, it's the vt field of the variant which holds the secret. If you give it the value of VT_UI1|VT_ARRAY you can stuff a BYTE-safearray into it. You can even stuff structures (VT_RECORD ) in there too, should you ever have feel masochistic.
Good music: In my rosary[^]
|
|
|
|
|
Jörgen Sigvardsson wrote:
And he beat me to it again!
My dev machine crashed on Monday, I've been using that as an excuse to screw around doing nothing but surf the web, LOL.
Jörgen Sigvardsson wrote:
I need to stop seeing women, because obviously they're taking up too much of my time..
I need to start seeing women, LOL. If you spend as much time with women as I spend masturbating, I envy you. :->
|
|
|
|
|
rwestgraham wrote:
If you spend as much time with women as I spend masturbating, I envy you.
release and go query some woman's interface. Beats addrefing yourself. Just finding the right interface is fun as it is!
Good music: In my rosary[^]
|
|
|
|
|
Actually, I have a live in. But these days I'm more interested in querying some IUnknowns, LOL. Just gotta make sure you use MarshalByLatex before you insert your stub into some strange proxy. :->
|
|
|
|
|
Hi!
I´m reading a Excel-Sheet by calling the Excel-COM-Object with the following code:
Excel.Application ExcelObj = new Excel.Application();
Excel.Workbook theWorkbook = ExcelObj.Workbooks.Open(filename, false, true, 5, "", "", true, Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, true, true);
Excel.Sheets sheets = theWorkbook.Worksheets;
Excel.Worksheet worksheet = (Excel.Worksheet)sheets.get_Item(sheetNumber);
for (int i = startRow; i <= endRow; i++)
{
Excel.Range range = worksheet.get_Range(startCol + i.ToString(), endCol + i.ToString());
System.Array myvalues = (System.Array)range.Cells.Value2;
string[] strArray = ConvertToStringArray(myvalues);
storage.Add(strArray);
}
ExcelObj.Quit();
My problem is, that Excel does not really quit but stay in my task-manager.
What do i have to do to make Excel to leave my memory?
Thanks!
|
|
|
|
|
Hello:
I am developping my first COM project , that in fact is an attempt to split a previous project into a client and a COM server. Since I'm not very experienced in this field, I'm having linking errors when trying to compile the server:
winComServer.cpp
Linking...
winComServer_i.obj : error LNK2005: _CLSID_CoServer already defined in winComServer.obj
winComServer_i.obj : error LNK2005: _LIBID_WINCOMSERVERLib already defined in winComServer.obj
winComServer_i.obj : error LNK2005: _IID_ICoServer already defined in winComServer.obj
I have been reading several forums about this kind of problems with no possitive results.
I'm NOT including "initguid.h" from "stdafx.h", that seems to be a source of problems.
Any help would be really welcomed.
Jose M
-- modified at 9:13 Monday 12th September, 2005
|
|
|
|
|
I have solved the problem:
I had changed my precompiled headers settings. I must use them in order to make the app works.
Sorry guys, no winners this time. Next time you shoud be faster .
Jose M
|
|
|
|
|
Hi,
I have tried to show an ActiveX Control on a Window in SDI application. I used the following API,
CLSID clsid; //clsid of activex control
IUnknown* pIunknown;
HRESULT hResult;
hResult = CoCreateInstance( clsid, NULL,
CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
IID_IUnknown, (void**)&pIunknown );
But still the Control is not display.......
Where lies the Error? Can anyone help me out?
-- modified at 5:31 Monday 12th September, 2005
|
|
|
|
|
Friends,
I want to develop a ActiveX control container,and save data in flat(uncompound) document.
My document CxxDoc is derived from COleDocument,and the constructor as following:
CxxDoc::CxxDoc()
{
// EnableCompoundFile();
// ^^^^^^^^^^^^^^^^^^^^^^^^^^I need a flat (uncompound) file.so i delete it.
...
}
Firstly, Is it OK????Can i save data in flat document?
Secondly,my client item is CxxClientItem,
class CxxClientItem : public COleClientItem
The WriteItem and ReadItem function (copied from the sample program of ActiceX control test container in Visual C++) as follows. They can work correctly in compound document. Please tell me how to change them from compound document to flat(uncompound) document. I'm a new and I do need your help.
void CxxClientItem::WriteItem( CArchive& ar )
{
USES_CONVERSION;
IStoragePtr pStorage;
IStreamPtr pStream;
IPersistStreamInitPtr pPSI;
TCHAR szItemName[64];
HRESULT hResult;
IPersistStoragePtr pPersistStorage;
CxxDoc* pDoc;
CLSID clsid;
(void)ar;
pDoc = GetDocument();
ASSERT_VALID( pDoc );
ASSERT( pDoc->m_lpRootStg != NULL );
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^It is wrong in uncompound document
ASSERT( pDoc->m_bCompoundFile );
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^It is wrong in uncompound document
ASSERT( m_lpStorage != NULL );
ASSERT( !ar.m_bForceFlat );
GetItemName( szItemName );
if( !pDoc->m_bSameAsLoad )
{
hResult = pDoc->m_lpRootStg->CreateStorage( T2COLE( szItemName ),STGM_CREATE|STGM_READWRITE|STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE, 0, 0, &pStorage );
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^It is wrong in uncompound document
if( FAILED( hResult ) )
{
AfxThrowOleException( hResult );
}
m_lpNewStorage = pStorage;
m_lpNewStorage->AddRef();
m_bNeedCommit = TRUE;
}
else
{
pStorage = m_lpStorage;
}
......
}
void CxxClientItem::ReadItem( CArchive& ar )
{
USES_CONVERSION;
BOOL tUsedStream;
IStoragePtr pStorage;
IPersistStreamInitPtr pPSI;
IStreamPtr pStream;
TCHAR szItemName[64];
HRESULT hResult;
BOOL tQuickActivated;
IPersistStoragePtr pPersistStorage;
CLSID clsid;
(void)ar;
CxxDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
ASSERT(pDoc->m_lpRootStg != NULL);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^It is wrong in uncompound document
ASSERT(pDoc->m_bCompoundFile);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^It is wrong in uncompound document
ASSERT(m_lpStorage == NULL);
ASSERT(m_lpLockBytes == NULL);
ASSERT( !ar.m_bForceFlat );
// get item name
GetItemName( szItemName );
// open storage for this item
hResult = pDoc->m_lpRootStg->OpenStorage( T2COLE( szItemName ), NULL,
STGM_READWRITE|STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE, 0, 0, &pStorage );
// ^^^^^^^^^^^^^^^^^^^^^^^^^^It is wrong in uncompound document
if( hResult != S_OK )
{
TRACE1( "Warning: unable to open child storage %s.\n", szItemName );
// upon failure throw file exception (item will be cleaned up)
AfxThrowOleException( hResult );
}
ASSERT(pStorage != NULL);
// remember the storage
m_lpStorage = pStorage;
ASSERT(m_lpStorage != NULL);
m_lpStorage->AddRef();
......
}
|
|
|
|
|
Can someone please tell me more or less how Microsoft updates your OS over the internet? I know they call API's through ActiveX but how do they do it?
Illegal Operation
Making Computer Software Talk
|
|
|
|
|
When I am into the STA or MTA threads, how can I check at runtime whether I am STA or MTA thread..
|
|
|
|
|
i'm wonder whether CComPtr<ixxxx> is equal with IXXXPtr(raw interface wrapper class)?
for example:
Excel::_ApplicationPtr spApp;
HRESULT hr = spApp.CreateInstance(L"Excel.Application"); // this will succeed
//CComPtr<Excel::_Application> spApp;
//HRESULT hr = spApp.CoCreateInstance(L"Excel.Application"); //this will fail
i guess in most cases this should be equal ,right?
-- modified at 2:24 Thursday 8th September, 2005
|
|
|
|
|
Hi,
I have stumbled upon an issue which I am failing to resolve..
Basically I have an outproc COM server (.exe) which exposes a couple of interfaces which are
bridged to inproc COM objects, .dll's). One of the inproc objects is interfacing with a serial port, this works like a charm with my test application (not using the outproc COM server directly, but instead using the inproc COM objects) but when using the outproc COM server (.exe) as the call-gateway
I am unable to open up the serial ports...
The problem is to open the serial port(s)...
Everything runs on the local machine, administrator accounts, WinXP SP2..
Very "fuzzy" description, however..
|
Application | .exe COM Server - inProc objects <-> serial port
| (not a service)
No impersonation code has been done, everything is most plain (i.e. no tricks applied)
Any ideas ?
// Fredrik
|
|
|
|
|
Hi,
I am using a third party COM component to connect to a remote SSH server. For this I have created a STA thread. Now I have a trivial user scenario, when the user issues a connect command a modal dialog is shown with a cancel button to display the status of connection. At anytime the user can press cancel button to abort the operation. Since the calls to cancel/abort are generally asynchronous the actual call to disconnect comes from a different STA thread. Now the problem I am facing is that the after the user clicks the cancel button the dialog is not getting disposed away and the thread is not stopping, thus my application hangs. If I attach a debugger to the release build of the application, the application breaks in the debugger with Invalid RtlHeapAddress. Initially I though it could be a problem of directly accessing my interface pointer, so I marshalled the interface pointer using GlobalInterfaceTable, yet the result is the same.
After some debugging I found that the call to Connect is not returning at all, to be on a safer side I have a message loops in my all STA threads.
How do I make sure that my dialog is disposed properly and my STA thread also stops properly.
I am using VC++ 6.0 for developing my application. The COM part is implemented using pure C++
Thanks
|
|
|
|
|
I want to write a service which will notify if any new file is generated in particular directory. How can i trap this event in Atl service
|
|
|
|
|