Click here to Skip to main content
15,504,286 members

Comments by Iain Clarke, Warrior Programmer (Top 15 by date)

Iain Clarke, Warrior Programmer 4-Nov-15 4:36am View    
This question does not make a lot of sense. C# had forms. MFC has windows and dialogs. If you have a dialog box, and a graph control on it, then I am guessing you are adding a double click handler to your dialog box, when you should be adding a notify handler, with the notify code and control ID.
Without knowing what "graph" is, we can't really help you any more that that.
Do a search for ON_NOTIFY, and NM_DBLCLK, and some information about standard controls will show up for you.
Iain Clarke, Warrior Programmer 31-May-13 7:45am View    
Well, I can do VT_BYREF | VT_I4 to "connect" to a (..., ref int, ...) function, so the marshaller is clever enough there. Just VT_ARRAY | x means the marshaller has to package up a safearray with its contents to pass to the other end too.

My problem is that the marshaller does not "bring back" the array afterwards...

I have done some reading into MarshalAs which started to look hopeful, but that might be just for C# to c++ (ie, PInvoke), not COM to C#.

Iain Clarke, Warrior Programmer 21-May-13 6:38am View    
You: "each value is a gray level from 0 to 255"... sounds like 1 byte to me!

As you have 1024 pixels, your data is already a multiple of 4, so I don't think you need padding. You might have the values in the BITMAPHEADER wrong? And maybe you're saying you;re using a palette, when your data is already in colour?

I'd start with a simple 16x16 array, with all colours being simple, and work up from there. If your 24 bit colour values are "backwards", then you might just have to copy them to another buffer, re-arranging them as you go.

Iain Clarke, Warrior Programmer 20-May-13 4:58am View    
Didn't you say your data is 1 byte, and greyscale?

In which case, R=G=B!

But I think the confusion may be in how intel stores numbers:
0x12345678 stored in ram becomes: 78 56 34 12

Trust me, you can use COLORREF type and RGB macro for this.

Iain Clarke, Warrior Programmer 15-May-13 3:40am View    
I guess you have a CDC of some sorts, and are doing SetPixel in a loop?

If so, throw the loop away, and do:
::SetDIBitsToDevice (*pDC, ...., &m_pBlockOfBytes, &m_bmiPrePreparedBitmapStructure, DIB_RGB_COLORS);

Your block of bytes is where your numerical values are - bytes 0-1024, followed by bytes 1040-2047, and so on. It's not quite the same as a 1040x1024 array, but it's equivalent.

You can also prepare your bitmap array in advance too:
m_pbmi = (BITMAPINFO *)malloc (sizeof (BITMAPINFOHEADER) + 256 * sizeof (RGBQUAD));
ZeroMemory (m_pbmi, sizeof (BITMAPINFOHEADER) + 256 * sizeof (RGBQUAD));
m_pbmi->bmiHeader.... = ...;
for (int n = 0; n < 256; n++)
m_pbmi->bmiColors [n].rgbRed = n;
m_pbmi->bmiColors [n].rgbGreen = n;
m_pbmi->bmiColors [n].rgbBlue = n;

As I said before, this is a complex function, but powerful. Once you've done the initial setup work, you can just change one of your data bytes, invalidate your window, and in your paint / ondraw function, you can just call the one line setdibitstodevice function, and you're done!

It's MILES faster than 1 million setpixels.