void setvisualpage(int page) { POINT pos; if (hdc[page] == NULL) { allocate_new_graphic_page(page); } if (!bgiemu_handle_redraw && active_page == visual_page) { SelectObject(hdc[1], hBitmap[visual_page]); SelectClipRgn(hdc[1], NULL); BitBlt(hdc[1], -view_settings.left, -view_settings.top, window_width, window_height, hdc[0], -view_settings.left, -view_settings.top, SRCCOPY); SelectClipRgn(hdc[1], hRgn); GetCurrentPositionEx(hdc[0], &pos); MoveToEx(hdc[1], pos.x, pos.y, NULL); } SelectClipRgn(hdc[0], NULL); SelectClipRgn(hdc[1], NULL); SelectObject(hdc[1], hBitmap[page]); BitBlt(hdc[0], -view_settings.left, -view_settings.top, window_width, window_height, hdc[1], -view_settings.left, -view_settings.top, SRCCOPY); SelectClipRgn(hdc[0], hRgn); SelectClipRgn(hdc[1], hRgn); if (page != active_page) { SelectObject(hdc[1], hBitmap[active_page]); } if (active_page != visual_page) { GetCurrentPositionEx(hdc[1], &pos); MoveToEx(hdc[0], pos.x, pos.y, NULL); } visual_page = page; }
/***************************************************************************** * bFindRadialEllipseIntersection - Calculate the intersection of a radial * and an Ellipse. * * Play the ArcTo into a path then query the path for the first and * last points on the Arc. *****************************************************************************/ BOOL bFindRadialEllipseIntersection(PLOCALDC pLocalDC, INT x1, INT y1, INT x2, INT y2, INT x3, INT y3, INT x4, INT y4, LPPOINT pptStart, LPPOINT pptEnd) { BOOL b; POINT ptCP; b = FALSE; // assume failure // Save the current position in the helper DC. if (!GetCurrentPositionEx(pLocalDC->hdcHelper, &ptCP)) return(FALSE); // Do an ArcTo with the same start radial line. if (!ArcTo(pLocalDC->hdcHelper, x1, y1, x2, y2, x3, y3, x3, y3)) goto exit_bFindRadialEllipseIntersection; // Get the start point of the arc. It is the current position. if (!GetCurrentPositionEx(pLocalDC->hdcHelper, pptStart)) goto exit_bFindRadialEllipseIntersection; // Continue with the ArcTo with the same end radial line this time. if (!ArcTo(pLocalDC->hdcHelper, x1, y1, x2, y2, x4, y4, x4, y4)) goto exit_bFindRadialEllipseIntersection; // Get the end point of the arc. It is the current position. if (!GetCurrentPositionEx(pLocalDC->hdcHelper, pptEnd)) goto exit_bFindRadialEllipseIntersection; // Everything is golden. b = TRUE; exit_bFindRadialEllipseIntersection: // Restore the current position in the helper DC. if (!MoveToEx(pLocalDC->hdcHelper, ptCP.x, ptCP.y, (LPPOINT) NULL)) RIP("MF3216: bFindRadialEllipseIntersection, MoveToEx failed"); return(b); }
static void IsInsidePointW(const HDC DC, int X, int Y, LPCWSTR Str, int Count) { SIZE Size; if ((Count > 0) && GetTextExtentPoint32W(DC, Str, Count, &Size)) { DWORD Flags = GetTextAlign(DC); POINT Pt; RECT Rect; if (Flags & TA_UPDATECP) { GetCurrentPositionEx(DC, &Pt); } else { Pt.x = X; Pt.y = Y; } if (Flags & TA_CENTER) { Pt.x-=(Size.cx/2); } else if (Flags & TA_RIGHT) { Pt.x-=Size.cx; } if (Flags & TA_BASELINE) { TEXTMETRICW tm; GetTextMetricsW(DC, &tm); Pt.y-=tm.tmAscent; } else if (Flags & TA_BOTTOM) { Pt.y-=Size.cy; } LPtoDP(DC, &Pt, 1); Rect.left = Pt.x; Rect.right = Pt.x + Size.cx; Rect.top = Pt.y; Rect.bottom = Pt.y + Size.cy; // Bug: We don't check Pt.y here, as don't call PtInRect() directly, because // in Title bar, Start Menu, IE, FireFox, Opera etc., the Rect.top and Rect.bottom will be wrong. // I try to use GetDCOrgEx(DC, &Pt), but they are not normal HDC that Pt.x and Pt.y will equal to 0 in these cases. // And use GetWindowRect() then get Rect.left and Rect.top is only useful on Title bar. if (((Rect.left <= Rect.right) && (CurParams->Pt.x >= Rect.left) && (CurParams->Pt.x <= Rect.right)) || ((Rect.left > Rect.right) && (CurParams->Pt.x <= Rect.left) && (CurParams->Pt.x >= Rect.right))) { int BegPos; //if (PtInRect(&Rect, CurParams->Pt)) { CurParams->Active = !PtInRect(&Rect, CurParams->Pt); //CurParams->Active = FALSE; BegPos = (int)((abs((CurParams->Pt.x - Rect.left) / (Rect.right - Rect.left)) * (Count - 1)) + 0.5); while ((BegPos < Count - 1) && GetTextExtentPoint32W(DC, Str, BegPos + 1, &Size) && (Size.cx < CurParams->Pt.x - Rect.left)) BegPos++; while ((BegPos >= 0) && GetTextExtentPoint32W(DC, Str, BegPos + 1, &Size) && (Size.cx > CurParams->Pt.x - Rect.left)) BegPos--; if (BegPos < Count - 1) BegPos++; CurParams->BeginPos = BegPos; if (Count > 255) CurParams->WordLen = 255; else CurParams->WordLen = Count; CurParams->Unicode = TRUE; CopyMemory(CurParams->MatchedWordW, Str, CurParams->WordLen * sizeof(wchar_t)); } } }
int getY(void) { POINT point; ACL_ASSERT_BEGIN_PAINT; GetCurrentPositionEx(g_hmemdc, &point); return (int) point.y; }
void moveRel(int dx, int dy) { POINT point; ACL_ASSERT_BEGIN_PAINT; GetCurrentPositionEx(g_hmemdc, &point); MoveToEx(g_hmemdc, (int) point.x + dx, (int) point.y + dy,NULL); }
/* compute the bounds of an array of points, optionally including the current position */ static void get_points_bounds( RECTL *bounds, const POINT *pts, UINT count, HDC hdc ) { UINT i; if (hdc) { POINT cur_pt; GetCurrentPositionEx( hdc, &cur_pt ); bounds->left = bounds->right = cur_pt.x; bounds->top = bounds->bottom = cur_pt.y; } else if (count) { bounds->left = bounds->right = pts[0].x; bounds->top = bounds->bottom = pts[0].y; } else *bounds = empty_bounds; for (i = 0; i < count; i++) { bounds->left = min( bounds->left, pts[i].x ); bounds->right = max( bounds->right, pts[i].x ); bounds->top = min( bounds->top, pts[i].y ); bounds->bottom = max( bounds->bottom, pts[i].y ); } }
void Util::ArrowTo(HDC dc, const POINT &ptTo, double theta, double headWidth, bool bFill) { POINT pFrom = { 0, 0 }; POINT pBase = { 0, 0 }; POINT aptPoly[3]; double vecLine[2]; double vecLeft[2]; double fLength; double th; double ta; // get from point //MoveToEx(dc, 0, 0, &pFrom); GetCurrentPositionEx(dc, &pFrom); // set to point aptPoly[0].x = ptTo.x; aptPoly[0].y = ptTo.y; // build the line vector vecLine[0] = (double) aptPoly[0].x - pFrom.x; vecLine[1] = (double) aptPoly[0].y - pFrom.y; // build the arrow base vector - normal to the line vecLeft[0] = -vecLine[1]; vecLeft[1] = vecLine[0]; // setup length parameters fLength = sqrt(vecLine[0] * vecLine[0] + vecLine[1] * vecLine[1]); th = headWidth / (2.0 * fLength); ta = headWidth / (2.0 * (tan(theta) / 2.0) * fLength); // find the base of the arrow pBase.x = (int) (aptPoly[0].x + -ta * vecLine[0]); pBase.y = (int) (aptPoly[0].y + -ta * vecLine[1]); // build the points on the sides of the arrow aptPoly[1].x = (int) (pBase.x + th * vecLeft[0]); aptPoly[1].y = (int) (pBase.y + th * vecLeft[1]); aptPoly[2].x = (int) (pBase.x + -th * vecLeft[0]); aptPoly[2].y = (int) (pBase.y + -th * vecLeft[1]); MoveToEx(dc, pFrom.x, pFrom.y, NULL); // draw we're fillin'... if(bFill) { LineTo(dc, pBase.x, pBase.y); //aptPoly[0].x, aptPoly[0].y); Polygon(dc, aptPoly, 3); } // ... or even jes chillin'... else { LineTo(dc, pBase.x, pBase.y); LineTo(dc, aptPoly[1].x, aptPoly[1].y); LineTo(dc, aptPoly[0].x, aptPoly[0].y); LineTo(dc, aptPoly[2].x, aptPoly[2].y); LineTo(dc, pBase.x, pBase.y); MoveToEx(dc, aptPoly[0].x, aptPoly[0].y, NULL); } }
void lineRel(int dx, int dy) { POINT point; ACL_ASSERT_BEGIN_PAINT; GetCurrentPositionEx(g_hmemdc, &point); LineTo(g_hmemdc, (int) point.x + dx, (int) point.y + dy); }
/*********************************************************************** * EMFDRV_LineTo */ BOOL EMFDRV_LineTo( PHYSDEV dev, INT x, INT y ) { POINT pt; EMRLINETO emr; RECTL bounds; EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dev; emr.emr.iType = EMR_LINETO; emr.emr.nSize = sizeof(emr); emr.ptl.x = x; emr.ptl.y = y; if(!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE; GetCurrentPositionEx(physDev->hdc, &pt); bounds.left = min(x, pt.x); bounds.top = min(y, pt.y); bounds.right = max(x, pt.x); bounds.bottom = max(y, pt.y); EMFDRV_UpdateBBox( dev, &bounds ); return TRUE; }
void line(int x0, int y0, int x1, int y1) { POINT point; ACL_ASSERT_BEGIN_PAINT; GetCurrentPositionEx(g_hmemdc, &point); MoveToEx(g_hmemdc, x0, y0, NULL); LineTo(g_hmemdc, x1, y1); MoveToEx(g_hmemdc, point.x, point.y, NULL); }
static void IsInsidePointA(const HDC DC, int X, int Y, LPCSTR Str, int Count) { SIZE Size; if ((Count > 0) && GetTextExtentPoint32A(DC, Str, Count, &Size)) { DWORD Flags = GetTextAlign(DC); POINT Pt; RECT Rect; if (Flags & TA_UPDATECP) { GetCurrentPositionEx(DC, &Pt); } else { Pt.x = X; Pt.y = Y; } if (Flags & TA_CENTER) { Pt.x-=(Size.cx/2); } else if (Flags & TA_RIGHT) { Pt.x-=Size.cx; } if (Flags & TA_BASELINE) { TEXTMETRIC tm; GetTextMetricsA(DC, &tm); Pt.y-=tm.tmAscent; } else if (Flags & TA_BOTTOM) { Pt.y-=Size.cy; } LPtoDP(DC, &Pt, 1); Rect.left = Pt.x; Rect.right = Pt.x + Size.cx; Rect.top = Pt.y; Rect.bottom = Pt.y + Size.cy; if (((Rect.left <= Rect.right) && (CurParams->Pt.x >= Rect.left) && (CurParams->Pt.x <= Rect.right)) || ((Rect.left > Rect.right) && (CurParams->Pt.x <= Rect.left) && (CurParams->Pt.x >= Rect.right))) { int BegPos; //if (PtInRect(&Rect, CurParams->Pt)) { CurParams->Active = !PtInRect(&Rect, CurParams->Pt); //CurParams->Active = FALSE; BegPos = (int)((abs((CurParams->Pt.x - Rect.left) / (Rect.right - Rect.left)) * (Count - 1)) + 0.5); while ((BegPos < Count - 1) && GetTextExtentPoint32A(DC, Str, BegPos + 1, &Size) && (Size.cx < CurParams->Pt.x - Rect.left)) BegPos++; while ((BegPos >= 0) && GetTextExtentPoint32A(DC, Str, BegPos + 1, &Size) && (Size.cx > CurParams->Pt.x - Rect.left)) BegPos--; if (BegPos < Count - 1) BegPos++; CurParams->BeginPos = BegPos; if (Count > 255) CurParams->WordLen = 255; else CurParams->WordLen = Count; CurParams->Unicode = FALSE; CopyMemory(CurParams->MatchedWordA, Str, CurParams->WordLen); } } }
BOOL FAR PASCAL MGetCurrentPosition(HDC hdc, INT FAR * px, INT FAR * py) { DWORD dwLocation; dwLocation = GetCurrentPositionEx(hdc); if (px != NULL) *px = (INT)LOWORD(dwLocation); if (py != NULL) *py = (INT)HIWORD(dwLocation); return(TRUE); }
BOOL nulldrv_PolyBezierTo( PHYSDEV dev, const POINT *points, DWORD count ) { BOOL ret = FALSE; POINT *pts = HeapAlloc( GetProcessHeap(), 0, sizeof(POINT) * (count + 1) ); if (pts) { GetCurrentPositionEx( dev->hdc, &pts[0] ); memcpy( pts + 1, points, sizeof(POINT) * count ); ret = PolyBezier( dev->hdc, pts, count + 1 ); HeapFree( GetProcessHeap(), 0, pts ); } return ret; }
void setactivepage(int page) { if (hBitmap[page] == NULL) { allocate_new_graphic_page(page); } else { SelectObject(hdc[1], hBitmap[page]); } if (!bgiemu_handle_redraw && active_page == visual_page) { POINT pos; GetCurrentPositionEx(hdc[0], &pos); MoveToEx(hdc[1], pos.x, pos.y, NULL); } active_page = page; }
// This function draws a line from the current point to (x,y). The current // point is updated to (x,y) // void lineto( int x, int y ) { HDC hDC; WindowData* pWndData = BGI__GetWindowDataPtr( ); // The current position POINT cp; hDC = BGI__GetWinbgiDC( ); GetCurrentPositionEx( hDC, &cp ); LineTo( hDC, x, y ); BGI__ReleaseWinbgiDC( ); // The update rectangle does not contain the right or bottom edge. Thus // add 1 so the entire region is included. RECT rect = { min(cp.x,x), min(cp.y,y), max(cp.x,x)+1, max(cp.y,y)+1 }; RefreshWindow( &rect ); }
/*********************************************************************** * PSDRV_LineTo */ BOOL PSDRV_LineTo(PHYSDEV dev, INT x, INT y) { POINT pt[2]; TRACE("%d %d\n", x, y); GetCurrentPositionEx( dev->hdc, pt ); pt[1].x = x; pt[1].y = y; LPtoDP( dev->hdc, pt, 2 ); PSDRV_SetPen(dev); PSDRV_SetClip(dev); PSDRV_WriteMoveTo(dev, pt[0].x, pt[0].y ); PSDRV_WriteLineTo(dev, pt[1].x, pt[1].y ); PSDRV_DrawLine(dev); PSDRV_ResetClip(dev); return TRUE; }
/*********************************************************************** * PSDRV_PolyBezierTo */ BOOL PSDRV_PolyBezierTo( PHYSDEV dev, const POINT *pts, DWORD count ) { DWORD i; POINT *dev_pts; TRACE("\n"); count++; /* add initial position */ if (!(dev_pts = HeapAlloc( GetProcessHeap(), 0, count * sizeof(*dev_pts) ))) return FALSE; GetCurrentPositionEx( dev->hdc, dev_pts ); memcpy( dev_pts + 1, pts, (count - 1) * sizeof(*dev_pts) ); LPtoDP( dev->hdc, dev_pts, count ); PSDRV_WriteSpool(dev, "%PolyBezier\n",12); PSDRV_SetPen(dev); PSDRV_SetClip(dev); PSDRV_WriteMoveTo(dev, dev_pts[0].x, dev_pts[0].y ); for (i = 1; i < count; i += 3) PSDRV_WriteCurveTo( dev, dev_pts + i ); PSDRV_DrawLine(dev); PSDRV_ResetClip(dev); HeapFree( GetProcessHeap(), 0, dev_pts ); return TRUE; }
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static BOOL bNeedSave ; static DRUM drum ; static HMENU hMenu ; static int iTempo = 50, iIndexLast ; static TCHAR szFileName [MAX_PATH], szTitleName [MAX_PATH] ; HDC hdc ; int i, x, y ; PAINTSTRUCT ps ; POINT point ; RECT rect ; TCHAR * szError ; switch (message) { case WM_CREATE: // Initialize DRUM structure drum.iMsecPerBeat = 100 ; drum.iVelocity = 64 ; drum.iNumBeats = 32 ; DrumSetParams (&drum) ; // Other initialization cxChar = LOWORD (GetDialogBaseUnits ()) ; cyChar = HIWORD (GetDialogBaseUnits ()) ; GetWindowRect (hwnd, &rect) ; MoveWindow (hwnd, rect.left, rect.top, 77 * cxChar, 29 * cyChar, FALSE) ; hMenu = GetMenu (hwnd) ; // Initialize "Volume" scroll bar SetScrollRange (hwnd, SB_HORZ, 1, 127, FALSE) ; SetScrollPos (hwnd, SB_HORZ, drum.iVelocity, TRUE) ; // Initialize "Tempo" scroll bar SetScrollRange (hwnd, SB_VERT, 0, 100, FALSE) ; SetScrollPos (hwnd, SB_VERT, iTempo, TRUE) ; DoCaption (hwnd, szTitleName) ; return 0 ; case WM_COMMAND: switch (LOWORD (wParam)) { case IDM_FILE_NEW: if (bNeedSave && IDCANCEL == AskAboutSave (hwnd, szTitleName)) return 0 ; // Clear drum pattern for (i = 0 ; i < NUM_PERC ; i++) { drum.dwSeqPerc [i] = 0 ; drum.dwSeqPian [i] = 0 ; } InvalidateRect (hwnd, NULL, FALSE) ; DrumSetParams (&drum) ; bNeedSave = FALSE ; return 0 ; case IDM_FILE_OPEN: // Save previous file if (bNeedSave && IDCANCEL == AskAboutSave (hwnd, szTitleName)) return 0 ; // Open the selected file if (DrumFileOpenDlg (hwnd, szFileName, szTitleName)) { szError = DrumFileRead (&drum, szFileName) ; if (szError != NULL) { ErrorMessage (hwnd, szError, szTitleName) ; szTitleName [0] = '\0' ; } else { // Set new parameters iTempo = (int) (50 * (log10 (drum.iMsecPerBeat) - 1)) ; SetScrollPos (hwnd, SB_VERT, iTempo, TRUE) ; SetScrollPos (hwnd, SB_HORZ, drum.iVelocity, TRUE) ; DrumSetParams (&drum) ; InvalidateRect (hwnd, NULL, FALSE) ; bNeedSave = FALSE ; } DoCaption (hwnd, szTitleName) ; } return 0 ; case IDM_FILE_SAVE: case IDM_FILE_SAVE_AS: // Save the selected file if ((LOWORD (wParam) == IDM_FILE_SAVE && szTitleName [0]) || DrumFileSaveDlg (hwnd, szFileName, szTitleName)) { szError = DrumFileWrite (&drum, szFileName) ; if (szError != NULL) { ErrorMessage (hwnd, szError, szTitleName) ; szTitleName [0] = '\0' ; } else bNeedSave = FALSE ; DoCaption (hwnd, szTitleName) ; } return 0 ; case IDM_APP_EXIT: SendMessage (hwnd, WM_SYSCOMMAND, SC_CLOSE, 0L) ; return 0 ; case IDM_SEQUENCE_RUNNING: // Begin sequence if (!DrumBeginSequence (hwnd)) { ErrorMessage (hwnd, TEXT ("Could not start MIDI sequence -- ") TEXT ("MIDI Mapper device is unavailable!"), szTitleName) ; } else { CheckMenuItem (hMenu, IDM_SEQUENCE_RUNNING, MF_CHECKED) ; CheckMenuItem (hMenu, IDM_SEQUENCE_STOPPED, MF_UNCHECKED) ; } return 0 ; case IDM_SEQUENCE_STOPPED: // Finish at end of sequence DrumEndSequence (FALSE) ; return 0 ; case IDM_APP_ABOUT: DialogBox (hInst, TEXT ("AboutBox"), hwnd, AboutProc) ; return 0 ; } return 0 ; case WM_LBUTTONDOWN: case WM_RBUTTONDOWN: hdc = GetDC (hwnd) ; // Convert mouse coordinates to grid coordinates x = LOWORD (lParam) / cxChar - 40 ; y = 2 * HIWORD (lParam) / cyChar - 2 ; // Set a new number of beats of sequence if (x > 0 && x <= 32 && y < 0) { SetTextColor (hdc, RGB (255, 255, 255)) ; TextOut (hdc, (40 + drum.iNumBeats) * cxChar, 0, TEXT (":|"), 2); SetTextColor (hdc, RGB (0, 0, 0)) ; if (drum.iNumBeats % 4 == 0) TextOut (hdc, (40 + drum.iNumBeats) * cxChar, 0, TEXT ("."), 1) ; drum.iNumBeats = x ; TextOut (hdc, (40 + drum.iNumBeats) * cxChar, 0, TEXT (":|"), 2); bNeedSave = TRUE ; } // Set or reset a percussion instrument beat if (x >= 0 && x < 32 && y >= 0 && y < NUM_PERC) { if (message == WM_LBUTTONDOWN) drum.dwSeqPerc[y] ^= (1 << x) ; else drum.dwSeqPian[y] ^= (1 << x) ; DrawRectangle (hdc, x, y, drum.dwSeqPerc, drum.dwSeqPian) ; bNeedSave = TRUE ; } ReleaseDC (hwnd, hdc) ; DrumSetParams (&drum) ; return 0 ; case WM_HSCROLL: // Change the note velocity switch (LOWORD (wParam)) { case SB_LINEUP: drum.iVelocity -= 1 ; break ; case SB_LINEDOWN: drum.iVelocity += 1 ; break ; case SB_PAGEUP: drum.iVelocity -= 8 ; break ; case SB_PAGEDOWN: drum.iVelocity += 8 ; break ; case SB_THUMBPOSITION: drum.iVelocity = HIWORD (wParam) ; break ; default: return 0 ; } drum.iVelocity = max (1, min (drum.iVelocity, 127)) ; SetScrollPos (hwnd, SB_HORZ, drum.iVelocity, TRUE) ; DrumSetParams (&drum) ; bNeedSave = TRUE ; return 0 ; case WM_VSCROLL: // Change the tempo switch (LOWORD (wParam)) { case SB_LINEUP: iTempo -= 1 ; break ; case SB_LINEDOWN: iTempo += 1 ; break ; case SB_PAGEUP: iTempo -= 10 ; break ; case SB_PAGEDOWN: iTempo += 10 ; break ; case SB_THUMBPOSITION: iTempo = HIWORD (wParam) ; break ; default: return 0 ; } iTempo = max (0, min (iTempo, 100)) ; SetScrollPos (hwnd, SB_VERT, iTempo, TRUE) ; drum.iMsecPerBeat = (WORD) (10 * pow (100, iTempo / 100.0)) ; DrumSetParams (&drum) ; bNeedSave = TRUE ; return 0 ; case WM_PAINT: hdc = BeginPaint (hwnd, &ps) ; SetTextAlign (hdc, TA_UPDATECP) ; SetBkMode (hdc, TRANSPARENT) ; // Draw the text strings and horizontal lines for (i = 0 ; i < NUM_PERC ; i++) { MoveToEx (hdc, i & 1 ? 20 * cxChar : cxChar, (2 * i + 3) * cyChar / 4, NULL) ; TextOut (hdc, 0, 0, szPerc [i], lstrlen (szPerc [i])) ; GetCurrentPositionEx (hdc, &point) ; MoveToEx (hdc, point.x + cxChar, point.y + cyChar / 2, NULL) ; LineTo (hdc, 39 * cxChar, point.y + cyChar / 2) ; } SetTextAlign (hdc, 0) ; // Draw rectangular grid, repeat mark, and beat marks for (x = 0 ; x < 32 ; x++) { for (y = 0 ; y < NUM_PERC ; y++) DrawRectangle (hdc, x, y, drum.dwSeqPerc, drum.dwSeqPian) ; SetTextColor (hdc, x == drum.iNumBeats - 1 ? RGB (0, 0, 0) : RGB (255, 255, 255)) ; TextOut (hdc, (41 + x) * cxChar, 0, TEXT (":|"), 2) ; SetTextColor (hdc, RGB (0, 0, 0)) ; if (x % 4 == 0) TextOut (hdc, (40 + x) * cxChar, 0, TEXT ("."), 1) ; } EndPaint (hwnd, &ps) ; return 0 ; case WM_USER_NOTIFY: // Draw the "bouncing ball" hdc = GetDC (hwnd) ; SelectObject (hdc, GetStockObject (NULL_PEN)) ; SelectObject (hdc, GetStockObject (WHITE_BRUSH)) ; for (i = 0 ; i < 2 ; i++) { x = iIndexLast ; y = NUM_PERC + 1 ; Ellipse (hdc, (x + 40) * cxChar, (2 * y + 3) * cyChar / 4, (x + 41) * cxChar, (2 * y + 5) * cyChar / 4); iIndexLast = wParam ; SelectObject (hdc, GetStockObject (BLACK_BRUSH)) ; } ReleaseDC (hwnd, hdc) ; return 0 ; case WM_USER_ERROR: ErrorMessage (hwnd, TEXT ("Can't set timer event for tempo"), szTitleName) ; // fall through case WM_USER_FINISHED: DrumEndSequence (TRUE) ; CheckMenuItem (hMenu, IDM_SEQUENCE_RUNNING, MF_UNCHECKED) ; CheckMenuItem (hMenu, IDM_SEQUENCE_STOPPED, MF_CHECKED) ; return 0 ; case WM_CLOSE: if (!bNeedSave || IDCANCEL != AskAboutSave (hwnd, szTitleName)) DestroyWindow (hwnd) ; return 0 ; case WM_QUERYENDSESSION: if (!bNeedSave || IDCANCEL != AskAboutSave (hwnd, szTitleName)) return 1L ; return 0 ; case WM_DESTROY: DrumEndSequence (TRUE) ; PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; }
VOID TextTest(HDC hdc) { LOGFONT lfnt; // dummy logical font description HFONT hfont; // handle to dummy font HFONT hfontUnderline,hfontStrikeOut; // handle of font originally in DC HRGN hrgnTmp; int y; #ifdef DOS_PLATFORM #define MAX_LENGTH 80 char aBuffer[MAX_LENGTH]; #endif //DOS_PLATFORM // Create a logical font #ifndef DOS_PLATFORM memset(&lfnt, 0, sizeof(lfnt)); #else memzero(&lfnt, sizeof(lfnt)); #endif //DOS_PLATFORM lfnt.lfHeight = 24; lfnt.lfEscapement = 0; // mapper respects this filed lfnt.lfUnderline = 0; // no underline lfnt.lfStrikeOut = 0; // no strike out lfnt.lfItalic = 0; lfnt.lfWeight = 400; // normal strcpy(lfnt.lfFaceName, DEFAULT_FACENAME); if ((hfont = CreateFontIndirect(&lfnt)) == NULL) { DbgPrint("Logical font creation failed.\n"); return; } lfnt.lfUnderline = 1; // underline if ((hfontUnderline = CreateFontIndirect(&lfnt)) == NULL) { DbgPrint("Logical font creation failed.\n"); return; } lfnt.lfUnderline = 0; // underline lfnt.lfStrikeOut = 1; // no underline if ((hfontStrikeOut = CreateFontIndirect(&lfnt)) == NULL) { DbgPrint("Logical font creation failed.\n"); return; } // Select font into DC SelectObject(hdc, hfont); // Set text alignment SetTextAlign(hdc, TA_LEFT | TA_TOP | TA_NOUPDATECP); // // List the character widths vListCharWidths(hdc); vDoPause(0); // Clear screen BitBlt(hdc, 0, 0, MAX_CX, MAX_CY, (HDC) 0, 0, 0, BLACKNESS); SetTextColor(hdc, RGB(127,127,0)); SetBkColor(hdc, RGB(0,255,0)); // nonclipped underlined text // Select font into DC SelectObject(hdc, hfontUnderline); TextOut(hdc, 0, 0, "This is normal text.", 20); SelectObject(hdc, hfont); // Inverse text BitBlt(hdc, 0, 30, MAX_CX, 30, (HDC) 0, 0, 0, WHITENESS); SetROP2(hdc, R2_BLACK); TextOut(hdc, 0, 30, "This is inverse text.", 21); SetROP2(hdc, R2_WHITE); // Clipped text (simple retangular region) hrgnTmp = CreateRectRgn(10, 70, MAX_CX, 90); SelectClipRgn(hdc, hrgnTmp); DeleteObject(hrgnTmp); TextOut(hdc, 0, 60, "This is clipped text.", 21); // Clipped text (circular region) hrgnTmp = hrgnCircle(150, 240, 150); SelectClipRgn(hdc, hrgnTmp); DeleteObject(hrgnTmp); BitBlt(hdc, 0, 0, MAX_CX, MAX_CY, (HDC) 0, 0, 0, WHITENESS); SetROP2(hdc, R2_BLACK); SelectObject(hdc, hfontStrikeOut); TextOut(hdc, 0, 120, "There was a young man from Wight,", 33); TextOut(hdc, 0, 150, "Who travelled much faster then light.", 37); SelectObject(hdc, hfontUnderline); TextOut(hdc, 0, 180, "He left home one day", 20); TextOut(hdc, 0, 210, "In a relative way,", 18); TextOut(hdc, 0, 240, "And arrived home the previous night.", 36); hrgnTmp = CreateRectRgn(0, 0, MAX_CX, MAX_CY); SelectClipRgn(hdc, hrgnTmp); DeleteObject(hrgnTmp); SelectObject(hdc, hfont); SetTextColor(hdc, RGB(127,127,0)); { // check that update current position mode works properly SIZE size; POINT pt; PSZ pszExtent; LOGFONT lfntEsc; HFONT hfntOld, hfntEsc; vDoPause(0); BitBlt(hdc, 0, 0, MAX_CX, MAX_CY, (HDC) 0, 0, 0, WHITENESS); y = 30; TextOut(hdc, 0, y , "Once upon a time there was a young man from Wight,", strlen("Once upon a time there was a young man from Wight,")); y += 30; GetCurrentPositionEx(hdc,&pt); DbgPOINT(&pt,"before MoveToEx"); SetTextAlign(hdc, TA_LEFT | TA_TOP | TA_UPDATECP); MoveToEx(hdc, 0, y, &pt); GetCurrentPositionEx(hdc,&pt); DbgPOINT(&pt,"before " ); TextOut(hdc, 0, 0 , "Once upon a time ", strlen("Once upon a time ")); GetCurrentPositionEx(hdc,&pt); DbgPOINT(&pt,"after " ); // change bk color to observe another textOut call SetBkColor(hdc, RGB(0,0,255)); TextOut(hdc, 0, 0 , "there was a young man from Wight,", strlen("there was a young man from Wight,")); SetTextAlign(hdc, TA_LEFT | TA_TOP | TA_NOUPDATECP); SetBkColor(hdc, RGB(0,255,0)); // get text extent test, pszExtent = "iiiiiiiiii"; TextOut(hdc,200,100, pszExtent, strlen(pszExtent)); GetTextExtentPoint(hdc, pszExtent, strlen(pszExtent), &size); DbgPrint("%s, cx = %ld, cy = %ld\n", pszExtent, size.cx, size.cy); pszExtent = "iiiiWWiiii"; TextOut(hdc,200,150, pszExtent, strlen(pszExtent)); GetTextExtentPoint(hdc, pszExtent, strlen(pszExtent), &size); DbgPrint("%s, cx = %ld, cy = %ld\n", pszExtent, size.cx, size.cy); // see whether text extent works with font with escapement // Create a logical font #ifndef DOS_PLATFORM memset(&lfntEsc, 0, sizeof(lfnt)); #else memzero(&lfntEsc, sizeof(lfnt)); #endif //DOS_PLATFORM lfntEsc.lfHeight = 18; lfntEsc.lfEscapement = 450; // 45 degrees lfntEsc.lfUnderline = 0; // no underline lfntEsc.lfStrikeOut = 0; // no strike out lfntEsc.lfItalic = 0; lfntEsc.lfWeight = 400; // normal if ((hfntEsc = CreateFontIndirect(&lfntEsc)) == NULL) { DbgPrint("Logical font creation failed.\n"); return; } hfntOld = SelectObject(hdc, hfntEsc); pszExtent = "iiiiiiiiii"; TextOut(hdc,100,200, pszExtent, strlen(pszExtent)); GetTextExtentPoint(hdc, pszExtent, strlen(pszExtent), &size); DbgPrint("%s, cx = %ld, cy = %ld\n", pszExtent, size.cx, size.cy); Rectangle(hdc,100,300,100 + size.cx,300 + size.cy); pszExtent = "iiiiWWiiii"; TextOut(hdc,400,200, pszExtent, strlen(pszExtent)); GetTextExtentPoint(hdc, pszExtent, strlen(pszExtent), &size); DbgPrint("%s, cx = %ld, cy = %ld\n", pszExtent, size.cx, size.cy); Rectangle(hdc,400,300,400 + size.cx,300 + size.cy); SelectObject(hdc, hfntOld); } { // test for emboldening and italicizing char ach[] = {0,1,2,4,32,88}; HFONT hfontBold, hfontItalic, hfontBoldItalic, hfontOld; char * pszString = "string"; vDoPause(0); BitBlt(hdc, 0, 0, MAX_CX, MAX_CY, (HDC) 0, 0, 0, WHITENESS); lfnt.lfStrikeOut = 0; lfnt.lfWeight = 700; // bold if ((hfontBold = CreateFontIndirect(&lfnt)) == NULL) { DbgPrint("Logical font creation failed.\n"); return; } lfnt.lfWeight = 400; // normal lfnt.lfItalic = 1; if ((hfontItalic = CreateFontIndirect(&lfnt)) == NULL) { DbgPrint("Logical font creation failed.\n"); return; } lfnt.lfWeight = 700; // bold if ((hfontBoldItalic = CreateFontIndirect(&lfnt)) == NULL) { DbgPrint("Logical font creation failed.\n"); return; } lfnt.lfWeight = 400; // normal lfnt.lfItalic = 0; // trying a string of chars with couple of chars out of range of the font TextOut ( hdc, 40, 40, "trying a string of chars with couple of chars out of range of the font", strlen("trying a string of chars with couple of chars out of range of the font") ); TextOut(hdc, 80, 80, (LPSTR)ach, sizeof(ach)); vDoPause(0); BitBlt(hdc, 0, 0, MAX_CX, MAX_CY, (HDC) 0, 0, 0, WHITENESS); y = 40; TextOut(hdc, 0, y, "string" , strlen("string")); y += 40; bTextOut(hdc,hfontBold, 0, y, pszString); y += 40; bTextOut(hdc,hfontItalic, 0, y, pszString); y += 40; bTextOut(hdc,hfontBoldItalic, 0, y, pszString); // couple of more strings, just for the fun of it y += 80; bTextOut(hdc,hfontItalic, 0, y, "These are funny italic strings:" ); y += 40; bTextOut(hdc,hfontItalic, 0, y, "UuuuU" ); bTextOut(hdc,hfontItalic, 100, y, "WvvvW" ); bTextOut(hdc,hfontItalic, 200, y, "VvvvV" ); bTextOut(hdc,hfontItalic, 300, y, "YyyyY" ); bTextOut(hdc,hfontItalic, 400, y, " 2 break chars " ); y += 80; bTextOut(hdc,hfontBoldItalic, 0, y, "These are silly bold italic strings:" ); y += 40; bTextOut(hdc,hfontBoldItalic, 0, y, "UuuuU" ); bTextOut(hdc,hfontBoldItalic, 100, y, "WvvvW" ); bTextOut(hdc,hfontBoldItalic, 200, y, "VvvvV" ); bTextOut(hdc,hfontBoldItalic, 300, y, "YyyyY" ); bTextOut(hdc,hfontBoldItalic, 400, y, " 2 break chars " ); DeleteObject(hfontBold); DeleteObject(hfontItalic); DeleteObject(hfontBoldItalic); } { // test fonts that are both emboldened and/or // italicized and striked out and/or outlined HFONT hfontBoldStrikeUnder, hfontItalicUnder, hfontBoldItalicUnder, hfontItalicStrike, hfontBoldItalicStrikeUnder; // wow, what a font !!! char * pszString = "string"; vDoPause(0); BitBlt(hdc, 0, 0, MAX_CX, MAX_CY, (HDC) 0, 0, 0, WHITENESS); lfnt.lfItalic = 0; lfnt.lfWeight = 700; // bold lfnt.lfStrikeOut = 1; lfnt.lfUnderline = 1; if ((hfontBoldStrikeUnder = CreateFontIndirect(&lfnt)) == NULL) { DbgPrint("Logical font creation failed.\n"); return; } lfnt.lfItalic = 1; lfnt.lfWeight = 400; lfnt.lfStrikeOut = 0; lfnt.lfUnderline = 1; if ((hfontItalicUnder = CreateFontIndirect(&lfnt)) == NULL) { DbgPrint("Logical font creation failed.\n"); return; } lfnt.lfItalic = 1; lfnt.lfWeight = 700; lfnt.lfStrikeOut = 0; lfnt.lfUnderline = 1; if ((hfontBoldItalicUnder = CreateFontIndirect(&lfnt)) == NULL) { DbgPrint("Logical font creation failed.\n"); return; } lfnt.lfItalic = 1; lfnt.lfWeight = 400; lfnt.lfStrikeOut = 1; lfnt.lfUnderline = 0; if ((hfontItalicStrike = CreateFontIndirect(&lfnt)) == NULL) { DbgPrint("Logical font creation failed.\n"); return; } lfnt.lfItalic = 1; lfnt.lfWeight = 700; lfnt.lfStrikeOut = 1; lfnt.lfUnderline = 1; if ((hfontBoldItalicStrikeUnder = CreateFontIndirect(&lfnt)) == NULL) { DbgPrint("Logical font creation failed.\n"); return; } // "clear" logfont lfnt.lfItalic = 0; lfnt.lfWeight = 400; lfnt.lfStrikeOut = 0; lfnt.lfUnderline = 0; y = 40; bTextOut(hdc,hfont, 20, y, "Normal font : YYYYYY"); y += 40; bTextOut(hdc,hfontBoldStrikeUnder, 20, y, "Bold Striked Out and Underlined font : YYYY"); y += 40; bTextOut(hdc,hfontItalicUnder, 20, y, "Italicized Underlined font: YYYY"); y += 40; bTextOut(hdc,hfontBoldItalicUnder, 20, y, "Underlined Bold Italic font :askpW"); y += 40; bTextOut(hdc,hfontItalicStrike, 20, y, "Striked Out Italic font :askpW"); y += 40; bTextOut(hdc,hfontBoldItalicStrikeUnder, 20, y, "Underlined and Striked Out Bold Italic font :askpW"); DeleteObject(hfontBoldStrikeUnder); DeleteObject(hfontItalicUnder); DeleteObject(hfontBoldItalicUnder); DeleteObject(hfontItalicStrike); DeleteObject(hfontBoldItalicStrikeUnder); } { // check whether mapper can select different sizes from an *.fon file // and choose bold, italic and bold_italic fonts HFONT hfontHt; short alfHeight[6] = {13, 16, 19, 23, 27, 35}; int iHt; int iName; PSZ pszComment = "Trying to map to the face name: "; for (iName = 0; iName < sizeof(apszFaceName)/4; iName++) { #ifndef DOS_PLATFORM memset(&lfnt, 0, sizeof(lfnt)); #else memzero(&lfnt, sizeof(lfnt)); #endif //DOS_PLATFORM strcpy(lfnt.lfFaceName, apszFaceName[iName]); vDoPause(0); BitBlt(hdc, 0, 0, MAX_CX, MAX_CY, (HDC) 0, 0, 0, WHITENESS); lfnt.lfItalic = 0; lfnt.lfWeight = 400; lfnt.lfStrikeOut = 0; lfnt.lfUnderline = 0; SetTextAlign(hdc, TA_UPDATECP); MoveToEx(hdc,60,40,NULL); TextOut(hdc,0,0,pszComment, strlen(pszComment)); TextOut(hdc, 0, 0, apszFaceName[iName], strlen(apszFaceName[iName])); SetTextAlign(hdc, TA_NOUPDATECP); y = 80; for (iHt = 0L; iHt < 6L; iHt++) { lfnt.lfHeight = alfHeight[iHt]; if ((hfontHt = CreateFontIndirect(&lfnt)) == NULL) { DbgPrint("Logical font creation failed.\n"); return; } bTextOut(hdc,hfontHt, 20, y, "Normal: Different font sizes from an *.fon file"); y += 40; DeleteObject(hfontHt); } vDoPause(0); BitBlt(hdc, 0, 0, MAX_CX, MAX_CY, (HDC) 0, 0, 0, WHITENESS); SetTextAlign(hdc, TA_UPDATECP); MoveToEx(hdc,60,40,NULL); TextOut(hdc,0,0,pszComment, strlen(pszComment)); TextOut(hdc, 0, 0, apszFaceName[iName], strlen(apszFaceName[iName])); SetTextAlign(hdc, TA_NOUPDATECP); lfnt.lfItalic = 1; lfnt.lfWeight = 700; lfnt.lfStrikeOut = 0; lfnt.lfUnderline = 0; y = 80; for (iHt = 0L; iHt < 6L; iHt++) { lfnt.lfHeight = alfHeight[iHt]; if ((hfontHt = CreateFontIndirect(&lfnt)) == NULL) { DbgPrint("Logical font creation failed.\n"); return; } bTextOut(hdc,hfontHt, 20, y, "Bold Italic: Different font sizes from an *.fon file"); y += 40; DeleteObject(hfontHt); } } } { vDoPause(0); // this part of the test tests the SetTextJustification functionality BitBlt(hdc, 0, 0, MAX_CX, MAX_CY, (HDC) 0, 0, 0, WHITENESS); y = 30; // first print strings without justification to see how long they are TextOut(hdc, 0, y , "There was a young man from Wight,", 33); // 120 TextOut(hdc, 0, y + 30 , "Who travelled much faster then light.", 37); // 150 TextOut(hdc, 0, y + 60 , "He left home one day", 20); // 180 TextOut(hdc, 0, y + 90 , "In a relative way,", 18); // 210 TextOut(hdc, 0, y + 120 , "And arrived home the previous night.", 36); // 240 y += 190; // coerce strings to have total length CX_LEN by addjusting spaces that // correspond to break chars // add more space to break chars (positive dda) (CX_LEN > text extent) vJustify(hdc, 0, y , "There was a young man from Wight,", CX_LEN); // 120 vJustify(hdc, 0, y + 30 , "Who travelled much faster then light.",CX_LEN); // 150 vJustify(hdc, 0, y + 60 , "He left home one day", CX_LEN); // 180 vJustify(hdc, 0, y + 90 , "In a relative way,", CX_LEN); // 210 vJustify(hdc, 0, y + 120 , "And arrived home the previous night.", CX_LEN); // 240 } { vDoPause(0); // add more space to break chars (positive dda) (CX_LEN > text extent) BitBlt(hdc, 0, 0, MAX_CX, MAX_CY, (HDC) 0, 0, 0, WHITENESS); y = 30; // first print strings without justification to see how long they are TextOut(hdc, 0, y , "Once upon a time there was a young man from Wight,", strlen("Once upon a time there was a young man from Wight,")); TextOut(hdc, 0, y + 30 , "Who travelled much much much faster then light." , strlen("Who travelled much much much faster then light." )); TextOut(hdc, 0, y + 60 , "Nobody knows why he left home one day" , strlen("Nobody knows why he left home one day" )); // 180 TextOut(hdc, 0, y + 90 , "Nor why he did it in a very relative way," , strlen("Nor why he did it in a very relative way," )); // 210 TextOut(hdc, 0, y + 120 , "And arrived back home the previous night." , strlen("And arrived back home the previous night." )); y += 190; vJustify(hdc, 0, y , "Once upon a time there was a young man from Wight," ,CX_LEN); vJustify(hdc, 0, y + 30 , "Who travelled much much much faster then light." ,CX_LEN); vJustify(hdc, 0, y + 60 , "Nobody knows why he left home one day" ,CX_LEN); vJustify(hdc, 0, y + 90 , "Nor why he did it in a very relative way," ,CX_LEN); // 210 vJustify(hdc, 0, y + 120 , "And arrived back home the previous night." ,CX_LEN); } { vDoPause(0); // justifying two or more strings with a single set text justification BitBlt(hdc, 0, 0, MAX_CX, MAX_CY, (HDC) 0, 0, 0, WHITENESS); y = 30; TextOut(hdc, 0, y , "Once upon a time there was a young man from Wight,", strlen("Once upon a time there was a young man from Wight,")); y += 30; vJustify(hdc, 0, y , "Once upon a time there was a young man from Wight," ,CX_LEN); y += 30; vJustify2(hdc, 0, y , "Once upon a time there", " was a young man from Wight," ,CX_LEN); y += 30; vJustify3(hdc, 0, y , "Once upon a ti","me there was a young"," man from Wight," ,CX_LEN); y += 30; vJustify3(hdc, 0, y , "Once ","upon a time there was a young"," man from Wight," ,CX_LEN); y += 90; // this string is shorter than CX_LEN TextOut(hdc, 0, y , "There was a young man from Wight,", 33); // 120 y += 30; vJustify(hdc, 0, y , "There was a young man from Wight,", CX_LEN); // 120 y += 30; vJustify2(hdc, 0, y , "There was a y","oung man from Wight,", CX_LEN); // 120 y += 30; vJustify3(hdc, 0, y , "The","re was a young"," man from Wight,", CX_LEN); // 120 y += 30; vJustify3(hdc, 0, y , "There wa","s a young"," man from Wight,", CX_LEN); // 120 } }
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); }
/*********************************************************************** * EMFDRV_ArcChordPie */ static BOOL EMFDRV_ArcChordPie( PHYSDEV dev, INT left, INT top, INT right, INT bottom, INT xstart, INT ystart, INT xend, INT yend, DWORD iType ) { EMFDRV_PDEVICE *physDev = get_emf_physdev( dev ); INT temp, xCentre, yCentre, i; double angleStart, angleEnd; double xinterStart, yinterStart, xinterEnd, yinterEnd; EMRARC emr; RECTL bounds; if(left == right || top == bottom) return FALSE; if(left > right) {temp = left; left = right; right = temp;} if(top > bottom) {temp = top; top = bottom; bottom = temp;} if(GetGraphicsMode(dev->hdc) == GM_COMPATIBLE) { right--; bottom--; } emr.emr.iType = iType; emr.emr.nSize = sizeof(emr); emr.rclBox.left = left; emr.rclBox.top = top; emr.rclBox.right = right; emr.rclBox.bottom = bottom; emr.ptlStart.x = xstart; emr.ptlStart.y = ystart; emr.ptlEnd.x = xend; emr.ptlEnd.y = yend; /* Now calculate the BBox */ xCentre = (left + right + 1) / 2; yCentre = (top + bottom + 1) / 2; xstart -= xCentre; ystart -= yCentre; xend -= xCentre; yend -= yCentre; /* invert y co-ords to get angle anti-clockwise from x-axis */ angleStart = atan2( -(double)ystart, (double)xstart); angleEnd = atan2( -(double)yend, (double)xend); /* These are the intercepts of the start/end lines with the arc */ xinterStart = (right - left + 1)/2 * cos(angleStart) + xCentre; yinterStart = -(bottom - top + 1)/2 * sin(angleStart) + yCentre; xinterEnd = (right - left + 1)/2 * cos(angleEnd) + xCentre; yinterEnd = -(bottom - top + 1)/2 * sin(angleEnd) + yCentre; if(angleStart < 0) angleStart += 2 * M_PI; if(angleEnd < 0) angleEnd += 2 * M_PI; if(angleEnd < angleStart) angleEnd += 2 * M_PI; bounds.left = min(xinterStart, xinterEnd); bounds.top = min(yinterStart, yinterEnd); bounds.right = max(xinterStart, xinterEnd); bounds.bottom = max(yinterStart, yinterEnd); for(i = 0; i <= 8; i++) { if(i * M_PI / 2 < angleStart) /* loop until we're past start */ continue; if(i * M_PI / 2 > angleEnd) /* if we're past end we're finished */ break; /* the arc touches the rectangle at the start of quadrant i, so adjust BBox to reflect this. */ switch(i % 4) { case 0: bounds.right = right; break; case 1: bounds.top = top; break; case 2: bounds.left = left; break; case 3: bounds.bottom = bottom; break; } } /* If we're drawing a pie then make sure we include the centre */ if(iType == EMR_PIE) { if(bounds.left > xCentre) bounds.left = xCentre; else if(bounds.right < xCentre) bounds.right = xCentre; if(bounds.top > yCentre) bounds.top = yCentre; else if(bounds.bottom < yCentre) bounds.bottom = yCentre; } if (iType == EMR_ARCTO) { POINT pt; GetCurrentPositionEx( dev->hdc, &pt ); bounds.left = min( bounds.left, pt.x ); bounds.top = min( bounds.top, pt.y ); bounds.right = max( bounds.right, pt.x ); bounds.bottom = max( bounds.bottom, pt.y ); } if(!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE; if(!physDev->path) EMFDRV_UpdateBBox( dev, &bounds ); 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; }
int gety() { POINT pos; GetCurrentPositionEx(hdc[active_page == visual_page ? 0 : 1], &pos); return pos.y; }
void moverel(int dx, int dy) { POINT pos; GetCurrentPositionEx(hdc[1], &pos); moveto(pos.x + dx, pos.y + dy); }
//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 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; }
int CReadEMF::EnhMetaFileProc( HDC hhDC, // handle to device context HANDLETABLE FAR *lpHTable, // pointer to metafile handle table ENHMETARECORD FAR *lpEMFR, // pointer to metafile record int nObj // count of objects ) { CComPtr<IPDDocument> pddoc; m_group->get_document(&pddoc); // CESvgDocument* pDoc = (CESvgDocument*)lpData; // ASSERT(pDoc); switch (lpEMFR->iType) { // Do nothing for these records case EMR_HEADER: break; case EMR_GDICOMMENT: break; // Palette Stuff / Do nothing case EMR_CREATEPALETTE: { // PEMRCREATEPALETTE pEMR = (PEMRCREATEPALETTE)lpEMFR; TRACE("EMR_CREATEPALETTE (unhandled)\n"); } break; case EMR_SELECTPALETTE: { // PEMRSELECTPALETTE pEMR = (PEMRSELECTPALETTE)lpEMFR; TRACE("EMR_SELECTPALETTE (unhandled)\n"); } break; case EMR_REALIZEPALETTE: { // PEMRREALIZEPALETTE pEMR = (PEMRREALIZEPALETTE)lpEMFR; TRACE("EMR_REALIZEPALETTE (unhandled)\n"); } break; // Mapping mode and coordinate translations case EMR_SETMAPMODE: { TRACE("EMR_SETMAPMODE:\n"); PEMRSETMAPMODE pEMR = (PEMRSETMAPMODE)lpEMFR; ::SetMapMode(hDC, pEMR->iMode); } break; case EMR_SETVIEWPORTEXTEX: { TRACE("EMR_SETVIEWPORTEXTEX:\n"); PEMRSETVIEWPORTEXTEX pEMR = (PEMRSETVIEWPORTEXTEX)lpEMFR; ::SetViewportExtEx(hDC, pEMR->szlExtent.cx, pEMR->szlExtent.cy, NULL); } break; case EMR_SETWINDOWEXTEX: { TRACE("EMR_SETWINDOWEXTEX:\n"); PEMRSETWINDOWEXTEX pEMR = (PEMRSETWINDOWEXTEX)lpEMFR; ::SetWindowExtEx(hDC, pEMR->szlExtent.cx, pEMR->szlExtent.cy, NULL); } break; case EMR_SETVIEWPORTORGEX: { TRACE("EMR_SETVIEWPORTORGEX:\n"); PEMRSETVIEWPORTORGEX pEMR = (PEMRSETVIEWPORTORGEX)lpEMFR; ::SetViewportOrgEx(hDC, pEMR->ptlOrigin.x, pEMR->ptlOrigin.y, NULL); } break; case EMR_SETWINDOWORGEX: { TRACE("EMR_SETWINDOWORGEX:\n"); PEMRSETWINDOWORGEX pEMR = (PEMRSETWINDOWORGEX)lpEMFR; ::SetWindowOrgEx(hDC, pEMR->ptlOrigin.x, pEMR->ptlOrigin.y, NULL); } break; case EMR_SCALEVIEWPORTEXTEX: { TRACE("EMR_SCALEVIEWPORTEXTEX:\n"); PEMRSCALEVIEWPORTEXTEX pEMR = (PEMRSCALEVIEWPORTEXTEX)lpEMFR; ::ScaleViewportExtEx(hDC, pEMR->xNum, pEMR->xDenom, pEMR->yNum, pEMR->yDenom, NULL); } break; case EMR_SCALEWINDOWEXTEX: { TRACE("EMR_SCALEWINDOWEXTEX:\n"); PEMRSCALEWINDOWEXTEX pEMR = (PEMRSCALEWINDOWEXTEX)lpEMFR; ::ScaleWindowExtEx(hDC, pEMR->xNum, pEMR->xDenom, pEMR->yNum, pEMR->yDenom, NULL); } break; // GDI Objects case EMR_SELECTOBJECT: { TRACE("EMR_SELECTOBJECT\n"); PEMRSELECTOBJECT pEMR = (PEMRSELECTOBJECT)lpEMFR; CGdiObj* pObj = NULL; if (pEMR->ihObject & ENHMETA_STOCK_OBJECT) { int n = pEMR->ihObject & ~ENHMETA_STOCK_OBJECT; if (n >= 0 && n <= STOCK_LAST) { pObj = m_stockObjects[n]; } //::SelectObject(hDC, ::GetStockObject(pEMR->ihObject & ~ENHMETA_STOCK_OBJECT)); } else if (hTable[pEMR->ihObject]) { pObj = hTable[pEMR->ihObject]; //::SelectObject(hDC, hTable[pEMR->ihObject]); } if (pObj) { if (pObj->m_type == OBJ_BRUSH) m_pCurrentBrush = (CGdiBrush*)pObj; else if (pObj->m_type == OBJ_PEN) m_pCurrentPen = (CGdiPen*)pObj; } } break; case EMR_DELETEOBJECT: { TRACE("EMR_DELETEOBJECT\n"); PEMRDELETEOBJECT pEMR = (PEMRDELETEOBJECT)lpEMFR; if (hTable[pEMR->ihObject]) { delete hTable[pEMR->ihObject]; //::DeleteObject(hTable[pEMR->ihObject]); hTable[pEMR->ihObject] = NULL; } } break; case EMR_CREATEPEN: { TRACE("EMR_CREATEPEN\n"); PEMRCREATEPEN pEMR = (PEMRCREATEPEN)lpEMFR; /* HPEN hPen = ::CreatePenIndirect(&pEMR->lopn); hTable[pEMR->ihPen] = hPen; */ CGdiPen* pPen = new CGdiPen; pPen->m_elp.elpColor = pEMR->lopn.lopnColor; pPen->m_elp.elpWidth = pEMR->lopn.lopnWidth.x; pPen->m_elp.elpPenStyle = pEMR->lopn.lopnStyle; hTable[pEMR->ihPen] = pPen; } break; case EMR_EXTCREATEPEN: { TRACE("EMR_EXTCREATEPEN\n"); PEMREXTCREATEPEN pEMR = (PEMREXTCREATEPEN)lpEMFR; //PS_USERSTYLE #if 0 LOGBRUSH lb; lb.lbColor = pEMR->elp.elpColor; lb.lbHatch = 0; lb.lbStyle = BS_SOLID; HPEN hPen = ::ExtCreatePen(/*PS_SOLID | PS_GEOMETRIC*/pEMR->elp.elpPenStyle, pEMR->elp.elpWidth, &lb, pEMR->elp.elpNumEntries, NULL/*pEMR->elp.elpStyleEntry*/); ATLASSERT(hPen); hTable[pEMR->ihPen] = hPen; #endif CGdiPen* pPen = new CGdiPen; pPen->m_elp = pEMR->elp; hTable[pEMR->ihPen] = pPen; } break; case EMR_CREATEBRUSHINDIRECT: { TRACE("EMR_CREATEBRUSHINDIRECT\n"); PEMRCREATEBRUSHINDIRECT pEMR = (PEMRCREATEBRUSHINDIRECT)lpEMFR; //HBRUSH hBrush = ::CreateBrushIndirect((LOGBRUSH*)&pEMR->lb); //hTable[pEMR->ihBrush] = hBrush; CGdiBrush* pBrush = new CGdiBrush; pBrush->m_lb = pEMR->lb; hTable[pEMR->ihBrush] = pBrush; } break; case EMR_EXTCREATEFONTINDIRECTW: { TRACE("EMR_EXTCREATEFONTINDIRECTW\n"); /* PEMREXTCREATEFONTINDIRECTW pEMR = (PEMREXTCREATEFONTINDIRECTW)lpEMFR; HFONT hFont = ::CreateFontIndirect((LPLOGFONT)&pEMR->elfw); hTable[pEMR->ihFont] = hFont; */ } break; // Transformations case EMR_SETWORLDTRANSFORM: // TODO { TRACE("EMR_SETWORLDTRANSFORM (unhandled)\n"); } break; case EMR_MODIFYWORLDTRANSFORM: // TODO { TRACE("EMR_MODIFYWORLDTRANSFORM (unhandled)\n"); } break; // Regions case EMR_INTERSECTCLIPRECT: { TRACE("EMR_INTERSECTCLIPRECT (unhandled)\n"); } break; case EMR_EXTSELECTCLIPRGN: { PEMREXTSELECTCLIPRGN pEMR = (PEMREXTSELECTCLIPRGN)lpEMFR; TRACE("EMR_EXTSELECTCLIPRGN (unhandled)\n"); } break; // DC State case EMR_SAVEDC: { TRACE("EMR_SAVEDC\n"); PEMRSAVEDC pEMR = (PEMRSAVEDC)lpEMFR; ::SaveDC(hDC); } break; case EMR_RESTOREDC: { TRACE("EMR_RESTOREDC\n"); PEMRRESTOREDC pEMR = (PEMRRESTOREDC)lpEMFR; if (pEMR->iRelative > 0) { // AfxMessageBox("restoredc is positive!!"); pEMR->iRelative = -pEMR->iRelative; } ::RestoreDC(hDC, pEMR->iRelative); } break; // GDI Modes case EMR_SETTEXTCOLOR: { TRACE("EMR_SETTEXTCOLOR\n"); PEMRSETTEXTCOLOR pEMR = (PEMRSETTEXTCOLOR)lpEMFR; ::SetTextColor(hDC, pEMR->crColor); } break; case EMR_SETBKCOLOR: { TRACE("EMR_SETBKCOLOR\n"); PEMRSETBKCOLOR pEMR = (PEMRSETBKCOLOR)lpEMFR; ::SetBkColor(hDC, pEMR->crColor); } break; case EMR_SETBKMODE: { TRACE("EMR_SETBKMODE\n"); PEMRSETBKMODE pEMR = (PEMRSETBKMODE)lpEMFR; ::SetBkMode(hDC, pEMR->iMode); } break; case EMR_SETPOLYFILLMODE: { TRACE("EMR_SETPOLYFILLMODE\n"); PEMRSETPOLYFILLMODE pEMR = (PEMRSETPOLYFILLMODE)lpEMFR; ::SetPolyFillMode(hDC, pEMR->iMode); } break; case EMR_SETROP2: { TRACE("EMR_SETROP2\n"); PEMRSETROP2 pEMR = (PEMRSETROP2)lpEMFR; ::SetROP2(hDC, pEMR->iMode); } break; case EMR_SETMAPPERFLAGS: { TRACE("EMR_SETMAPPERFLAGS\n"); PEMRSETMAPPERFLAGS pEMR = (PEMRSETMAPPERFLAGS)lpEMFR; ::SetMapperFlags(hDC, pEMR->dwFlags); } break; case EMR_MOVETOEX: { TRACE("EMR_MOVETOEX\n"); PEMRMOVETOEX pEMR = (PEMRMOVETOEX)lpEMFR; ::MoveToEx(hDC, pEMR->ptl.x, pEMR->ptl.y, NULL); m_startPt.x = pEMR->ptl.x; m_startPt.y = pEMR->ptl.y; if (m_curSubPath) // Start new subpath { m_curSubPath.Release(); } } break; case EMR_SETMITERLIMIT: { TRACE("EMR_SETMITERLIMIT\n"); PEMRSETMITERLIMIT pEMR = (PEMRSETMITERLIMIT)lpEMFR; ::SetMiterLimit(hDC, pEMR->eMiterLimit, NULL); } break; case EMR_BEGINPATH: { TRACE("EMR_BEGINPATH\n"); if (m_curFrame == NULL) { pddoc->createObjectFrame(&m_curFrame); m_curFrame->get_path(&m_curPath); m_group->appendObject(m_curFrame); } } break; case EMR_STROKEPATH: { TRACE("EMR_STROKEPATH\n"); if (m_curFrame) { SetShapeStroke(m_curFrame, &m_pCurrentPen->m_elp); m_group->appendObject(m_curFrame); m_curSubPath.Release(); m_curPath.Release(); m_curFrame.Release(); } } break; case EMR_STROKEANDFILLPATH: { TRACE("EMR_STROKEANDFILLPATH\n"); if (m_curFrame) { SetShapeFill(m_curFrame, &m_pCurrentBrush->m_lb); SetShapeStroke(m_curFrame, &m_pCurrentPen->m_elp); m_group->appendObject(m_curFrame); m_curSubPath.Release(); m_curPath.Release(); m_curFrame.Release(); } } break; // Geometric shapes case EMR_LINETO: { TRACE("EMR_LINETO\n"); PEMRLINETO pEMR = (PEMRLINETO)lpEMFR; if (m_curSubPath) { BezierPoint bpt; LPToDP(hDC, pEMR->ptl.x, pEMR->ptl.y, &bpt.x, &bpt.y); ConvertPt(&bpt.x, &bpt.y); bpt.x1 = bpt.x; bpt.y1 = bpt.y; bpt.x2 = bpt.x; bpt.y2 = bpt.y; long index; m_curSubPath->appendPoint(bpt.x, bpt.y, bpt.x1, bpt.y1, bpt.x2, bpt.y2, &index); } MoveToEx(hDC, pEMR->ptl.x, pEMR->ptl.y, NULL); } break; case EMR_POLYGON16: case EMR_POLYLINE16: { PEMRPOLYGON16 pEMR = (PEMRPOLYGON16)lpEMFR; if (lpEMFR->iType == EMR_POLYGON16) TRACE("POLYGON16\n"); else TRACE("POLYLINE16\n"); BOOL bInPath; if (m_curFrame == NULL) { bInPath = FALSE; pddoc->createObjectFrame(&m_curFrame); m_curFrame->get_path(&m_curPath); m_curPath->createSubPath(&m_curSubPath); m_curPath->insertSubPath(-1, m_curSubPath); if (lpEMFR->iType == EMR_POLYGON16) { /* if (fillMode == WINDING) ;//pLayer->m_fillType = 0; else if (fillMode == ALTERNATE) ;//pLayer->m_fillType = 1; else ASSERT(0); */ m_curSubPath->put_closed(VARIANT_TRUE); SetShapeFill(m_curFrame, &m_pCurrentBrush->m_lb); SetShapeStroke(m_curFrame, &m_pCurrentPen->m_elp); } else { SetShapeStroke(m_curFrame, &m_pCurrentPen->m_elp); } } else bInPath = TRUE; for (int i = 0; i < pEMR->cpts; i++) { POINT pt; pt.x = pEMR->apts[i].x; pt.y = pEMR->apts[i].y; BezierPoint bpt; LPToDP(hDC, pt.x, pt.y, &bpt.x, &bpt.y); ConvertPt(&bpt.x, &bpt.y); bpt.x1 = bpt.x; bpt.y1 = bpt.y; bpt.x2 = bpt.x; bpt.y2 = bpt.y; long index; m_curSubPath->appendPoint(bpt.x, bpt.y, bpt.x1, bpt.y1, bpt.x2, bpt.y2, &index); } if (!bInPath) { m_group->appendObject(m_curFrame); m_curSubPath.Release(); m_curPath.Release(); m_curFrame.Release(); } } break; case EMR_POLYPOLYGON16: case EMR_POLYPOLYLINE16: { TRACE("POLYPOLYGON16/POLYPOLYLINE16 (unhandled)\n"); } break; case EMR_RECTANGLE: case EMR_ELLIPSE: { TRACE("RECTANGLE/ELLIPSE\n"); } break; #if 0 { CComPtr<IPDObjectFrame> element; HPEN hPen = (HPEN)::GetCurrentObject(hDC, OBJ_PEN); HBRUSH hBrush = (HBRUSH)::GetCurrentObject(hDC, OBJ_BRUSH); LOGPEN lp; ::GetObject(hPen, sizeof(lp), &lp); LOGBRUSH lb; ::GetObject(hBrush, sizeof(lb), &lb); int fillMode = ::GetPolyFillMode(hDC); switch (lpEMFR->iType) { case EMR_POLYGON16: case EMR_POLYLINE16: { TRACE("POLYGON16/POLYLINE16\n"); /* PEMRPOLYGON16 pEMR = (PEMRPOLYGON16)lpEMFR; pddoc->createObjectFrame(&element); CComPtr<IPDPath> pathData; element->get_path(&pathData); if (lpEMFR->iType == EMR_POLYGON16) { // pLayer->m_name.Format("Polygon"); if (fillMode == WINDING) ;//pLayer->m_fillType = 0; else if (fillMode == ALTERNATE) ;//pLayer->m_fillType = 1; else ASSERT(0); } else { // pLayer->m_name.Format("Polyline"); } SetShapeStrokeFill(path, &lp, (EMR_POLYGON16)? &lb: NULL); int j = 0; for (DWORD i = 0; i < pEMR->cpts; i++) { POINT pt; pt.x = pEMR->apts[i].x; pt.y = pEMR->apts[i].y; ::LPtoDP(hDC, &pt, 1); if (i == 0) { SVGLib::ISVGPathSegMovetoAbsPtr moveto = path->createSVGPathSegMovetoAbs(pt.x, pt.y); pathData->pathSegList->appendItem(moveto); } else { SVGLib::ISVGPathSegLinetoAbsPtr lineto = path->createSVGPathSegLinetoAbs(pt.x, pt.y); pathData->pathSegList->appendItem(lineto); } } element = path; */ } break; case EMR_POLYPOLYGON16: case EMR_POLYPOLYLINE16: { TRACE("POLYPOLYGON16/POLYPOLYLINE16 (unhandled)\n"); /* PEMRPOLYPOLYGON16 pEMR = (PEMRPOLYPOLYGON16)lpEMFR; POINTS* apts = (POINTS*)(((LPBYTE)pEMR->apts) + (pEMR->nPolys-1)*4); SVGLib::ISVGPathElementPtr path = pDoc->GetDOMDocument()->createElement(L"path"); SVGLib::ISVGAnimatedPathDataPtr pathData = path; for (DWORD nPoly = 0; nPoly < pEMR->nPolys; nPoly++) { // pLayer->SetShapeStrokeFill(&lp, (lpEMFR->iType == EMR_POLYPOLYGON16) ? &lb: NULL); if (lpEMFR->iType == EMR_POLYPOLYGON16) { if (fillMode == WINDING) ;//pLayer->m_fillType = 0; else// if (fillMode == ALTERNATE) ;//pLayer->m_fillType = 1; } else { } int j = 0; for (DWORD i = 0; i < pEMR->aPolyCounts[nPoly]; i++) { POINT pt; pt.x = apts->x; pt.y = apts->y; apts++; ::LPtoDP(hDC, &pt, 1); if (i == 0) { SVGLib::ISVGPathSegMovetoAbsPtr moveto = path->createSVGPathSegMovetoAbs(pt.x, pt.y); pathData->pathSegList->appendItem(moveto); } else { SVGLib::ISVGPathSegLinetoAbsPtr lineto = path->createSVGPathSegLinetoAbs(pt.x, pt.y); pathData->pathSegList->appendItem(lineto); } } } element = path; */ } break; case EMR_RECTANGLE: case EMR_ELLIPSE: { /* PEMRRECTANGLE pEMR = (PEMRRECTANGLE)lpEMFR; CRect r; r.left = pEMR->rclBox.left; r.right = pEMR->rclBox.right; r.top = pEMR->rclBox.top; r.bottom = pEMR->rclBox.bottom; ::LPtoDP(hDC, (LPPOINT)&r, 2); if (lpEMFR->iType == EMR_RECTANGLE) { SVGLib::ISVGRectElementPtr rect = pDoc->GetDOMDocument()->createElement(L"rect"); rect->x->baseVal->value = r.left; rect->y->baseVal->value = r.top; rect->width->baseVal->value = r.Width(); rect->height->baseVal->value = r.Height(); element = rect; } else if (lpEMFR->iType == EMR_ELLIPSE) { SVGLib::ISVGEllipseElementPtr ellipse = pDoc->GetDOMDocument()->createElement(L"ellipse"); ellipse->cx->baseVal->value = r.left + r.Width()/2; ellipse->cy->baseVal->value = r.top + r.Height()/2; ellipse->rx->baseVal->value = r.Width()/2; ellipse->ry->baseVal->value = r.Height()/2; element = ellipse; } SetShapeStrokeFill(element, &lp, &lb); */ } break; } if (element) { m_group->appendObject(element); } } break; #endif case EMR_POLYBEZIER16: { TRACE("EMR_POLYBEZIER16: (unhandled)\n"); } break; case EMR_POLYBEZIERTO16: { TRACE("EMR_POLYBEZIERTO16:\n"); PEMRPOLYBEZIERTO16 pEMR = (PEMRPOLYBEZIERTO16)lpEMFR; POINT pt; GetCurrentPositionEx(hDC, &pt); BezierPoint bpt; if (m_curSubPath == NULL) { m_curPath->createSubPath(&m_curSubPath); m_curPath->insertSubPath(-1, m_curSubPath); } LPToDP(hDC, pt.x, pt.y, &bpt.x, &bpt.y); ConvertPt(&bpt.x, &bpt.y); bpt.x1 = bpt.x; bpt.y1 = bpt.y; ATLASSERT((pEMR->cpts % 3) == 0); for (int i = 0; i < pEMR->cpts; i += 3) { LPToDP(hDC, pEMR->apts[i].x, pEMR->apts[i].y, &bpt.x2, &bpt.y2); ConvertPt(&bpt.x2, &bpt.y2); long index; m_curSubPath->appendPoint(bpt.x, bpt.y, bpt.x1, bpt.y1, bpt.x2, bpt.y2, &index); LPToDP(hDC, pEMR->apts[i+1].x, pEMR->apts[i+1].y, &bpt.x1, &bpt.y1); ConvertPt(&bpt.x1, &bpt.y1); LPToDP(hDC, pEMR->apts[i+2].x, pEMR->apts[i+2].y, &bpt.x, &bpt.y); ConvertPt(&bpt.x, &bpt.y); } bpt.x2 = bpt.x; bpt.y2 = bpt.y; long index; m_curSubPath->appendPoint(bpt.x, bpt.y, bpt.x1, bpt.y1, bpt.x2, bpt.y2, &index); MoveToEx(hDC, pEMR->apts[i-1].x, pEMR->apts[i-1].y, NULL); } break; case EMR_CLOSEFIGURE: { TRACE("EMR_CLOSEFIGURE:\n"); if (m_curSubPath) { m_curSubPath->put_closed(VARIANT_TRUE); m_curSubPath.Release(); /* Have this ????? BezierPoint bpt; LPToDP(hDC, m_startPt.x, m_startPt.y, &bpt.x, &bpt.y); ConvertPt(&bpt.x, &bpt.y); bpt.x1 = bpt.x; bpt.y1 = bpt.y; bpt.x2 = bpt.x; bpt.y2 = bpt.y; long index; m_curSubPath->appendPoint(bpt.x, bpt.y, bpt.x1, bpt.y1, bpt.x2, bpt.y2, &index); */ } } break; case EMR_ROUNDRECT: // TODO { TRACE("EMR_ROUNDRECT: (unhandled)\n"); } break; case EMR_ARC: // TODO { TRACE("EMR_ARC: (unhandled)\n"); } break; case EMR_PIE: // TODO { TRACE("EMR_PIE: (unhandled)\n"); } break; case EMR_CHORD: // TODO { TRACE("EMR_CHORD: (unhandled)\n"); } break; case EMR_ANGLEARC: // TODO { TRACE("EMR_ANGLEARC: (unhandled)\n"); } break; case EMR_ARCTO: { TRACE("EMR_ARCTO: (unhandled)\n"); } break; // Bitmap Stuff (in order of importance) case EMR_BITBLT: // TODO { PEMRBITBLT pEMR = (PEMRBITBLT)lpEMFR; // pEMR-> TRACE("EMR_BITBLT: (unhandled)\n"); } break; case EMR_STRETCHDIBITS: // TODO { TRACE("EMR_STRETCHDIBITS: (unhandled)\n"); } break; case EMR_STRETCHBLT: // TODO { TRACE("EMR_STRETCHBLT: (unhandled)\n"); } break; case EMR_SETDIBITSTODEVICE: // TODO { TRACE("EMR_SETDIBITSTODEVICE: (unhandled)\n"); } break; case EMR_MASKBLT: { TRACE("EMR_MASKBLT: (unhandled)\n"); } break; case EMR_PLGBLT: { TRACE("EMR_PLGBLT: (unhandled)\n"); } break; case EMR_ALPHABLEND: // TODO { TRACE("EMR_ALPHABLEND: (unhandled)\n"); } break; case 115: //EMR_ALPHADIBBLEND: // TODO { TRACE("EMR_ALPHADIBBLEND: (unhandled)\n"); } break; case EMR_TRANSPARENTBLT: { TRACE("EMR_TRANSPARENTBLT: (unhandled)\n"); } break; case 117: //EMR_TRANSPARENTDIB: { TRACE("EMR_TRANSPARENTDIB: (unhandled)\n"); } break; case 118: //EMR_GRADIENTFILL: { TRACE("EMR_GRADIENTFILL: (unhandled)\n"); } break; case EMR_SETPIXELV: { TRACE("EMR_SETPIXELV: (unhandled)\n"); } break; // Text Stuff case EMR_EXTTEXTOUTA: // TODO case EMR_EXTTEXTOUTW: { TRACE("EMR_EXTTEXTOUT: (unhandled)\n"); } break; case EMR_POLYTEXTOUTA: // TODO case EMR_POLYTEXTOUTW: { TRACE("EMR_POLYTEXTOUT: (unhandled)\n"); } break; // End of file case EMR_EOF: { PEMREOF pEMR = (PEMREOF)lpEMFR; return 0; } break; default: // Unknown record type { ATLTRACE("Unknown iType: %d\n", lpEMFR->iType); } break; } return 1; }
BOOL nulldrv_PolyDraw( PHYSDEV dev, const POINT *points, const BYTE *types, DWORD count ) { POINT *line_pts = NULL, *bzr_pts = NULL, bzr[4]; INT i, num_pts, num_bzr_pts, space, size; /* check for valid point types */ for (i = 0; i < count; i++) { switch (types[i]) { case PT_MOVETO: case PT_LINETO | PT_CLOSEFIGURE: case PT_LINETO: break; case PT_BEZIERTO: if((i + 2 < count) && (types[i + 1] == PT_BEZIERTO) && ((types[i + 2] & ~PT_CLOSEFIGURE) == PT_BEZIERTO)) { i += 2; break; } default: return FALSE; } } space = count + 300; line_pts = HeapAlloc( GetProcessHeap(), 0, space * sizeof(POINT) ); num_pts = 1; GetCurrentPositionEx( dev->hdc, &line_pts[0] ); for (i = 0; i < count; i++) { switch (types[i]) { case PT_MOVETO: if (num_pts >= 2) Polyline( dev->hdc, line_pts, num_pts ); num_pts = 0; line_pts[num_pts++] = points[i]; break; case PT_LINETO: case (PT_LINETO | PT_CLOSEFIGURE): line_pts[num_pts++] = points[i]; break; case PT_BEZIERTO: bzr[0].x = line_pts[num_pts - 1].x; bzr[0].y = line_pts[num_pts - 1].y; memcpy( &bzr[1], &points[i], 3 * sizeof(POINT) ); if ((bzr_pts = GDI_Bezier( bzr, 4, &num_bzr_pts ))) { size = num_pts + (count - i) + num_bzr_pts; if (space < size) { space = size * 2; line_pts = HeapReAlloc( GetProcessHeap(), 0, line_pts, space * sizeof(POINT) ); } memcpy( &line_pts[num_pts], &bzr_pts[1], (num_bzr_pts - 1) * sizeof(POINT) ); num_pts += num_bzr_pts - 1; HeapFree( GetProcessHeap(), 0, bzr_pts ); } i += 2; break; } if (types[i] & PT_CLOSEFIGURE) line_pts[num_pts++] = line_pts[0]; } if (num_pts >= 2) Polyline( dev->hdc, line_pts, num_pts ); MoveToEx( dev->hdc, line_pts[num_pts - 1].x, line_pts[num_pts - 1].y, NULL ); HeapFree( GetProcessHeap(), 0, line_pts ); 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); }