int far pascal zGetTextCharacterExtra( HDC pp1 ) { int r; SaveRegs(); /* ** Log IN Parameters (No Create/Destroy Checking Yet!) */ LogIn( (LPSTR)"APICALL:GetTextCharacterExtra HDC+", pp1 ); /* ** Call the API! */ RestoreRegs(); GrovelDS(); r = GetTextCharacterExtra(pp1); UnGrovelDS(); SaveRegs(); /* ** Log Return Code & OUT Parameters (No Create/Destroy Checking Yet!) */ LogOut( (LPSTR)"APIRET:GetTextCharacterExtra int++", r, (short)0 ); RestoreRegs(); return( r ); }
static void test_dc_values(void) { HDC hdc = CreateDCA("DISPLAY", NULL, NULL, NULL); COLORREF color; int extra; ok( hdc != NULL, "CreateDC failed\n" ); color = SetBkColor( hdc, 0x12345678 ); ok( color == 0xffffff, "initial color %08x\n", color ); color = GetBkColor( hdc ); ok( color == 0x12345678, "wrong color %08x\n", color ); color = SetBkColor( hdc, 0xffffffff ); ok( color == 0x12345678, "wrong color %08x\n", color ); color = GetBkColor( hdc ); ok( color == 0xffffffff, "wrong color %08x\n", color ); color = SetBkColor( hdc, 0 ); ok( color == 0xffffffff, "wrong color %08x\n", color ); color = GetBkColor( hdc ); ok( color == 0, "wrong color %08x\n", color ); color = SetTextColor( hdc, 0xffeeddcc ); ok( color == 0, "initial color %08x\n", color ); color = GetTextColor( hdc ); ok( color == 0xffeeddcc, "wrong color %08x\n", color ); color = SetTextColor( hdc, 0xffffffff ); ok( color == 0xffeeddcc, "wrong color %08x\n", color ); color = GetTextColor( hdc ); ok( color == 0xffffffff, "wrong color %08x\n", color ); color = SetTextColor( hdc, 0 ); ok( color == 0xffffffff, "wrong color %08x\n", color ); color = GetTextColor( hdc ); ok( color == 0, "wrong color %08x\n", color ); extra = GetTextCharacterExtra( hdc ); ok( extra == 0, "initial extra %d\n", extra ); SetTextCharacterExtra( hdc, 123 ); extra = GetTextCharacterExtra( hdc ); ok( extra == 123, "initial extra %d\n", extra ); SetMapMode( hdc, MM_LOMETRIC ); extra = GetTextCharacterExtra( hdc ); ok( extra == 123, "initial extra %d\n", extra ); SetMapMode( hdc, MM_TEXT ); extra = GetTextCharacterExtra( hdc ); ok( extra == 123, "initial extra %d\n", extra ); DeleteDC( hdc ); }
GDI2FT_RENDERER::GDI2FT_RENDERER( const GDI2FT_CONTEXT& _context ) /* -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- */ { context = &_context; render_mode = FT_RENDER_MODE_LCD; char_extra = GetTextCharacterExtra( context->hdc ); const int lf_metric_size = sizeof( context->log_font ) - sizeof( context->log_font.lfFaceName ); const int lf_facename_size = static_cast<const int>( ( wcslen( context->log_font.lfFaceName ) * sizeof( wchar_t ) ) ); const int lf_total_size = lf_metric_size + lf_facename_size; #ifdef _M_X64 font_trait = hash64( &context->log_font, lf_total_size, 0 ); #else font_trait = hash32( &context->log_font, lf_total_size, 0 ); #endif // _M_X64 }
void GR_Win32CharWidths::setCharWidthsOfRange(HDC hdc, UT_UCSChar c0, UT_UCSChar c1) { if(m_vRanges.getItemCount() == 0) { _retrieveFontInfo(hdc); } UINT k; int w; #ifdef DEBUG DWORD iErrorCode = 0; #endif // Windows NT and Windows 95 support the Unicode Font file. // All of the Unicode glyphs can be rendered if the glyph is found in // the font file. However, Windows 95 does not support the Unicode // characters other than the characters for which the particular codepage // of the font file is defined. // Reference Microsoft knowledge base: // Q145754 - PRB ExtTextOutW or TextOutW Unicode Text Output Is Blank if (UT_IsWinNT()) { for (k=c0; k<=c1; k++) { if(k == 0x200B || k == 0xFEFF || k == UCS_LIGATURE_PLACEHOLDER) setWidth(k,0); else if(!_doesGlyphExist(k)) { setWidth(k,GR_CW_ABSENT); } else { GetCharWidth32W(hdc,k,k,&w); #ifdef DEBUG ABC abc; int iRes = GetCharABCWidthsW(hdc,k,k,&abc); #endif // handle overstriking chars here UT_uint32 iOver = UT_isOverstrikingChar(k); if(!w || iOver != UT_NOT_OVERSTRIKING) { iOver &= UT_OVERSTRIKING_TYPE; if(iOver == UT_OVERSTRIKING_RIGHT) { w = 0; } else { ABC abc; UT_DebugOnly<int> iRes = GetCharABCWidthsW(hdc,k,k,&abc); UT_ASSERT( iRes ); if(iOver == UT_OVERSTRIKING_LEFT) { UT_ASSERT( abc.abcB < GR_OC_MAX_WIDTH); w = abc.abcB | GR_OC_LEFT_FLUSHED; } else { w = abc.abcB /*+ abc.abcA + abc.abcC*/; w = -w; } } } setWidth(k,w); } } } else { HFONT hFont = (HFONT) GetCurrentObject(hdc, OBJ_FONT); LOGFONTW aLogFont; UT_DebugOnly<int> iRes = GetObjectW(hFont, sizeof(LOGFONTW), &aLogFont); UT_ASSERT(iRes); xxx_UT_DEBUGMSG(("gr_Win32Graphics::getCharWidth: extra interchar. spacing %d\n", GetTextCharacterExtra(hdc))); if(aLogFont.lfCharSet == SYMBOL_CHARSET) { // Symbol character handling for (k=c0; k<=c1; k++) { if(!_doesGlyphExist(k)) { setWidth(k,GR_CW_ABSENT); } else { SIZE Size; char str[sizeof(UT_UCSChar)]; int iConverted = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR) &k, 1, str, sizeof(str), NULL, NULL); GetTextExtentPoint32A(hdc, str, iConverted, &Size); setWidth(k, Size.cx); } } } else { // Unicode font and default character sets for (k=c0; k<=c1; k++) { if(k == 0x200B || k == 0xFEFF || k == UCS_LIGATURE_PLACEHOLDER) setWidth(k,0); else if(!_doesGlyphExist(k)) { setWidth(k,GR_CW_ABSENT); } else { SIZE Size; wchar_t sz1[2]; sz1[0] = k; GetTextExtentPoint32W(hdc, sz1, 1, &Size); // handle overstriking chars here UT_uint32 iOver = UT_isOverstrikingChar(k); if(!Size.cx || iOver != UT_NOT_OVERSTRIKING) { iOver &= UT_OVERSTRIKING_TYPE; if(iOver == UT_OVERSTRIKING_RIGHT) { Size.cx = 0; } else { ABC abc; iRes = GetCharABCWidthsW(hdc,k,k,&abc); // I have commented out the assert below, // because when the function above is called for // the first time, it seems to always // return 0, even though it fills the abc // structure with reasonable values, // Tomas, June 22, 2003 // UT_ASSERT( iRes ); #ifdef DEBUG if(!iRes) { iErrorCode = GetLastError(); } #endif if(iOver == UT_OVERSTRIKING_LEFT) { UT_ASSERT( abc.abcB < GR_OC_MAX_WIDTH); Size.cx = abc.abcB | GR_OC_LEFT_FLUSHED; } else { Size.cx = abc.abcB; Size.cx = -Size.cx; } } } #ifdef DEBUG if(iErrorCode) { LPVOID lpMsgBuf; FormatMessageW( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, iErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPWSTR) &lpMsgBuf, 0, NULL ); // Process any inserts in lpMsgBuf. // ... // Display the string. //MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION ); UT_DEBUGMSG(("char width error: %s\n", lpMsgBuf)); // Free the buffer. LocalFree( lpMsgBuf ); } #endif setWidth(k,Size.cx); xxx_UT_DEBUGMSG(("gr_Win32Graphics::getCharWidths: 0x%x: Size.cx %d\n", k, Size.cx)); } } } } }
//Hook TextOutW 的过程 DLLEXPORT BOOL WINAPI NHExtTextOutW(HDC hdc, int X, int Y, UINT fuOptions, CONST RECT *lprc, LPCWSTR lpString, UINT cbCount, CONST INT *lpDx) { POINT pt; HWND hWDC; HWND hWPT; DWORD dwThreadIdWithPoint = 0; DWORD dwThreadIdCurr = 0; // restore RestoreWin32Api(&g_ExtTextOutWHook, HOOK_NEED_CHECK); /* { char cBuffer[0x100]; wsprintf(cBuffer, "-> NHExtTextOutW : %s\n", "start"); OutputDebugString(cBuffer); } */ //DbgFilePrintf("-> NHExtTextOutW : lpString(%s), cbCount(%d)\n", lpString, cbCount); pt.x = g_CurMousePos.x; pt.y = g_CurMousePos.y; hWDC = WindowFromDC(hdc); hWPT = WindowFromPoint(pt); // 01/17/2000 // Fix Bug3: get word error when IE window overlaps. // Fix Bug3 begin dwThreadIdWithPoint = GetWindowThreadProcessId(hWPT, NULL); dwThreadIdCurr = GetCurrentThreadId(); if(dwThreadIdWithPoint == dwThreadIdCurr) { // Fix Bug3 end if (hWDC == NULL || hWPT == hWDC || IsParentOrSelf(hWPT, hWDC) || IsParentOrSelf(hWDC, hWPT)) { if ((g_bAllowGetCurWord) && (!IsBadReadPtr(lpString, cbCount)) && (cbCount > 0)) { /* { //char cBuffer[0x100]; //wsprintf(cBuffer, ">>>----> NHExtTextOutW : (%s) %d\n", lpTemp, cbCount); //OutputDebugString(cBuffer); } */ g_nTextAlign = GetTextAlign(hdc); g_nExtra = GetTextCharacterExtra(hdc); GetCurrentPositionEx(hdc, &g_CurPos); GetTextMetrics(hdc, &g_tm); g_dwDCOrg.x = 0; g_dwDCOrg.y = 0; bRecAllRect = FALSE; GetStringRectW(hdc, lpString, cbCount, X, Y, &g_rcTotalRect, lpDx); bRecAllRect = TRUE; //{DbgFilePrintf("--> NHExtTextOutW: lpTemp(%s)len(%d)\n", lpTemp, strlen(lpTemp));} //{DbgFilePrintf("--> NHExtTextOutW: X(%d)Y(%d), g_rcTotalRect(%d,%d,%d,%d)\n", X, Y, g_rcTotalRect.left, g_rcTotalRect.top, g_rcTotalRect.right, g_rcTotalRect.bottom);} if ((WindowFromDC != NULL)&&(WindowFromDC(hdc) == NULL)) { g_dwDCOrg.x = 0; g_dwDCOrg.y = 0; // 01/19/2000 // Fix Bug5: get word position error sometimes // Fix Bug5 begin AddToTextOutBufferW(hdc, lpString, cbCount, X, Y, lpDx); // Fix Bug5 end } else { GetDCOrgEx(hdc, &g_dwDCOrg); // 01/19/2000 // Fix Bug5: get word position error sometimes // Fix Bug5 begin GetCurMousePosWordW(hdc, lpString, cbCount, X, Y, lpDx); // Fix Bug5 end } } } } // call ExtTextOutW ExtTextOutW(hdc, X, Y, fuOptions, lprc, lpString, cbCount, lpDx); //调用封装好的HooK过程 HookWin32Api(&g_ExtTextOutWHook, HOOK_NEED_CHECK); return TRUE; }
//Hook TextOutA的过程 DLLEXPORT BOOL WINAPI NHExtTextOutA(HDC hdc, int X, //当前需要绘制的文本的起始位置 int Y, UINT fuOptions, CONST RECT *lprc, LPCTSTR lpString, UINT cbCount, CONST INT *lpDx) { POINT pt; HWND hWDC; HWND hWPT; DWORD dwThreadIdWithPoint = 0; DWORD dwThreadIdCurr = 0; // restore RestoreWin32Api(&g_ExtTextOutAHook, HOOK_NEED_CHECK); /* if (cbCount != 0) { char cBuffer[0x100]; wsprintf(cBuffer, "-> NHExtTextOutA : %s (%s) (%d)\n", "start", lpString, cbCount); OutputDebugString(cBuffer); } */ //DbgFilePrintf("-> NHExtTextOutA : lpString(%s), cbCount(%d)\n", lpString, cbCount); pt.x = g_CurMousePos.x; pt.y = g_CurMousePos.y; hWDC = WindowFromDC(hdc); hWPT = WindowFromPoint(pt); dwThreadIdWithPoint = GetWindowThreadProcessId(hWPT, NULL); dwThreadIdCurr = GetCurrentThreadId(); if(dwThreadIdWithPoint == dwThreadIdCurr) { if (hWDC == NULL || hWPT == hWDC || IsParentOrSelf(hWPT, hWDC) || IsParentOrSelf(hWDC, hWPT)) { if ((g_bAllowGetCurWord) && (!IsBadReadPtr(lpString, cbCount)) && (cbCount > 0)) { g_nTextAlign = GetTextAlign(hdc); g_nExtra = GetTextCharacterExtra(hdc); GetCurrentPositionEx(hdc, &g_CurPos); GetTextMetrics(hdc, &g_tm); g_dwDCOrg.x = 0; g_dwDCOrg.y = 0; bRecAllRect = FALSE; //findword.c中的代码,取出当前字符的矩形范围 GetStringRect(hdc, (LPSTR)lpString, cbCount, X, Y, &g_rcTotalRect, lpDx); bRecAllRect = TRUE; if ((WindowFromDC != NULL)&&(WindowFromDC(hdc) == NULL)) { g_dwDCOrg.x = 0; g_dwDCOrg.y = 0; AddToTextOutBuffer(hdc, (LPSTR)lpString, cbCount, X, Y, lpDx); } else { GetDCOrgEx(hdc, &g_dwDCOrg); //findword.c中的代码,取出当前位置下的单词 GetCurMousePosWord(hdc, (LPSTR)lpString, cbCount, X, Y, lpDx); } } } } // call ExtTextOutA ExtTextOutA(hdc, X, Y, fuOptions, lprc, lpString, cbCount, lpDx); HookWin32Api(&g_ExtTextOutAHook, HOOK_NEED_CHECK); return TRUE; }
//Hook TextOutW 的过程 DLLEXPORT BOOL WINAPI NHTextOutW(HDC hdc, int nXStart, int nYStart, LPCWSTR lpString, int cbString) { POINT pt; HWND hWDC; HWND hWPT; DWORD dwThreadIdWithPoint = 0; DWORD dwThreadIdCurr = 0; /* { char cBuffer[0x100]; wsprintf(cBuffer, "-> NHTextOutW : %s\n", "start"); OutputDebugString(cBuffer); } */ //DbgFilePrintf("-> NHTextOutW : lpString(%s), cbString(%d)\n", lpString, cbString); // restore RestoreWin32Api(&g_TextOutWHook, HOOK_NEED_CHECK); pt.x = g_CurMousePos.x; pt.y = g_CurMousePos.y; hWDC = WindowFromDC(hdc); hWPT = WindowFromPoint(pt); dwThreadIdWithPoint = GetWindowThreadProcessId(hWPT, NULL); dwThreadIdCurr = GetCurrentThreadId(); if(dwThreadIdWithPoint == dwThreadIdCurr) { if (hWDC == NULL || hWPT == hWDC || IsParentOrSelf(hWPT, hWDC) || IsParentOrSelf(hWDC, hWPT)) { if ((g_bAllowGetCurWord) && (!IsBadReadPtr(lpString, cbString)) && (cbString > 0)) { g_nTextAlign = GetTextAlign(hdc); g_nExtra = GetTextCharacterExtra(hdc); GetCurrentPositionEx(hdc, &g_CurPos); GetTextMetrics(hdc, &g_tm); g_dwDCOrg.x = 0; g_dwDCOrg.y = 0; bRecAllRect = FALSE; GetStringRectW(hdc, lpString, cbString, nXStart, nYStart, &g_rcTotalRect, NULL); bRecAllRect = TRUE; if ((WindowFromDC != NULL)&&(WindowFromDC(hdc) == NULL)) { g_dwDCOrg.x = 0; g_dwDCOrg.y = 0; // 01/19/2000 // Fix Bug5: get word position error sometimes // Fix Bug5 begin AddToTextOutBufferW(hdc, lpString, cbString, nXStart, nYStart, NULL); //Fix Bug5 end } else { GetDCOrgEx(hdc, &g_dwDCOrg); // 01/19/2000 // Fix Bug5: get word position error sometimes // Fix Bug5 begin GetCurMousePosWordW(hdc, lpString, cbString, nXStart, nYStart, NULL); //Fix Bug5 end } } } } // call TextOutW 处理完我们的函数之后,回调系统的TextOutW函数,以便系统继续进行 TextOutW(hdc, nXStart, nYStart, lpString, cbString); HookWin32Api(&g_TextOutWHook, HOOK_NEED_CHECK); return TRUE; }
//Hook TextOutA的过程 DLLEXPORT BOOL WINAPI NHTextOutA(HDC hdc, int nXStart, int nYStart, LPCTSTR lpString, int cbString) { POINT pt; HWND hWDC; HWND hWPT; DWORD dwThreadIdWithPoint = 0; DWORD dwThreadIdCurr = 0; /* { char cBuffer[0x100]; wsprintf(cBuffer, "-> NHTextOutA : %s\n", "start"); OutputDebugString(cBuffer); } */ //DbgFilePrintf("-> NHTextOutA : lpString(%s), cbString(%d)\n", lpString, cbString); // restore RestoreWin32Api(&g_TextOutAHook, HOOK_NEED_CHECK); // pt.x = g_CurMousePos.x; pt.y = g_CurMousePos.y; hWDC = WindowFromDC(hdc); //Xianfeng:对方所在窗体句柄 hWPT = WindowFromPoint(pt); //Xianfeng:鼠标所在窗体句柄 dwThreadIdWithPoint = GetWindowThreadProcessId(hWPT, NULL); //Xianfeng:取得鼠标所在窗体线程ID dwThreadIdCurr = GetCurrentThreadId(); //Xianfeng:取得当前线程ID if(dwThreadIdWithPoint == dwThreadIdCurr) { if (hWDC == NULL || hWPT == hWDC || IsParentOrSelf(hWPT, hWDC) || IsParentOrSelf(hWDC, hWPT)) { if ((g_bAllowGetCurWord) && (!IsBadReadPtr(lpString, cbString)) && (cbString > 0)) { g_nTextAlign = GetTextAlign(hdc); //Xianfeng:取得当前DC的文本对齐方式,在后面计算矩形用 g_nExtra = GetTextCharacterExtra(hdc); //Xianfeng:取得字符间空隙,单位估计是像素 GetCurrentPositionEx(hdc, &g_CurPos); //Xianfeng:取得当前DC的逻辑位置 GetTextMetrics(hdc, &g_tm); //Xianfeng:取得当前DC的font的基本信息 g_dwDCOrg.x = 0; g_dwDCOrg.y = 0; bRecAllRect = FALSE; GetStringRect(hdc, (LPSTR)lpString, cbString, nXStart, nYStart, &g_rcTotalRect, NULL); bRecAllRect = TRUE; if ((WindowFromDC != NULL)&&(WindowFromDC(hdc) == NULL)) { g_dwDCOrg.x = 0; g_dwDCOrg.y = 0; //Xianfeng:保存输出字符信息到内存 AddToTextOutBuffer(hdc, (LPSTR)lpString, cbString, nXStart, nYStart, NULL); } else { //Xianfeng:取回DC原点,通常的值是客户区左上角相对于窗体左上角的偏移量 GetDCOrgEx(hdc, &g_dwDCOrg); //Xianfeng:获取当前鼠标下的字 GetCurMousePosWord(hdc, (LPSTR)lpString, cbString, nXStart, nYStart, NULL); } } } } // call TextOutA TextOutA(hdc, nXStart, nYStart, lpString, cbString); HookWin32Api(&g_TextOutAHook, HOOK_NEED_CHECK); return TRUE; }
void KDCAttributes::DumpDC(HDC hDC) { POINT pnt; SIZE size; m_List.DeleteAll(); Add(_T("Technology"), _T("%d"), GetDeviceCaps(hDC, TECHNOLOGY)); Add(_T("width"), _T("%d"), GetDeviceCaps(hDC, HORZRES)); Add(_T("height"), _T("%d"), GetDeviceCaps(hDC, VERTRES)); GetDCOrgEx(hDC, & pnt); Add(_T("DC Origin"), _T("{ %d, %d }"), pnt.x, pnt.y); TCHAR szTitle[MAX_PATH]; szTitle[0] = 0; GetWindowText(WindowFromDC(hDC), szTitle, MAX_PATH); Add(_T("Window"), _T("0x%X \"%s\""), WindowFromDC(hDC), szTitle); Add(_T("Bitmap"), _T("0x%X"), GetCurrentObject(hDC, OBJ_BITMAP)); Add(_T("Graphics Mode"), _T("%d"), GetGraphicsMode(hDC)); Add(_T("Mapping Mode"), _T("%d"), GetMapMode(hDC)); GetViewportExtEx(hDC, & size); Add(_T("Viewport Extent"), _T("{ %d, %d }"), size.cx, size.cy); GetViewportOrgEx(hDC, & pnt); Add(_T("Viewport Origin"), _T("{ %d, %d }"), pnt.x, pnt.y); GetWindowExtEx(hDC, & size); Add(_T("Window Extent"), _T("{ %d, %d }"), size.cx, size.cy); GetWindowOrgEx(hDC, & pnt); Add(_T("Window Origin"), _T("{ %d, %d }"), pnt.x, pnt.y); XFORM xform; GetWorldTransform(hDC, & xform); Add(_T("World transformation"), _T("{ %f, %f, %f, %f, %f, %f }"), xform.eM11, xform.eM12, xform.eM21, xform.eM22, xform.eDx, xform.eDy); // transformation Add(_T("Background Color"), _T("0x%X"), GetBkColor(hDC)); Add(_T("Text Color"), _T("0x%X"), GetTextColor(hDC)); Add(_T("Palette"), _T("0x%X"), GetCurrentObject(hDC, OBJ_PAL)); { COLORADJUSTMENT ca; GetColorAdjustment(hDC, & ca); Add(_T("Color Adjustment"), _T("{ %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d }"), ca.caSize, ca.caFlags, ca.caIlluminantIndex, ca.caRedGamma, ca.caGreenGamma, ca.caBlueGamma, ca.caReferenceBlack, ca.caReferenceWhite, ca.caContrast, ca.caBrightness, ca.caColorfulness, ca.caRedGreenTint); } Add(_T("Color Space"), _T("0x%X"), GetColorSpace(hDC)); Add(_T("ICM Mode"), _T("%d"), SetICMMode(hDC, ICM_QUERY)); { TCHAR szProfile[MAX_PATH]; DWORD dwSize = MAX_PATH; szProfile[0] = 0; GetICMProfile(hDC, & dwSize, szProfile); Add(_T("ICM Profile"), _T("%s"), szProfile); } GetCurrentPositionEx(hDC, & pnt); Add(_T("Current Position"), _T("{ %d, %d }"), pnt.x, pnt.y); Add(_T("ROP2"), _T("%d"), GetROP2(hDC)); Add(_T("Background Mode"), _T("%d"), GetBkMode(hDC)); Add(_T("Logical Pen"), _T("0x%X"), GetCurrentObject(hDC, OBJ_PEN)); Add(_T("DC Pen Color"), _T("0x%X"), GetDCPenColor(hDC)); Add(_T("Arc Direction"), _T("%d"), GetArcDirection(hDC)); FLOAT miter; GetMiterLimit(hDC, & miter); Add(_T("Miter Limit"), _T("%f"), miter); Add(_T("Logical Brush"), _T("0x%X"), GetCurrentObject(hDC, OBJ_BRUSH)); Add(_T("DC Brush Color"), _T("0x%X"), GetDCBrushColor(hDC)); GetBrushOrgEx(hDC, & pnt); Add(_T("Brush Origin"), _T("{ %d, %d }"), pnt.x, pnt.y); Add(_T("Polygon Filling Mode"), _T("%d"), GetPolyFillMode(hDC)); Add(_T("Bitmap Stretching Mode"), _T("%d"), GetStretchBltMode(hDC)); Add(_T("Logical Font"), _T("0x%X"), GetCurrentObject(hDC, OBJ_FONT)); Add(_T("Inter-character spacing"), _T("%d"), GetTextCharacterExtra(hDC)); DWORD flag = SetMapperFlags(hDC, 0); SetMapperFlags(hDC, flag); Add(_T("Font Mapper Flags"), _T("0x%X"), flag); Add(_T("Text Alignment"), _T("0x%X"), GetTextAlign(hDC)); Add(_T("Text Justification"), _T("write only"), 0); Add(_T("Layout"), _T("%d"), GetLayout(hDC)); Add(_T("Path"), _T("%d bytes"), GetPath(hDC, NULL, NULL, 0)); RECT rect; int typ = GetClipBox(hDC, & rect); HRGN hRgn = CreateRectRgn(0, 0, 1, 1); GetClipRgn(hDC, hRgn); Add(_T("Clipping"), _T("type %d clip box { %d, %d, %d, %d } size %d bytes"), typ, rect.left, rect.top, rect.right, rect.bottom, GetRegionData(hRgn, 0, NULL) ); GetMetaRgn(hDC, hRgn); GetRgnBox(hRgn, & rect); Add(_T("Meta Region"), _T("size %d bytes, rgn box { %d, %d, %d, %d }"), GetRegionData(hRgn, 0, NULL), rect.left, rect.top, rect.right, rect.bottom); for (int i=1; i<=5; i++) { int rslt = GetRandomRgn(hDC, hRgn, i); if ( rslt==1 ) { GetRgnBox(hRgn, & rect); Add(_T("Random Region"), _T("size %d bytes, rgn box { %d, %d, %d, %d }"), GetRegionData(hRgn, 0, NULL), rect.left, rect.top, rect.right, rect.bottom); } else if ( rslt==0 ) Add(_T("Random Region"), _T("NULL"), 0); else Add(_T("Random Region"), _T("FAIL"), 0); } DeleteObject(hRgn); GetBoundsRect(hDC, & rect, 0); Add(_T("Bounds Rectangle"), _T("{ %d, %d, %d, %d }"), rect.left, rect.top, rect.right, rect.bottom); }
BOOL WINAPI _export BLExtTextOut(HDC hDC, int x, int y, UINT fuOpt, const RECT FAR* lprc, LPCSTR lpStr, UINT cbLen, int FAR* lpDx) { POINT pt ; HWND hWDC ; HWND hWPT ; #ifdef _DEBUG DbgPrintf("NhWSrh.DLL BLExtTextOut Begin"); DbgPrintf("NhWSrh.DLL BLExtTextOut hDC: %d, x: %d, y: %d, fuOpt: %d, cbLen: %d", hDC, x, y, fuOpt, cbLen); #endif // restore the old textout. RestoreWinApi(&g_ExtTextOutHook); //Added by XGL, Nov 3rd, 1998 //We cannot get corret word with Explorer as background window //in Windows98, so this situation must be dealt with. pt.x = g_CurMousePos.x; pt.y = g_CurMousePos.y ; hWDC = WindowFromDC(hDC) ; hWPT = WindowFromPoint(pt) ; if (hWDC == NULL || hWPT == hWDC || IsParentOrSelf(hWPT, hWDC) || IsParentOrSelf(hWDC, hWPT)) { //Adding ends. XGL, Nov 3rd, 1998 if ((g_bAllowGetCurWord) && (!IsBadReadPtr(lpStr, cbLen)) && (cbLen > 0)) { g_nTextAlign = GetTextAlign(hDC); g_nExtra = GetTextCharacterExtra(hDC); GetCurrentPositionEx(hDC, &g_CurPos); GetTextMetrics(hDC, &g_tm); /////////////////////////////////////////////////////////////////////////// // Modify by Yan/Gang 1997/11/18 // 用於修改在计算 TA_CENTER 情况的失误。 g_dwDCOrg = 0; bRecAllRect = FALSE; GetStringRect(hDC, (LPSTR)lpStr, cbLen, x, y, &g_rcTotalRect, lpDx); bRecAllRect = TRUE; // End Modify /////////////////////////////////////////////////////////////////////////// if ((WindowFromDC != NULL)&&(WindowFromDC(hDC) == NULL)) { #ifdef _DEBUG DbgPrintf("NhWSrh.DLL BLTextOut WindowFromDC() == NULL"); DbgLPCSTR("NhWSrh.DLL BLTextOut: ", (LPSTR)lpStr, cbLen, TRUE); #endif // 赋零,用於避免MEMDC对串位置的影响· g_dwDCOrg = 0; AddToTextOutBuffer(hDC, (LPSTR)lpStr, cbLen, x, y, lpDx); } else { #ifdef _DEBUG DbgPrintf("NhWSrh.DLL BLTextOut WindowFromDC() != NULL"); DbgLPCSTR("NhWSrh.DLL BLTextOut: ", (LPSTR)lpStr, cbLen, TRUE); #endif g_dwDCOrg = GetDCOrg(hDC); GetCurMousePosWord(hDC, (LPSTR)lpStr, cbLen, x, y, lpDx); } } else { #ifdef _DEBUG DbgPrintf("NhWSrh.DLL BLExtTextOut ((!g_bAllowGetCurWord) || (IsBadReadPtr(lpStr, cbLen)) && (cbLen <= 0))"); if (!g_bAllowGetCurWord) { DbgPrintf("NhWSrh.DLL BLExtTextOut !g_bAllowGetCurWord"); } if (IsBadReadPtr(lpStr, cbLen)) { DbgPrintf("NhWSrh.DLL BLExtTextOut IsBadReadPtr()"); } if (cbLen <= 0) { DbgPrintf("NhWSrh.DLL BLExtTextOut cbLen <= 0"); } #endif } } // call old textout. ExtTextOut(hDC, x, y, fuOpt, lprc, lpStr, cbLen, lpDx); HookWinApi(&g_ExtTextOutHook, ONLYHOOK); #ifdef _DEBUG DbgPrintf("NhWSrh.DLL BLExtTextOut End"); #endif return (TRUE); }