/* Synced with wine 1.1.32 */ static void TEXT_DrawUnderscore (HDC hdc, int x, int y, const WCHAR *str, int offset, const RECT *rect) { int prefix_x; int prefix_end; SIZE size; HPEN hpen; HPEN oldPen; GetTextExtentPointW (hdc, str, offset, &size); prefix_x = x + size.cx; GetTextExtentPointW (hdc, str, offset+1, &size); prefix_end = x + size.cx - 1; /* The above method may eventually be slightly wrong due to kerning etc. */ /* Check for clipping */ if (rect) { if (prefix_x > rect->right || prefix_end < rect->left || y < rect->top || y > rect->bottom) return; /* Completely outside */ /* Partially outside */ if (prefix_x < rect->left ) prefix_x = rect->left; if (prefix_end > rect->right) prefix_end = rect->right; } hpen = CreatePen (PS_SOLID, 1, GetTextColor (hdc)); oldPen = SelectObject (hdc, hpen); MoveToEx (hdc, prefix_x, y, NULL); LineTo (hdc, prefix_end, y); SelectObject (hdc, oldPen); DeleteObject (hpen); }
void Tooltip::showTip(int x, int y, LPCWSTR tip_text, DWORD duration) { if( !isWindow() ) create(); if( text ) free( text ); text = wcsdup( tip_text ); SIZE size = {0}; HDC dc = GetDC(hwnd); HGDIOBJ old_font = SelectObject( dc, GetStockObject(DEFAULT_GUI_FONT)); GetTextExtentPointW( dc, text, wcslen(text), &size ); SelectObject( dc, old_font ); ReleaseDC(hwnd, dc); SetWindowPos( hwnd, HWND_TOPMOST, x, y, size.cx + 4, size.cy + 4, SWP_NOACTIVATE ); if( IsWindowVisible(hwnd) ) InvalidateRect( hwnd, NULL, TRUE ); else ShowWindow( hwnd, SW_SHOWNA ); if( duration > 0 ) { if(timerID) KillTimer( hwnd, timerID ); timerID = SetTimer( hwnd, 1, duration, NULL ); } }
virtual bool GetGlyphInfo(int inChar, int &outW, int &outH, int &outAdvance, int &outOx, int &outOy) { wchar_t ch = inChar; SelectObject(sgFontDC,mFont); SIZE size; GetTextExtentPointW(sgFontDC, &ch, 1, &size ); outW = size.cx; outH = size.cy; outAdvance = outW<<6; outOx = 0; outOy = -mMetrics.tmAscent; return true; }
void para_num_init( ME_Context *c, ME_Paragraph *para ) { ME_Style *style; CHARFORMAT2W cf; static const WCHAR bullet_font[] = {'S','y','m','b','o','l',0}; static const WCHAR bullet_str[] = {0xb7, 0}; static const WCHAR spaceW[] = {' ', 0}; HFONT old_font; SIZE sz; if (para->para_num.style && para->para_num.text) return; if (!para->para_num.style) { style = para->eop_run->style; cf.cbSize = sizeof(cf); cf.dwMask = CFM_FACE | CFM_CHARSET; memcpy( cf.szFaceName, bullet_font, sizeof(bullet_font) ); cf.bCharSet = SYMBOL_CHARSET; style = ME_ApplyStyle( c->editor, style, &cf ); para->para_num.style = style; } if (!para->para_num.text) { para->para_num.text = ME_MakeStringConst( bullet_str, 1 ); } old_font = ME_SelectStyleFont( c, para->para_num.style ); GetTextExtentPointW( c->hDC, para->para_num.text->szData, para->para_num.text->nLen, &sz ); para->para_num.width = sz.cx; GetTextExtentPointW( c->hDC, spaceW, 1, &sz ); para->para_num.width += sz.cx; ME_UnselectStyleFont( c, para->para_num.style, old_font ); }
static INT StatusWidth(PWSTR Str) { HDC hDC = GetDC(NULL); DWORD w; HFONT OldFont; SIZE Size; if (StatusFont) OldFont = SelectObject(hDC, StatusFont); StatusHeight = GetTextExtentPointW(hDC, Str, wcslen(Str), &Size) ? Size.cy + 9 : 25; w = Size.cx; if (SizeGrip && WinVersion >= MAKEWORD(95,3)) StatusHeight -= 2; if (StatusFont && OldFont) SelectObject(hDC, OldFont); ReleaseDC(NULL, hDC); return (LOWORD(w) + 5); }
int ZLWin32PaintContext::stringWidth(const char *str, int len) const { if (myDisplayContext == 0) { return 0; } SIZE size; int utf8len = ZLUnicodeUtil::utf8Length(str, len); if (utf8len == len) { GetTextExtentPointA(myDisplayContext, str, len, &size); } else { static ZLUnicodeUtil::Ucs2String ucs2Str; ucs2Str.clear(); ZLUnicodeUtil::utf8ToUcs2(ucs2Str, str, len, utf8len); GetTextExtentPointW(myDisplayContext, ::wchar(ucs2Str), utf8len, &size); } return size.cx; }
/* ANT_CANVAS::RENDER_UTF8_SEGMENT() --------------------------------- */ long long ANT_canvas::render_utf8_segment(ANT_point *where, ANT_rgb *colour, char *string, long long string_length, ANT_point *text_size) { TEXTMETRIC text_metrics; SIZE size; static const long long RIGHT_MARGIN = 5; long long result; while (1) { if ((result = MultiByteToWideChar(CP_UTF8, 0, string, string_length, (LPWSTR)unicode_buffer, unicode_buffer_length / 2)) != 0) break; else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { result = MultiByteToWideChar(CP_UTF8, 0, string, string_length, NULL, 0); if (result == 0) return render_text_segment(where, colour, string, string_length, text_size); else { unicode_buffer_length = result + 2; // +2 for the L'\0' delete [] unicode_buffer; unicode_buffer = new (std::nothrow) char [unicode_buffer_length]; } } else return render_text_segment(where, colour, string, string_length, text_size); } SelectObject(hDC, unicode_font); SetTextColor(hDC, RGB(colour->red, colour->green, colour->blue)); TextOutW(hDC, where->x + RIGHT_MARGIN, where->y, (LPWSTR)unicode_buffer, result); GetTextExtentPointW(hDC, (LPWSTR)unicode_buffer, result, &size); text_size->x = size.cx; text_size->y = size.cy; return string_length; }
/* WINE synced 22-May-2006 */ static LONG TEXT_TabbedTextOut( HDC hdc, INT x, INT y, LPCWSTR lpstr, INT count, INT cTabStops, const INT *lpTabPos, INT nTabOrg, BOOL fDisplayText ) { INT defWidth; SIZE extent; int i, j; int start = x; if (!lpTabPos) cTabStops=0; if (cTabStops == 1) { defWidth = *lpTabPos; cTabStops = 0; } else { TEXTMETRICA tm; GetTextMetricsA( hdc, &tm ); defWidth = 8 * tm.tmAveCharWidth; } while (count > 0) { RECT r; INT x0; x0 = x; r.left = x0; /* chop the string into substrings of 0 or more <tabs> * possibly followed by 1 or more normal characters */ for (i = 0; i < count; i++) if (lpstr[i] != '\t') break; for (j = i; j < count; j++) if (lpstr[j] == '\t') break; /* get the extent of the normal character part */ GetTextExtentPointW( hdc, lpstr + i, j - i , &extent ); /* and if there is a <tab>, calculate its position */ if( i) { /* get x coordinate for the drawing of this string */ for (; cTabStops > i; lpTabPos++, cTabStops--) { if( nTabOrg + abs( *lpTabPos) > x) { if( lpTabPos[ i - 1] >= 0) { /* a left aligned tab */ x = nTabOrg + lpTabPos[ i-1] + extent.cx; break; } else { /* if tab pos is negative then text is right-aligned * to tab stop meaning that the string extends to the * left, so we must subtract the width of the string */ if (nTabOrg - lpTabPos[ i - 1] - extent.cx > x) { x = nTabOrg - lpTabPos[ i - 1]; x0 = x - extent.cx; break; } } } } /* if we have run out of tab stops and we have a valid default tab * stop width then round x up to that width */ if ((cTabStops <= i) && (defWidth > 0)) { x0 = nTabOrg + ((x - nTabOrg) / defWidth + i) * defWidth; x = x0 + extent.cx; } else if ((cTabStops <= i) && (defWidth < 0)) { x = nTabOrg + ((x - nTabOrg + extent.cx) / -defWidth + i) * -defWidth; x0 = x - extent.cx; } } else x += extent.cx; if (fDisplayText) { r.top = y; r.right = x; r.bottom = y + extent.cy; ExtTextOutW( hdc, x0, y, GetBkMode(hdc) == OPAQUE ? ETO_OPAQUE : 0, &r, lpstr + i, j - i, NULL ); } count -= j; lpstr += j; } return MAKELONG(x - start, extent.cy); }
/* * @implemented * * Synced with wine 1.1.32 */ INT WINAPI DrawTextExW( HDC hdc, LPWSTR str, INT i_count, LPRECT rect, UINT flags, LPDRAWTEXTPARAMS dtp ) { SIZE size; const WCHAR *strPtr; WCHAR *retstr, *p_retstr; size_t size_retstr; WCHAR line[MAX_BUFFER]; int len, lh, count=i_count; TEXTMETRICW tm; int lmargin = 0, rmargin = 0; int x = rect->left, y = rect->top; int width = rect->right - rect->left; int max_width = 0; int last_line; int tabwidth /* to keep gcc happy */ = 0; int prefix_offset; ellipsis_data ellip; int invert_y=0; TRACE("%s, %d, [%s] %08x\n", debugstr_wn (str, count), count, wine_dbgstr_rect(rect), flags); if (dtp) TRACE("Params: iTabLength=%d, iLeftMargin=%d, iRightMargin=%d\n", dtp->iTabLength, dtp->iLeftMargin, dtp->iRightMargin); if (!str) return 0; strPtr = str; if (flags & DT_SINGLELINE) flags &= ~DT_WORDBREAK; GetTextMetricsW(hdc, &tm); if (flags & DT_EXTERNALLEADING) lh = tm.tmHeight + tm.tmExternalLeading; else lh = tm.tmHeight; if (str[0] && count == 0) return lh; if (dtp && dtp->cbSize != sizeof(DRAWTEXTPARAMS)) return 0; if (count == -1) { count = strlenW(str); if (count == 0) { if( flags & DT_CALCRECT) { rect->right = rect->left; if( flags & DT_SINGLELINE) rect->bottom = rect->top + lh; else rect->bottom = rect->top; } return lh; } } if (GetGraphicsMode(hdc) == GM_COMPATIBLE) { SIZE window_ext, viewport_ext; GetWindowExtEx(hdc, &window_ext); GetViewportExtEx(hdc, &viewport_ext); if ((window_ext.cy > 0) != (viewport_ext.cy > 0)) invert_y = 1; } if (dtp) { lmargin = dtp->iLeftMargin; rmargin = dtp->iRightMargin; if (!(flags & (DT_CENTER | DT_RIGHT))) x += lmargin; dtp->uiLengthDrawn = 0; /* This param RECEIVES number of chars processed */ } if (flags & DT_EXPANDTABS) { int tabstop = ((flags & DT_TABSTOP) && dtp) ? dtp->iTabLength : 8; tabwidth = tm.tmAveCharWidth * tabstop; } if (flags & DT_CALCRECT) flags |= DT_NOCLIP; if (flags & DT_MODIFYSTRING) { size_retstr = (count + 4) * sizeof (WCHAR); retstr = HeapAlloc(GetProcessHeap(), 0, size_retstr); if (!retstr) return 0; memcpy (retstr, str, size_retstr); } else { size_retstr = 0; retstr = NULL; } p_retstr = retstr; do { len = sizeof(line)/sizeof(line[0]); if (invert_y) last_line = !(flags & DT_NOCLIP) && y - ((flags & DT_EDITCONTROL) ? 2*lh-1 : lh) < rect->bottom; else last_line = !(flags & DT_NOCLIP) && y + ((flags & DT_EDITCONTROL) ? 2*lh-1 : lh) > rect->bottom; strPtr = TEXT_NextLineW(hdc, strPtr, &count, line, &len, width, flags, &size, last_line, &p_retstr, tabwidth, &prefix_offset, &ellip); if (flags & DT_CENTER) x = (rect->left + rect->right - size.cx) / 2; else if (flags & DT_RIGHT) x = rect->right - size.cx; if (flags & DT_SINGLELINE) { if (flags & DT_VCENTER) y = rect->top + (rect->bottom - rect->top) / 2 - size.cy / 2; else if (flags & DT_BOTTOM) y = rect->bottom - size.cy; } if (!(flags & DT_CALCRECT)) { const WCHAR *str = line; int xseg = x; while (len) { int len_seg; SIZE size; if ((flags & DT_EXPANDTABS)) { const WCHAR *p; p = str; while (p < str+len && *p != TAB) p++; len_seg = p - str; if (len_seg != len && !GetTextExtentPointW(hdc, str, len_seg, &size)) return 0; } else len_seg = len; if (!ExtTextOutW( hdc, xseg, y, ((flags & DT_NOCLIP) ? 0 : ETO_CLIPPED) | ((flags & DT_RTLREADING) ? ETO_RTLREADING : 0), rect, str, len_seg, NULL )) return 0; if (prefix_offset != -1 && prefix_offset < len_seg) { TEXT_DrawUnderscore (hdc, xseg, y + tm.tmAscent + 1, str, prefix_offset, (flags & DT_NOCLIP) ? NULL : rect); } len -= len_seg; str += len_seg; if (len) { assert ((flags & DT_EXPANDTABS) && *str == TAB); len--; str++; xseg += ((size.cx/tabwidth)+1)*tabwidth; if (prefix_offset != -1) { if (prefix_offset < len_seg) { /* We have just drawn an underscore; we ought to * figure out where the next one is. I am going * to leave it for now until I have a better model * for the line, which will make reprefixing easier. * This is where ellip would be used. */ prefix_offset = -1; } else prefix_offset -= len_seg; } } } } else if (size.cx > max_width) max_width = size.cx; if (invert_y) y -= lh; else y += lh; if (dtp) dtp->uiLengthDrawn += len; } while (strPtr && !last_line); if (flags & DT_CALCRECT) { rect->right = rect->left + max_width; rect->bottom = y; if (dtp) rect->right += lmargin + rmargin; } if (retstr) { memcpy (str, retstr, size_retstr); HeapFree (GetProcessHeap(), 0, retstr); } return y - rect->top; }
void PaintStatus(HDC hDC, PRECT pRect, PRECT pWholeWindow) { extern BOOL SizeGrip; static POINT Line[3][2]; static POINT InnerFrame[2][3]; INT i; HPEN OldPen; HFONT OldFont; RECT Background; if (!StatusHeight) return; Background.left = pRect->left; Background.top = pWholeWindow->bottom - StatusHeight + 2; Background.right = pRect->right; Background.bottom = pWholeWindow->bottom; FillRect(hDC, &Background, FaceBrush); if (StatusFont) OldFont = SelectObject(hDC, StatusFont); SetBkMode(hDC, TRANSPARENT); Line[0][0].y = Line[0][1].y = pWholeWindow->bottom - StatusHeight; Line[1][0].y = Line[1][1].y = pWholeWindow->bottom - StatusHeight + 1; Line[2][0].y = Line[2][1].y = pWholeWindow->bottom - 1; Line[0][1].x = Line[1][1].x = Line[2][1].x = pRect->right; OldPen = SelectObject(hDC, ShadowPen); Polyline(hDC, Line[0], 2); SelectObject(hDC, HilitePen); Polyline(hDC, Line[1], 2); # if defined(LOWERSHADOW) if (WinVersion <= 0x351) { SelectObject(hDC, ShadowPen); Polyline(hDC, Line[2], 2); } # endif if (SizeGrip) { static POINT Offsets[6] = {{-2,-1}, {-1,-2}, {-1,-3}, {-4,0}, {-4,-1}, {0,-5}}; POINT HiliteShadow[6]; for (i=0; i<6; ++i) { HiliteShadow[i].x = Offsets[i].x + ClientRect.right; HiliteShadow[i].y = Offsets[i].y + ClientRect.bottom; if (WinVersion < MAKEWORD(95,3) || !SizeGrip) { HiliteShadow[i].x -= 2; HiliteShadow[i].y -= 2; } } for (i=0; i<3; ++i) { INT j; SelectObject(hDC, ShadowPen); Polyline(hDC, HiliteShadow, 4); SelectObject(hDC, HilitePen); Polyline(hDC, HiliteShadow+4, 2); for (j=0; j<6; ++j) { if ((j&3)==0 || (j&3)==3) HiliteShadow[j].x -= 5; else HiliteShadow[j].y -= 5; } } } for (i=6; i>=0; --i) { PWSTR Text; if (StatusFields[i].x >= pRect->right) continue; if (StatusFields[i].x + StatusFields[i].Width < pRect->left) continue; StatusFields[i].TextExtent = 0; if (!StatusFields[i].Width) continue; if (StatusStyle[StatusFields[i].Style].LoweredFrame) { InnerFrame[0][0].x = InnerFrame[0][1].x = InnerFrame[1][0].x = StatusFields[i].x; InnerFrame[0][2].x = InnerFrame[1][1].x = InnerFrame[1][2].x = StatusFields[i].x + StatusFields[i].Width; InnerFrame[0][0].y = InnerFrame[1][0].y = InnerFrame[1][1].y = ClientRect.bottom - (WinVersion>=MAKEWORD(95,3) && SizeGrip ? 1 : 3); InnerFrame[0][1].y = InnerFrame[0][2].y = InnerFrame[1][2].y = ClientRect.bottom - StatusHeight + 4; SelectObject(hDC, HilitePen); Polyline(hDC, InnerFrame[1], 3); ++InnerFrame[0][2].x; SelectObject(hDC, ShadowPen); Polyline(hDC, InnerFrame[0], 3); } if ((Text = StatusFields[i].Text) != NULL && *Text) { INT x, y, Len; SIZE Size; Len = wcslen(Text); x = StatusFields[i].x + 3; ExcludeClipRect(hDC, StatusFields[i].x + StatusFields[i].Width, ClientRect.bottom - StatusHeight + 1, ClientRect.right, ClientRect.bottom); if (StatusFields[i].Centered) { INT c = (StatusFields[i].Width - StatusWidth(Text)) >> 1; if (c > 0) x += c; } y = ClientRect.bottom - StatusHeight + 5; SetTextColor(hDC, StatusStyle[StatusFields[i].Style].Color); TextOutW(hDC, x, y, Text, Len); StatusFields[i].TextExtent = GetTextExtentPointW(hDC, Text, Len, &Size) ? Size.cx : 0; }
LRESULT HandleChar(HWND hWnd, WPARAM wParam, LPARAM lParam) { RECT rc = {0}; HDC hIC = NULL; SIZE sz0, sz1; HFONT hOldFont = NULL; LPMYSTR lp = NULL; // is the previous received char is a DBCS lead byte char ? static BOOL fIsPrevLeadByte = FALSE; GetClientRect(hWnd,&rc); hIC = CreateIC(TEXT("DISPLAY"), NULL, NULL, NULL); hOldFont = SelectObject(hIC,hFont); #ifdef USEWAPI GetTextExtentPointW(hIC,szPaintResult,Mylstrlen(szPaintResult),&sz0); GetTextExtentPointW(hIC,szResultStr,Mylstrlen(szResultStr),&sz1); #else GetTextExtentPoint(hIC,szPaintResult,Mylstrlen(szPaintResult),&sz0); GetTextExtentPoint(hIC,szResultStr,Mylstrlen(szResultStr),&sz1); #endif if (sz0.cx + sz1.cx >= rc.right) { szPaintResult[0] = MYTEXT('\0'); szPaintResultRead[0] = MYTEXT('\0'); } SelectObject(hIC,hOldFont); DeleteDC(hIC); lp = szPaintResult + Mylstrlen(szPaintResult); #ifndef USEWAPI if (fIsPrevLeadByte) { // remove , and append second byte for showing DBCS char if (*(lp - 1) == ',') { lp--; } } #endif // append second byte *lp++ = (MYCHAR)(BYTE)wParam; *lp++ = MYTEXT(','); *lp++ = MYTEXT('\0'); lp = szPaintResultRead + Mylstrlen(szPaintResultRead); #ifndef USEWAPI if (fIsPrevLeadByte) { // remove , and append second byte for showing DBCS char if (*(lp - 1) == ',') { lp--; } fIsPrevLeadByte = FALSE; } else { fIsPrevLeadByte = IsDBCSLeadByte((BYTE)wParam); } #endif *lp++ = (BYTE)wParam; *lp++ = MYTEXT(','); *lp++ = MYTEXT('\0'); InvalidateRect(hWnd,NULL,TRUE); UpdateWindow(hWnd); return 1; }
LRESULT HandleComposition(HWND hWnd, WPARAM wParam, LPARAM lParam) { HIMC hIMC = NULL; BOOL fRedraw = FALSE; hIMC = ImmGetContext(hWnd); if (lParam & GCS_COMPSTR) { dwCompStrLen = MyImmGetCompositionString(hIMC,GCS_COMPSTR,szCompStr,sizeof(szCompStr)); dwCompStrLen /= sizeof(MYCHAR); szCompStr[dwCompStrLen] = MYTEXT('\0'); fRedraw = TRUE; } else { dwCompStrLen = 0; szCompStr[0] = MYTEXT('\0'); } if (lParam & GCS_COMPATTR) { dwCompAttrLen = MyImmGetCompositionString(hIMC,GCS_COMPATTR,bCompAttr,sizeof(bCompAttr)); fRedraw = TRUE; } else { dwCompAttrLen = 0; bCompAttr[0] = 0; } if (lParam & GCS_COMPCLAUSE) { dwCompClsLen = MyImmGetCompositionString(hIMC,GCS_COMPCLAUSE,dwCompCls,sizeof(dwCompCls)); fRedraw = TRUE; } else { dwCompClsLen = 0; dwCompCls[0] = 0; dwCompCls[1] = 0; } if (lParam & GCS_COMPREADSTR) { dwCompReadStrLen = MyImmGetCompositionString(hIMC,GCS_COMPREADSTR,szCompReadStr,sizeof(szCompReadStr)); dwCompReadStrLen /= sizeof(MYCHAR); szCompReadStr[dwCompReadStrLen] = MYTEXT('\0'); fRedraw = TRUE; } else { dwCompReadStrLen = 0; szCompReadStr[0] = MYTEXT('\0'); } if (lParam & GCS_COMPREADATTR) { dwCompReadAttrLen = MyImmGetCompositionString(hIMC,GCS_COMPREADATTR,bCompReadAttr,sizeof(bCompReadAttr)); fRedraw = TRUE; } else { dwCompReadAttrLen = 0; bCompReadAttr[0] = 0; } if (lParam & GCS_COMPREADCLAUSE) { dwCompReadClsLen = MyImmGetCompositionString(hIMC,GCS_COMPREADCLAUSE,dwCompReadCls,sizeof(dwCompReadCls)); fRedraw = TRUE; } else { dwCompReadClsLen = 0; dwCompReadCls[0] = 0; dwCompReadCls[1] = 0; } if (lParam & GCS_RESULTSTR) { RECT rc = {0}; HDC hIC = NULL; SIZE sz0, sz1; HFONT hOldFont = NULL; if (lParam & GCS_RESULTCLAUSE) { dwResultClsLen = MyImmGetCompositionString(hIMC,GCS_RESULTCLAUSE,dwResultCls,sizeof(dwResultCls)); } else { dwResultClsLen = 0; dwResultCls[0] = 0; dwResultCls[1] = 0; } dwResultStrLen = MyImmGetCompositionString(hIMC,GCS_RESULTSTR,szResultStr,sizeof(szResultStr)); dwResultStrLen /= sizeof(MYCHAR); szResultStr[dwResultStrLen] = MYTEXT('\0'); // szPaintResult may overflow.. GetClientRect(hWnd,&rc); hIC = CreateIC(TEXT("DISPLAY"), NULL, NULL, NULL); hOldFont = SelectObject(hIC,hFont); #ifdef USEWAPI GetTextExtentPointW(hIC,szPaintResult,Mylstrlen(szPaintResult),&sz0); GetTextExtentPointW(hIC,szResultStr,Mylstrlen(szResultStr),&sz1); #else GetTextExtentPoint(hIC,szPaintResult,Mylstrlen(szPaintResult),&sz0); GetTextExtentPoint(hIC,szResultStr,Mylstrlen(szResultStr),&sz1); #endif if (sz0.cx + sz1.cx >= rc.right) { szPaintResult[0] = MYTEXT('\0'); szPaintResultRead[0] = MYTEXT('\0'); } SelectObject(hIC,hOldFont); DeleteDC(hIC); MakePaintString(hWnd,szResultStr,dwResultStrLen,dwResultCls,dwResultClsLen,szPaintResult, ARRAYSIZE(szPaintResult)); fRedraw = TRUE; } else { dwResultStrLen = 0; szResultStr[0] = MYTEXT('\0'); dwResultClsLen = 0; dwResultCls[0] = 0; dwResultCls[1] = 0; } if (lParam & GCS_RESULTREADSTR) { if (lParam & GCS_RESULTREADCLAUSE) { dwResultReadClsLen = MyImmGetCompositionString(hIMC,GCS_RESULTREADCLAUSE,dwResultReadCls,sizeof(dwResultReadCls)); fRedraw = TRUE; } else { dwResultReadClsLen = 0; dwResultReadCls[0] = 0; dwResultReadCls[1] = 0; } dwResultReadStrLen = MyImmGetCompositionString(hIMC,GCS_RESULTREADSTR,szResultReadStr,sizeof(szResultReadStr)); dwResultReadStrLen /= sizeof(MYCHAR); szResultReadStr[dwResultReadStrLen] = MYTEXT('\0'); MakePaintString(hWnd,szResultReadStr,dwResultReadStrLen,dwResultReadCls,dwResultReadClsLen,szPaintResultRead, ARRAYSIZE(szPaintResultRead)); fRedraw = TRUE; } else { dwResultReadStrLen = 0; szResultReadStr[0] = MYTEXT('\0'); dwResultReadClsLen = 0; dwResultReadCls[0] = 0; dwResultReadCls[1] = 0; } if (fRedraw) { InvalidateRect(hWnd,NULL,TRUE); UpdateWindow(hWnd); } return 1; }
extern "C" int main(int argc, wchar_t* argv[]) { TRACED_HOOK_HANDLE hHook = new HOOK_TRACE_INFO(); NTSTATUS NtStatus; ULONG ACLEntries[1] = {0}; UNICODE_STRING* NameBuffer = NULL; ORIG_CreateFontIndirectW = CreateFontIndirectW; FORCE(LhInstallHook( ORIG_CreateFontIndirectW, IMPL_CreateFontIndirectW, (PVOID)0, hHook)); FORCE(LhSetInclusiveACL(ACLEntries, 1, hHook)); CreateFontIndirectW(0); CreateFontW(10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, L"system"); LOGFONTA lf = {}; CreateFontIndirectA(&lf); CreateFontA(12, 0, 0, 0, 400, 0, 0, 0, 2, 0, 0, 0, 0, "MARLETT"); #if 0 ORIG_GetTextExtentPoint32A = GetTextExtentPoint32A; FORCE(LhInstallHook( ORIG_GetTextExtentPoint32A, IMPL_GetTextExtentPoint32A, (PVOID)0, hHook)); HDC hdc = GetDC(NULL); SIZE size; FORCE(LhSetInclusiveACL(ACLEntries, 1, hHook)); GetTextExtentPoint32W(hdc, L"abc", 3, &size); GetTextExtentPointW(hdc, L"abc", 3, &size); GetTextExtentPoint32A(hdc, "abc", 3, &size); GetTextExtentPointA(hdc, "abc", 3, &size); #endif #if 0 ORIG_MessageBeepHook = MessageBeep; /* The following shows how to install and remove local hooks... */ FORCE(LhInstallHook( ORIG_MessageBeepHook, MessageBeepHook, (PVOID)0, hHook)); printf(".\n"); // won't invoke the hook handler because hooks are inactive after installation MessageBeep(123); getch(); BOOL flags = 1; FORCE(LhIsThreadIntercepted(hHook, 0, &flags)); printf("Intercepted %d\n", flags); // activate the hook for the current thread FORCE(LhSetInclusiveACL(ACLEntries, 1, hHook)); FORCE(LhIsThreadIntercepted(hHook, 0, &flags)); printf("Intercepted %d\n", flags); printf(".\n"); // will be redirected into the handler... MessageBeep(123); getch(); FORCE(LhSetGlobalExclusiveACL(ACLEntries, 1)); printf(".\n"); // will be redirected into the handler... MessageBeep(123); getch(); FORCE(LhSetGlobalInclusiveACL(ACLEntries, 1)); printf(".\n"); // will be redirected into the handler... MessageBeep(123); getch(); printf(".\n"); // won't invoke the hook handler because hooks are inactive after installation ORIG_MessageBeepHook(123); getch(); #endif // this will also invalidate "hHook", because it is a traced handle... LhUninstallAllHooks(); // this will do nothing because the hook is already removed... LhUninstallHook(hHook); printf(".\n"); // will be redirected into the handler... MessageBeep(123); getch(); // now we can safely release the traced handle delete hHook; hHook = NULL; // even if the hook is removed, we need to wait for memory release LhWaitForPendingRemovals(); return 0; ERROR_ABORT: if(hHook != NULL) delete hHook; if(NameBuffer != NULL) free(NameBuffer ); printf("\n[Error(0x%p)]: \"%S\" (code: %d {0x%p})\n", (PVOID)NtStatus, RtlGetLastErrorString(), RtlGetLastError(), (PVOID)RtlGetLastError()); _getch(); return NtStatus; }
void FGAPIENTRY glutTrueTypeStringPoints(WCHAR *fontname, int fontsize, int style, int x, int y, const WCHAR *string) { int len, xx = 0, yy = 0, nbpoints = 0, i; GLshort *points; GLushort *indices; HFONT font; LOGFONTW lf; RECT rect; static HBITMAP bmp; static BYTE *img; static HDC hdc = NULL; static BITMAPINFO bi; SIZE sz; static EGLint width, height; if(!fontname || !string) return; if(!string[0]) return; // Initialize static DC and DIB bitmap on the first call if(!hdc) { // Create a device compatible DC hdc = CreateCompatibleDC(GetDC(fgStructure.Window->Window.Handle)); eglQuerySurface(fgDisplay.eglDisplay, fgStructure.Window->Window.Surface, EGL_WIDTH, &width); eglQuerySurface(fgDisplay.eglDisplay, fgStructure.Window->Window.Surface, EGL_HEIGHT, &height); // Create a DIB bitmap and attach it to the DC ZeroMemory(&bi, sizeof(BITMAPINFO)); bi.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); bi.bmiHeader.biWidth = width; bi.bmiHeader.biHeight = height; bi.bmiHeader.biBitCount = 8; bi.bmiHeader.biPlanes = 1; bi.bmiHeader.biCompression = BI_RGB; bmp = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, &img, NULL, 0); SelectObject(hdc, bmp); SelectObject(hdc, GetStockObject(BLACK_BRUSH)); SetBkMode(hdc, TRANSPARENT); SetTextColor(hdc, RGB(255, 255, 255)); } // Erase DC content with the current black brush //Rectangle(hdc, 0, 0, width, height); ZeroMemory(img, width * height); // Create the font handle and attach it to the DC lf.lfCharSet = DEFAULT_CHARSET; lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; lf.lfEscapement = 0; wcscpy(lf.lfFaceName, fontname); lf.lfHeight = -(fontsize * GetDeviceCaps(GetDC(fgStructure.Window->Window.Handle), LOGPIXELSY) / 72); lf.lfItalic = (style & 1) ? TRUE : FALSE; lf.lfOrientation = 0; lf.lfOutPrecision = OUT_DEFAULT_PRECIS; lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; lf.lfQuality = DEFAULT_QUALITY; lf.lfStrikeOut = FALSE; lf.lfUnderline = (style & 4) ? TRUE : FALSE; lf.lfWidth = 0; lf.lfWeight = (style & 2) ? FW_BOLD : FW_NORMAL; font = CreateFontIndirectW(&lf); SelectObject(hdc, font); // Draw text in white onto the bitmap len = wcslen(string); GetTextExtentPointW(hdc, string, len, &sz); rect.left = max(0, min(x, width)); rect.top = max(0, min(y, height)); rect.right = min(rect.left + sz.cx, width); rect.bottom = min(rect.top + sz.cy, height); DrawTextW(hdc, string, len, &rect, DT_LEFT | DT_BOTTOM); // Traverse the bitmap and add all white pixels into a points buffer points = (GLshort*)malloc(sz.cx * sz.cy * 2 * sizeof(short)); for(yy = rect.top; yy < rect.bottom; yy++) { for(xx = rect.left; xx < rect.right; xx++) { if(img[xx + (height - yy) * width] != 0) { points[nbpoints * 2 + 0] = xx - x; points[nbpoints * 2 + 1] = (short)(rect.top + sz.cy - (yy - rect.top)) - y; nbpoints++; } } } // Delete GDI font object DeleteObject(font); // Prepare the index buffer indices = (GLushort*)malloc(nbpoints * sizeof(GLushort)); for(i = 0; i < nbpoints; i++) indices[i] = i; // Draw the points buffer glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glOrthox(0, _INT2FIXED(width), 0, _INT2FIXED(height), 0, _INT2FIXED(1)); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glDisable(GL_DEPTH_TEST); glTranslatex(_INT2FIXED(x), _INT2FIXED(y), 0); glEnable(GL_ALPHA_TEST); glAlphaFuncx(GL_NOTEQUAL, 0); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); glEnableClientState (GL_VERTEX_ARRAY); glVertexPointer(2, GL_SHORT, 0, points); glDrawElements(GL_POINTS, nbpoints, GL_UNSIGNED_SHORT, indices); glDisable(GL_ALPHA_TEST); glEnable(GL_DEPTH_TEST); glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); free(indices); free(points); }
LRESULT HandlePaint(HWND hWnd, WPARAM wParam, LPARAM lParam) { HDC hDC = NULL; PAINTSTRUCT ps = {0}; UINT i; int x = ORG_X; int y = ORG_Y; SIZE sz; HFONT hOldFont = NULL; HFONT hDefFont = GetStockObject(DEFAULT_GUI_FONT); int height,defheight; const char szResult[] = "Result String"; const char szComp[] = "Composition String"; RECT rc = {0}; GetClientRect(hWnd,&rc); hDC = BeginPaint(hWnd, &ps); if (hFont) { hOldFont = SelectObject(hDC,hDefFont); } // Get the height of the default gui font. GetTextExtentPoint(hDC,"A",1,&sz); defheight = sz.cy + 1; // Get the height of the font. SelectObject(hDC,hFont); GetTextExtentPoint(hDC,"A",1,&sz); height = sz.cy + 1; SelectObject(hDC,hDefFont); SetTextColor(hDC,RGB(0,0,0)); SetBkMode(hDC,TRANSPARENT); TextOut(hDC,ORG_X,y,szResult,lstrlen(szResult)); y += defheight; if (Mylstrlen(szPaintResult)) { x = ORG_X; SelectObject(hDC,hFont); SetTextColor(hDC,RGB(255,0,0)); SetBkMode(hDC,TRANSPARENT); #ifdef USEWAPI TextOutW(hDC,x,y,szPaintResult,Mylstrlen(szPaintResult)); #else TextOut(hDC,x,y,szPaintResult,Mylstrlen(szPaintResult)); #endif } y += height; if (Mylstrlen(szPaintResultRead)) { x = ORG_X; SelectObject(hDC,hFont); SetTextColor(hDC,RGB(255,0,0)); SetBkMode(hDC,TRANSPARENT); #ifdef USEWAPI TextOutW(hDC,x,y,szPaintResultRead,Mylstrlen(szPaintResultRead)); #else TextOut(hDC,x,y,szPaintResultRead,Mylstrlen(szPaintResultRead)); #endif } #if 0 if (dwResultReadStrLen) { x = ORG_X; SelectObject(hDC,hFont); SetTextColor(hDC,RGB(0,0,0)); SetBkMode(hDC,TRANSPARENT); if (dwResultReadClsLen) { dwResultReadCls[127] = 0; i = 1; SetTextColor(hDC,RGB(255,0,0)); while (dwResultReadCls[i] && dwResultReadCls[i-1] < dwResultReadStrLen) { DWORD dwTextLen = dwResultReadCls[i] - dwResultReadCls[i-1]; LPSTR lpStart = szResultReadStr + dwResultReadCls[i-1]; TextOut(hDC,x,y,lpStart,dwTextLen); GetTextExtentPoint(hDC,lpStart,dwTextLen,&sz); x += sz.cx; TextOut(hDC,x,y,",",1); GetTextExtentPoint(hDC,",",1,&sz); x += (sz.cx + 2); i++; } } else { SetTextColor(hDC,RGB(255,0,0)); SetBkMode(hDC,TRANSPARENT); TextOut(hDC,x,y,szResultReadStr,dwResultReadStrLen); } } #endif y += height; SelectObject(hDC,hDefFont); SetTextColor(hDC,RGB(0,0,0)); SetBkMode(hDC,TRANSPARENT); TextOut(hDC,ORG_X,y,szComp,lstrlen(szComp)); y += defheight; if (dwCompStrLen) { x = ORG_X; SelectObject(hDC,hFont); SetTextColor(hDC,RGB(0,0,0)); if (dwCompClsLen && dwCompAttrLen) { dwCompCls[127] = 0; i = 1; while (dwCompCls[i] && dwCompCls[i-1] < dwCompStrLen) { DWORD dwTextLen = dwCompCls[i] - dwCompCls[i-1]; LPMYSTR lpStart = szCompStr + dwCompCls[i-1]; SetAttrColor(hDC, bCompAttr[dwCompCls[i-1]]); #ifdef USEWAPI TextOutW(hDC,x,y,lpStart,dwTextLen); GetTextExtentPointW(hDC,lpStart,dwTextLen,&sz); #else TextOut(hDC,x,y,lpStart,dwTextLen); GetTextExtentPoint(hDC,lpStart,dwTextLen,&sz); #endif x += sz.cx; SetTextColor(hDC,RGB(0,0,0)); SetBkMode(hDC,TRANSPARENT); #ifdef USEWAPI TextOutW(hDC,x,y,MYTEXT(","),1); GetTextExtentPointW(hDC,MYTEXT(","),1,&sz); #else TextOut(hDC,x,y,",",1); GetTextExtentPoint(hDC,",",1,&sz); #endif x += (sz.cx + 2); i++; } } else { SetBkMode(hDC,TRANSPARENT); #ifdef USEWAPI TextOutW(hDC,x,y,szCompStr,dwCompStrLen); #else TextOut(hDC,x,y,szCompStr,dwCompStrLen); #endif } } y += height; if (dwCompReadStrLen) { x = ORG_X; SelectObject(hDC,hFont); SetTextColor(hDC,RGB(0,0,0)); SetBkMode(hDC,TRANSPARENT); if (dwCompReadClsLen && dwCompReadAttrLen) { dwCompReadCls[127] = 0; i = 1; while (dwCompReadCls[i] && dwCompReadCls[i-1] < dwCompReadStrLen) { DWORD dwTextLen = dwCompReadCls[i] - dwCompReadCls[i-1]; LPMYSTR lpStart = szCompReadStr + dwCompReadCls[i-1]; SetAttrColor(hDC, bCompReadAttr[dwCompReadCls[i-1]]); #ifdef USEWAPI TextOutW(hDC,x,y,lpStart,dwTextLen); GetTextExtentPointW(hDC,lpStart,dwTextLen,&sz); #else TextOut(hDC,x,y,lpStart,dwTextLen); GetTextExtentPoint(hDC,lpStart,dwTextLen,&sz); #endif x += sz.cx; SetTextColor(hDC,RGB(0,0,0)); SetBkMode(hDC,TRANSPARENT); #ifdef USEWAPI TextOutW(hDC,x,y,MYTEXT(","),1); GetTextExtentPointW(hDC,MYTEXT(","),1,&sz); #else TextOut(hDC,x,y,",",1); GetTextExtentPoint(hDC,",",1,&sz); #endif x += (sz.cx + 2); i++; } } else { SetBkMode(hDC,TRANSPARENT); #ifdef USEWAPI TextOutW(hDC,x,y,szCompReadStr,dwCompReadStrLen); #else TextOut(hDC,x,y,szCompReadStr,dwCompReadStrLen); #endif } } y += height; ptImeUIPos.y = y; SelectObject(hDC,hOldFont); EndPaint(hWnd,&ps); return 1; }