问题描述:
项目需要使用IMovePointFeedBack来模拟要素编辑过程中的捕捉行为,在视图没有改变的情况下,捕捉的行为很好,但是使用Zoom In/Out去改变地图的比例尺的时候,IMovePointFeedBack会在DC上残留在上一个地图比例尺下的位置,如图所示:
问题分析:
这个问题其实普遍存在于Arcgis engine中的**Feedback类型的接口中,之前在使用ILineFeedBack进行橡皮筋的绘制的时候也遇到过这个“残影”的问题,根据以往使用GDI绘图的经验知道这肯定是缺少一次重绘。因为这种类似橡皮筋的行为一般都是调用Windows底层的SetROP更改绘制模式为XOR,这样要擦除上一条记录只要在原来线的位置上再重新绘制一遍,则可擦除上一条线,于是自己在.Net中extern了如下几个函数,模拟AE的ILineFeedback的行为自己写了一个类解决了这个问题,但是当我试图自己在去写一个IMovePointFeedback的时候发现这两者的行文不能很好的兼容,因而只能放弃,根据Google的搜索结果可以发现这个问题被作为一个BUG在GisStack上进行了上报,但是在ArcMap中的捕捉行为却不存在这个问题,自己便开始怀疑可能是自己对接口的理解不完全造成的,在查阅了开发文档后发现岂是**Feedback类都存在Refresh方法,我估计这个方法应该就是针对这个问题的,接着我就在Tool的Refresh(int hDC)中调用了相应的Refresh方法,发现这个问题得到了很好的解决,而且从重绘的间隙发现它的解决方案肯定和我写的Feedback的解决方案是一样的,也就是在重绘完成后多绘制一次,以消除“残影”。
public class GDI
{
private IntPtr hdc;
private System.Drawing.Graphics grp;
public void BeginGDI(System.Drawing.Graphics g)
{
grp = g;
hdc = grp.GetHdc();
}
public void EndGDI()
{
grp.ReleaseHdc(hdc);
}
public IntPtr CreatePEN(
PenStyles fnPenStyle, // pen style
int nWidth, // pen width
int crColor // pen color
)
{
return CreatePen(fnPenStyle, nWidth, crColor);
}
public bool DeleteOBJECT(IntPtr hObject)
{
return DeleteObject(hObject);
}
public IntPtr SelectObject(
IntPtr hgdiobj // handle to object
)
{
return SelectObject(hdc, hgdiobj);
}
public void MoveTo(int X, int Y)
{
MoveToEx(hdc, X, Y, 0);
}
public void LineTo(int X, int Y)
{
LineTo(hdc, X, Y);
}
public int SetROP2(drawingMode fnDrawMode)
{
return SetROP2(hdc, fnDrawMode);
}
[System.Runtime.InteropServices.DllImportAttribute(
"gdi32.dll")]
private static extern int SetROP2(
IntPtr hdc, // handle of device context
drawingMode fnDrawMode // drawing mode
);
[System.Runtime.InteropServices.DllImportAttribute(
"gdi32.dll")]
private static extern bool MoveToEx(
IntPtr hdc, // handle to device context
int X, // x-coordinate of new current position
int Y, // y-coordinate of new current position
int oldp// pointer to old current position
);
[System.Runtime.InteropServices.DllImportAttribute(
"gdi32.dll")]
private static extern bool LineTo(
IntPtr hdc, // device context handle
int nXEnd, // x-coordinate of line's ending point
int nYEnd // y-coordinate of line's ending point
);
[System.Runtime.InteropServices.DllImportAttribute(
"gdi32.dll")]
private static extern IntPtr CreatePen(
PenStyles fnPenStyle, // pen style
int nWidth, // pen width
int crColor // pen color
);
[System.Runtime.InteropServices.DllImportAttribute(
"gdi32.dll")]
private static extern bool DeleteObject(IntPtr hObject // handle to graphic object
);
[System.Runtime.InteropServices.DllImportAttribute(
"gdi32.dll")]
private static extern IntPtr SelectObject(
IntPtr hdc, // handle to device context
IntPtr hgdiobj // handle to object
);
public static int RGB(int R, int G, int B)
{
return (R | (G << 8) | (B << 16));
}
}
如下图是解决“残影”后的捕捉效果,如果有更好的方案请告知我:
QQ:1926856741 ; E-mail:zhaozhipeng1000@126.com