|
MFC bmpToHBITMAP issue |
Posted by Sal on May-31-2017 01:59 |
|
Hello Peter,
I am getting randomly a "memcpy" error inside the function CStaticHelper::bmpToHBITMAP () of ChartViewer()
It looks like I fail to obtain "buffer" from the call to:
HBITMAP ret = CreateDIBSection(cdc->m_hDC, bmp, DIB_RGB_COLORS, &buffer, NULL, 0x0);
which is null. "ret" is anything but Zero everytime
The parameters I am supplying for the call are the same, that I can tell
The code appear to work most of the time, so I do not know what could I possible do to prevent the issue from happening.
I would imagine that the line above would have had a check for the pointer validity or a check for the ret value.
I have added a try/catch code into the code sections that call makeChart or updateDisplay that eventually gets to the above function, to no help
I stopped from changing your code, thinking that probably there was a good reason why it was written that way
What can you suggest I could do to beef-up the mention function by supplying some sort of error catch/handler, so I can trap the reason of the failure ?
I am running 64 bits code + I have plenty memory
Anything to try or what you know I could trigger a failure of the above function ?
Thanks
Sal |
Re: MFC bmpToHBITMAP issue |
Posted by Peter Kwan on May-31-2017 03:47 |
|
Hi Sal,
The CreateDIBSection is a Windows function. According to Microsoft documentation, it will return ERROR_INVALID_PARAMETER the parameters are invalid. See:
https://msdn.microsoft.com/en-us/library/windows/desktop/dd183494(v=vs.85).aspx
To check if there is error, you may add a line:
assert(ret != ERROR_INVALID_PARAMETER);
With the above code, if ERROR_INVALID_PARAMETER, the debugger will stop at the above line. You can then check the parameters to see if any of them is incorrect.
For your case, is the error occurring in the original unmodified CChartViewer, or do you mean you have copied the CreateDIBSection line out and use it in your own code?
If the code crash, there should be a stack trace. Is the trace indicates that line causing the error?
The line uses two variable parameters, which is:
(a) cdc->m_hDC: This parameter is only valid inside certain MFC objects and only valid after the MFC object has been initialized and before the MFC object is destroyed.
(b) bmp: This should be the BMP output from ChartDirector. If you think this can be incorrect, you can save a copy of the BMP to a file. In this way, when the code crash, we can get the BMP as a file for analysis. In the original CChartViewer code, the bmpToHBITMAP is only called from CStaticHelper::displayChart. In displayChart, there BMP is in a MemBlock, which contains both the memory pointer and its length. You can just save the memory to a file (using regular fopen/fwrite).
If you code is multi-threaded, I assume you are aware that any code that uses any MFC control must run in the GUI thread, not in another thread. For example, the code "XYChart *c = new XYChart(....);" can run in any thread. However, the code "viewer.setChart(c);" must run in the GUI thread, as it uses the MFC object "viewer". This is not a limitation of ChartDirector, but is a limitation of MFC, and is a common rule for all GUI code. (The GUI thread is the thread the creates the MFC object. This is typically the main thread.)
Regards
Peter Kwan |
|