Извлечь местоположение текста, перехватывая ExtTextOutW

У меня есть вопрос относительно API Windows RedrawWindow , ExtTextOut и BitBlt.
Я перехватываю ExtTextOut для извлечения местоположения текста на экране, если я вызываю RedrawWindow с параметром lprcUpdate = NULL и hrgnUpdate = NULL:

 WindowWrapper.RedrawWindow(topWnd, IntPtr.Zero, IntPtr.Zero, RedrawWindowFlags.UpdateNow | RedrawWindowFlags.Frame | RedrawWindowFlags.Invalidate | RedrawWindowFlags.AllChildren | RedrawWindowFlags.Erase);

В подключенной функции ExtTextOut я вызываю LPToDP API для перевода местоположения в местоположение контекста устройства. Тогда все работает нормально. Расположение текста правильное.

WindowWrapper.LPtoDP(hdc, arrPoint, 2);

Но если я позвоню

 WindowWrapper.RedrawWindow(topWnd, ref location, IntPtr.Zero, RedrawWindowFlags.UpdateNow | RedrawWindowFlags.Frame | RedrawWindowFlags.Invalidate | RedrawWindowFlags.AllChildren | RedrawWindowFlags.Erase);

Тогда это не удается. Местоположение неверно. Я вижу, что оно переведено с использованием LPToDP в неправильное местоположение.

Кто-нибудь знает об этой проблеме? Как мы можем это исправить?

 public static bool ExtTextOutW_Hook(IntPtr hdc, int X, int Y, uint fuOptions,
IntPtr lprc, [MarshalAs(UnmanagedType.LPWStr)] string lpString,
uint cbCount, IntPtr lpDx)
{
try
{
lock (IsRetrievingSynch)
{
if (IsRetrieving && !string.IsNullOrEmpty(lpString) && cbCount > 0)
{
TextData textData = new TextData();
textData.FuncName = "ExtTextOutW";

char[] text = new char[cbCount];
bool isGlyphIndex = ((fuOptions & 0x0010) == 0x0010);

//ETO_GLYPH_INDEX
if (isGlyphIndex)
{
FontMap fontMap = GlyphCharMap.LoadGlyphCharMap(hdc);
if (fontMap != null && fontMap.GlyphCharMap != null)
{
for (int i = 0; i < cbCount; i++)
{
ushort glyph = lpString[i];
if (glyph < fontMap.GlyphCharMap.Length)
{
if (fontMap.GlyphCharMap[glyph] != 0)
{
text[i] = (char)(fontMap.GlyphCharMap[glyph]);
}
else
{
text[i] = (char)32;
}
}
else
{
text[i] = (char)glyph;
}
}
}
}
else
{
for (int i = 0; i < cbCount; i++)
{
text[i] = lpString[i];
}
}

textData.Text = new string(text);
textData.Text = textData.Text.Normalize(NormalizationForm.FormKC);
//textData.Text = textData.Text.Trim();

if (!string.IsNullOrEmpty(textData.Text))
{
int realCount = textData.Text.Length;

TEXTMETRICW tm = new TEXTMETRICW();
WindowWrapper.GetTextMetricsW(hdc, out tm);
int[] nWidth = new int[1];
WindowWrapper.GetCharWidth32W(hdc, ' ', ' ', nWidth);
textData.CharHeight = tm.tmHeight;
textData.CharWidth = nWidth[0];
textData.CharWidths = new int[realCount];
for (int i = 0; i < realCount; i++)
{
nWidth = new int[1];
WindowWrapper.GetCharWidth32W(hdc, textData.Text[i], textData.Text[i], nWidth);
textData.CharWidths[i] = nWidth[0];
}

uint textAlign = WindowWrapper.GetTextAlign(hdc);
POINT ptStartPos = new POINT();if ((textAlign & WindowWrapper.TA_UPDATECP) > 0)
{
WindowWrapper.GetCurrentPositionEx(hdc, out ptStartPos);
}
else
{
ptStartPos.X = X;
ptStartPos.Y = Y;
}

switch (textAlign & (WindowWrapper.TA_BASELINE | WindowWrapper.TA_BOTTOM | WindowWrapper.TA_TOP))
{
case WindowWrapper.TA_BOTTOM:
textData.Location.Top = Y - tm.tmHeight;
textData.Location.Bottom = Y;
break;
case WindowWrapper.TA_BASELINE:
textData.Location.Top = Y - tm.tmAscent;
textData.Location.Bottom = Y + tm.tmDescent;
break;
case WindowWrapper.TA_TOP:
default:
textData.Location.Top = Y;
textData.Location.Bottom = Y + tm.tmHeight;
break;
}

int nLAlign = 0, nRAlign = 0;
switch (textAlign & (WindowWrapper.TA_LEFT | WindowWrapper.TA_RIGHT | WindowWrapper.TA_CENTER))
{
case WindowWrapper.TA_LEFT:
nLAlign = 0;
nRAlign = 2;
break;
case WindowWrapper.TA_CENTER:
nLAlign = -1;
nRAlign = 1;
break;
case WindowWrapper.TA_RIGHT:
nLAlign = -2;
nRAlign = 0;
break;
}

SIZE size = new SIZE();
if (WindowWrapper.GetTextExtentPoint32W(hdc, lpString, (int)cbCount, ref size))
{
textData.Location.Left = X + nLAlign * (size.CX / 2);
textData.Location.Right = X + nRAlign * (size.CX / 2);
}
else
{
textData.Location.Left = X - 20;
textData.Location.Right = X + 20;
}
LogFactory.RemoteLog.TraceDebug(string.Format("1.ExtTextOutW {0} {1} {2} {3} {4}",
textData.Text, textData.Location.Left, textData.Location.Top,
textData.Location.Right - textData.Location.Left,
textData.Location.Bottom - textData.Location.Top));

//Utility.ClipViewPort(hdc, ref textData.Location);POINT[] arrPoint = new POINT[2];
arrPoint[0] = new POINT()
{
X = textData.Location.Left,
Y = textData.Location.Top
};
arrPoint[1] = new POINT()
{
X = textData.Location.Right,
Y = textData.Location.Bottom
};
POINT ptDCOrg = new POINT();

WindowWrapper.LPtoDP(hdc, arrPoint, 2);

textData.Location.Left = arrPoint[0].X;
textData.Location.Top = arrPoint[0].Y;
textData.Location.Right = arrPoint[1].X;
textData.Location.Bottom = arrPoint[1].Y;

WindowWrapper.GetDCOrgEx(hdc, out ptDCOrg);
textData.Location.Left += ptDCOrg.X;
textData.Location.Top += ptDCOrg.Y;
textData.Location.Right += ptDCOrg.X;
textData.Location.Bottom += ptDCOrg.Y;

LogFactory.RemoteLog.TraceDebug(string.Format("2.ExtTextOutW {0} {1} {2} {3} {4}",
textData.Text, textData.Location.Left, textData.Location.Top,
textData.Location.Right - textData.Location.Left,
textData.Location.Bottom - textData.Location.Top));

StringBuilder fontName = new StringBuilder();
fontName.Capacity = 260;
WindowWrapper.GetTextFace(hdc, 260, fontName);
textData.Font = fontName.ToString();

IntPtr hWnd = WindowWrapper.WindowFromDC(hdc);
if (WindowWrapper.IsWindowVisible(hWnd))
{
textData.Hdc = hdc;
textData.Hwnd = hWnd;

textData.ZOrder = WindowWrapper.GetZOrder(hWnd);

if (Utility.IsIntersect(_location, textData.Location) && WindowWrapper.IsChildWindow(_topWindow, hWnd))
{
LogFactory.RemoteLog.TraceVerbose(string.Format("3.ExtTextOutW {0} {1} {2} {3} {4} Z-Order: {5}",
textData.Text,
textData.Location.Left,
textData.Location.Top,
textData.Location.Right - textData.Location.Left,
textData.Location.Bottom - textData.Location.Top,
textData.ZOrder));
if (TextDataChannel != null)
TextDataChannel.SendTextData(textData);
}
}
else
{
textData.Hdc = hdc;
//if (lpDx != IntPtr.Zero)
//    Utility.ClipViewPort(hdc, ref textData.Location);
_tempDataList.Add(textData);
}
}
}
}
}
catch (Exception ex)
{
LogFactory.RemoteLog.TraceError("ExtTextOutW " + ex.Message);
}

return ExtTextOutW(hdc, X, Y, fuOptions, lprc, lpString, cbCount, lpDx);
}

Благодарю.

0

Решение

Задача ещё не решена.

Другие решения


По вопросам рекламы [email protected]