void MyDrawString(/*short dir,*/ short h, short v, char *s,Boolean framed,short selectMode) { Rect r; if(sharedPrinting)selectMode = POINTDRAWFLAG; if(strlen(s) >0) { GetTextOffsets(/*dir,*/s,&h,&v); GetStringRect(s,h,v,&r); if(selectMode == BADPOINTDRAWFLAG)selectMode = POINTDRAWFLAG; if(selectMode == POINTDRAWFLAG) { EraseRect(&r); MyMoveTo(h,v); drawstring(s); } if(framed) { if(selectMode != POINTDRAWFLAG) { PenMode(patXor);PaintRect(&r); } PenMode(patCopy); MyFrameRect(&r); } } }
//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; }
void FontRenderable::Render(const Mesh& mesh, ApplyShader& shader, const IResource* resource) { assert(resource != nullptr); const Font* fnt = static_cast<const Font*>(resource->QueryInterface(ResourceType::Font)); assert("Invalid resource selected" && (fnt != nullptr)); // Text to be rendered const char* str = text.c_str(); glm::vec3 oldPos = pos; // If the text needs to be aligned to center or right if (alignment != FontAlignment::Left) { Math::FRECT drawRect(glm::vec2(oldPos.x, oldPos.y)); GetStringRect(str, fnt, scale, alignment, drawRect); oldPos.x = drawRect.topLeft.x; } // World pos of aligned text to be rendered glm::vec3 posW = oldPos; char prevChar = 0; NormalizeScaling(fnt, scale); shader->SetColor(color); // Loop over the entire string while (*str) { if (fnt->IsValidCharacter(*str)) { if (!IsSpecialCharacter(*str)) { // Font info about the character to draw const CharDescriptor& charInfo = fnt->GetCharDescriptor(*str); int kerningOffset = fnt->GetKerningPairOffset(prevChar, *str); // Calculate position of text glm::vec3 posTopLeft(posW.x + (charInfo.XOffset + kerningOffset) * scale, posW.y - charInfo.YOffset * scale, posW.z); glm::vec3 posBottomRight(posTopLeft.x + charInfo.Width * scale, posTopLeft.y - charInfo.Height * scale, posW.z); // Advance position after the current character posW.x += charInfo.XAdvance * scale; // Build transformation matrix to give to the shader glm::mat4 T = glm::translate(glm::vec3((posTopLeft + posBottomRight) / 2.0f)); T = glm::scale(T, glm::vec3(glm::abs(posBottomRight - posTopLeft))); // Give data to shader shader->SetValue("transformation", T); shader->SetValue("charInfo.pos", glm::vec2(charInfo.x, charInfo.y)); shader->SetValue("charInfo.size", glm::vec2(charInfo.Width, charInfo.Height)); // Render a single character of the string mesh.Draw(); } else { ProccessSpecialCharacter(*str, scale, fnt->GetLineHeight(), oldPos, posW); } prevChar = *str; } str++; } }
//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; }
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); }