Whenever I set a new value in the Image
property of the CVB Display OCX, the display’s zoom state is reset to the initially used panorama mode. I’d like the zoom state to remain as it was before the new image handle was set, but I dunno how
You can use GetDisplayZoomEx
to readout the current zoom state and then simply set it again once the new image handle has been set.
Yeah, but that way you’ll still see the zoom state flickering to panoramic and then back to what it should be. At 25 fps that’s not really an option…
It’s true that setting the image handle will reset the zoom state - this is a design decision that has been made because you cannot be sure that with a new image the currently set zoom state is possible (e.g. if the zoom center would be outside the image) and on the other hand having a situation where the zoom state is altered only sometimes made no sense.
On top of that, setting a new image handle will trigger a repaint of the image, which is why @GaunterODim’s suggestion will lead to the flickering. To suppress that flicker, it’ll be necessary to suppress the repaints. How this is done differs between different GUI toolkits. MFC adds a member function SetRedraw()
to each ActiveX control that will do the job:
...
long centerX, centerY;
centerX = centerY = 0;
double factor = 0.0;
m_cvDisp.GetDisplayZoomEx(¢erX, ¢erY, &factor);
m_cvDisp.SetRedraw(FALSE);
m_cvDisp.SetImage(m_cvImg.GetImage());
m_cvDisp.SetRedraw(TRUE);
m_cvDisp.SetDisplayZoomEx(centerX, centerY, factor);
...
(this assumes that m_cvDisp
is a Common Vision Blox display control and m_cvImg
is a Common Vision Blox image control).
Other toolkits are not as forthcoming and the effect of SetRedraw
needs to be triggered by sending the WM_SETREDRAW
message to the display control. For example in C# this works as follows:
// import of SendMessage and definition of WM_SETREDRAW as found on http://www.pinvoke.net
[DllImport("user32.dll",EntryPoint="SendMessage")]
public extern static int SendMessage(IntPtr hwnd, uint msg, IntPtr wParam, IntPtr lParam);
const uint WM_SETREDRAW = 0x000B;
...
// this code goes where the image handle is updated
int centerX, centerY;
centerX = centerY = 0;
double factor;
axCVdisplay.GetDisplayZoomEx(ref centerX, ref centerY, ref factor);
SendMessage(axCVdisplay.Handle, WM_SETREDRAW, IntPtr.Zero, IntPtr.Zero);
axCVdisplay.Image = axCVImage.Image;
SendMessage(axCVdisplay.Handle, WM_SETREDRAW, new IntPtr(1), IntPtr.Zero);
axCVdisplay.SetDisplayZoomEx(centerX, centerY, factor);