|
For question #1, maybe. It depends on how your data is stored. You can get a void * back from the safearray, then cast it to the type, the memcpy it:
void *pData;
SafeArrayAccessData(sa,&pData);
memcpy((LPBYTE)pData,pMyByteArray,sizeof(BYTE)*numElements);
or something similar.
Question 2:
This gets trickier. Different schools of thought:
1.) don't do that. Define the struct in IDL, define the interface to return those (say, maybe an Item property with an index).
2.) Someone has a gun to your head and says they'll kill you if you don't (only acceptable reason to do it this way): Create an array of variants. Each variant then in and of itself contains a safearray of bytes, which is one element in your array of structs. Version 2 of this, create a variant that is an array of bytes and memcpy the whole thing.
If this is for something production, I highly suggest doing something different than blobbing it. It's much more extensible to have a collection interface that returns interfaces for each structure your defining:
ActiveX Control
|
|----- property Item([in]long index, [out,retval] IStruct **ppIStruct)
interface IStruct
|
|--- property name
|--- property address
etc etc, mapping a property value in IStruct to the value of your structure.
If your using something like ATL, you might want to look at a tear-off interface for implementing this. Just a thought.
|
|
|
|
|
Thx!
I am very happy by your answers! But I must admit that I dont follow you all the time! I am quite new to c++.
Would you mind to give me a short example on the memcpy stuff? For instance how to do it with an array of doubles, and then send it to client?
And regarding question 2, you say; "Each variant then in and of itself contains a safearray of bytes, which is one element in your array of structs."
Why should it contain bytes and not doubles for instance?
Last question; How would a code snipp for the idl look like?
Lets say I have the following stucture:
Code:
typedef struct somePoints{
int a,b,c;
} MY_STRUCT;
I have the "somePoints" elements arranged in an array and have this get method;
Code:
MY_STRUCT *getArrayP(void)
{
return arrayP;
}
So by using CComSafeArray, how would you send this array?
So far I have been iterating through the struct elements one by one, and then inserting a, b and then c. By doing is this way I feel that I put a lot of responsibility on the client, because he has to know that element i*3+0 is my a, i*3+1 is b and i*3+2 is c.
Any way of improving this, at least making it easier for client?
Cheers
|
|
|
|
|
Well, it's extremely uncommon to have a structure with uniform data types. Most structs are more like
struct
{
int value;
float fvalue;
short somethingElse;
etc., etc.
}
Now, for your case, I'd do one of two approaches. The big question is do you have to support scripting environments?
Option 1) Using the interface
Define the structure in IDL. This looks pretty much identical to you C structure definition.
Define a method that returns these:
For instance, in your IDL
struct MY_STRUCT{
long a;
long b;
long c;
};
//as a method on your COM object
[propget, id(1)] HRESULT Item([in[ Index,[out,retval] struct MyDataType* blah);
And implement from there.
Option 2) Using a big safearray
Create a safearray of variants (one for each structure), then each variant is a safearray of VT_I4. It's up to your client to know what the order of each value means, which means that this approach is fairly brittle.
|
|
|
|
|
Thanks! This helped me a lot!
Now this is hopefully my last post to this thread!
Lets say I have the following code on client:
<br />
CComVariant varArray;<br />
<br />
my_readCtrl.getArray(&varArray);<br />
<br />
<br />
if(varArray.vt==VT_I1) {<br />
CComSafeArray <char> saFromVariant;<br />
}<br />
else if(varArray.vt==VT_R8) {<br />
CComSafeArray <double> saFromVariant;<br />
}<br />
<br />
saFromVariant.Attach (varArray.parray);<br />
This results in an compilation error since saFromVariant is not declared. That is obviously because the declarations are inside if statements. How to avoid this but still declared it correct?
Thx
|
|
|
|
|
I think I want to go for option 1 here.
Can you show me how to write the code for the idl stuff?
Thanks
|
|
|
|
|
Hello!
I wrote an application, which use one or two cameras.
This application can render the camera streams on the display,
make AVIS or make BITMAPS.
What I like to have:
- Grab n different BITMAPS
- Grab different BITMAPS from start to stop
I need an event, “new BITMAP in the camera buffer available”.
Thank you
Baumann Tobias
|
|
|
|
|
Check the documentation for the camera software to see if it sends any kind of event, or if the bitmaps are being placed into a specific location on disk, you can set up a change notifier (and poll as a fallback) to detect when new bitmaps are available.
Peace!
-=- James If you think it costs a lot to do it right, just wait until you find out how much it costs to do it wrong! Avoid driving a vehicle taller than you and remember that Professional Driver on Closed Course does not mean your Dumb Ass on a Public Road! DeleteFXPFiles & CheckFavorites (Please rate this post!)
|
|
|
|
|
What do you mean by different bitmaps? Are these webcams?
|
|
|
|
|
I have a program that sends an email if a certain alarm condition arises. Currently, the email only contains a text message, but I'd like it also to include an xy plot of about 400 points. Trouble is, I don't know how to put that plot into an email. I know I could create an image in a file and attach that to the email, but I prefer not to do that.
Is there some kind of html or something else that can go in an email that will display a plot given the set of xy points? I know that java classes on a web page can plot given the points, but can email clients like Outlook and Outlook Express run java applets? Any other thoughts?
One thing someone suggested to me was to make a plot using ASCII codes. But my plot needs to be very precise for the points given, not some rough approximation, so I don't think that would work.
|
|
|
|
|
there's a client-side graphics package called SVG[^], but i'm not sure if email clients will like it, plus it requires a client-side install (the same way you need a PDF-reader to read PDF)
Cleek | Image Toolkits | Thumbnail maker
|
|
|
|
|
If you do not want to attach, and I would worry security-wise about readers that will just go an automatically execute script and/or applets, I would suggest one of two things:
1: Use some fancy (D)HTML to draw your graph. It might be as simple as a table containing non-whitespace characters with a specific background/fill color.
2: Go old-school and create an ASCII Art drawing. (Anyone remember "The Draw"?)
Peace!
-=- James If you think it costs a lot to do it right, just wait until you find out how much it costs to do it wrong! Avoid driving a vehicle taller than you and remember that Professional Driver on Closed Course does not mean your Dumb Ass on a Public Road! DeleteFXPFiles & CheckFavorites (Please rate this post!)
|
|
|
|
|
To clarify your question, what is the form of your plot, a hard-copy printout or an electronic file? If saved in an electronic file, is it a raw data format or image format such as BMP, PDF, JPEG, etc?
- It's easier to make than to correct a mistake.
|
|
|
|
|
My old post is somewhere on page 20 and I couldn't bump it by replying. As you can see in the code (as a comment) I tried putting "Hello World" right into the function and it worked fine. I'm trying to use the Win32 WriteConsole() function but it prints out random characters (but it is a number of random characters equal to the length of the string I used in each case). I think it is a problem with the pointers I'm using but I'm not getting any warnings or errors. Please take a look:
Client code:
<br />
int _tmain(int argc, _TCHAR* argv[])<br />
{<br />
MainConsole.SwitchBuffers(1);<br />
MainConsole.WriteStreamToBuffer(1, "Hi");<br />
MainConsole.SetBufferCursorPos(2, 20, 20);<br />
MainConsole.WriteStreamToBuffer(2, "John!");<br />
MainConsole.SwitchBuffers(2);<br />
cin.get();<br />
<br />
return 0;<br />
}<br />
Class function being called:
<br />
void MainWindowSpecs::WriteBuffer(string TextToWrite)<br />
{<br />
DWORD NumCharsWritten;<br />
string *TextPtr = &TextToWrite;<br />
<br />
WriteConsole(StandardHandles.hOut, &TextPtr, TextToWrite.length(), &NumCharsWritten, NULL);<br />
if(TextToWrite.length() != NumCharsWritten)<br />
cerr<<"All characters were not written."<<endl;<br />
}<br />
|
|
|
|
|
CoffeeAddict19 wrote: WriteConsole(StandardHandles.hOut, &TextPtr, TextToWrite.length(), &NumCharsWritten, NULL);
At this point, what is the value of TextToWrite and TextPtr ?
"The largest fire starts but with the smallest spark." - David Crow
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
CoffeeAddict19 wrote:
void MainWindowSpecs::WriteBuffer(string TextToWrite)<br />
{<br />
DWORD NumCharsWritten;<br />
string *TextPtr = &TextToWrite;<br />
<br />
WriteConsole(StandardHandles.hOut, &TextPtr, TextToWrite.length(), &NumCharsWritten, NULL);<br />
if(TextToWrite.length() != NumCharsWritten)<br />
cerr<<"All characters were not written."<<endl;<br />
}
Assuming this is an STL string you are dealing with, try:
void MainWindowSpecs::WriteBuffer(const string &TextToWrite)
{
DWORD NumCharsWritten;
string *TextPtr = &TextToWrite;
WriteConsole(StandardHandles.hOut, TextToWrite.c_str(), TextToWrite.length(), &NumCharsWritten, NULL);
if(TextToWrite.length() != NumCharsWritten)
cerr<<"All characters were not written."<<endl;
} It looks like you are passing the address of the string object [edit] to WriteConsole(...) [/edit], not the pointer to its contents, which is what c_str() returns. The const reference should be a bit more efficient.
Peace!
-=- James If you think it costs a lot to do it right, just wait until you find out how much it costs to do it wrong! Avoid driving a vehicle taller than you and remember that Professional Driver on Closed Course does not mean your Dumb Ass on a Public Road! DeleteFXPFiles & CheckFavorites (Please rate this post!)
-- modified at 13:03 Wednesday 14th June, 2006
|
|
|
|
|
^It worked, thanks. I really appreciate the help, both of you. I'm still having trouble flipping buffers but that's another problem for another day.
Thanks!
|
|
|
|
|
how i can change the parent dialog's variables from a child dialog?
erfan
|
|
|
|
|
pass the this pointer of the parent class to the child.
cheers..Milton Kb
|
|
|
|
|
|
Are you sure you want to do this? It's considered bad OO design for a child object to operate on items belonging to its parent. Consider sending the parent a message instead.
"The largest fire starts but with the smallest spark." - David Crow
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
thanks.
i know this is a bad way but i need it
|
|
|
|
|
I have ever seen only the function like this
SomeFuntion(input1,input2);
such as
FindWindow(NULL,m_input);
but I never seen the funtion like this
(Something)SomeProcedure;
such as
(HOOKPROC)KeyboardProc;
What does it mean ?
|
|
|
|
|
(SomeType) is an explicit cast into the SomeType type.
such code line actually changes the type of the expression into the type specified.
TOXCCT >>> GEII power
[VisualCalc 3.0 updated ][Flags Beginner's Guide new! ]
|
|
|
|
|
It seems that you see a cast operation. For instance (int)7.2 means that the float-point value is converted to an integer, obtaining 7 . Casting can be applied for function pointers too. Thus, (HOOKPROC)KeyboardProc means that the address of KeyboardProc function is interpreted as a callback function required by the second argument of the SetWindowsHookEx call.
|
|
|
|
|
Max++ wrote: but I never seen the funtion like this
(Something)SomeProcedure;
such as
(HOOKPROC)KeyboardProc;
When you see that you are generally looking at a cast. However, in older code, especially from the U*ix world or from older U*nix developers, you may see something like:
<code>(void)</code>printf( "Some String" );
<code>(void)</code>strcpy( caSomeBuffer, "Some Other String" );
<code>(void)</code>sprintf( caSomeBuffer, "%d-%d-%d", iVal1, iVal2, iVal3 ); In this case, I believe you are seeing a construct that means something along the lines of "I am intentionally ignoring the return value of this function." I believe that some compilers may even complain (or may have complained) about disregarding return results like this(?).
Peace!
-=- James If you think it costs a lot to do it right, just wait until you find out how much it costs to do it wrong! Avoid driving a vehicle taller than you and remember that Professional Driver on Closed Course does not mean your Dumb Ass on a Public Road! DeleteFXPFiles & CheckFavorites (Please rate this post!)
|
|
|
|
|