⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dc.cpp

📁 A*算法 A*算法 A*算法 A*算法A*算法A*算法
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    // the region coords are always the device ones, so do the translation
    // manually
    //
    // FIXME: possible +/-1 error here, to check!
    HRGN hrgn = ::CreateRectRgn(LogicalToDeviceX(x),
                                LogicalToDeviceY(y),
                                LogicalToDeviceX(x + w),
                                LogicalToDeviceY(y + h));
    if ( !hrgn )
    {
        wxLogLastError(_T("CreateRectRgn"));
    }
    else
    {
        SetClippingHrgn((WXHRGN)hrgn);

        ::DeleteObject(hrgn);
    }
}

void wxDC::DoSetClippingRegionAsRegion(const wxRegion& region)
{
    SetClippingHrgn(region.GetHRGN());
}

void wxDC::DestroyClippingRegion()
{
    WXMICROWIN_CHECK_HDC

    if (m_clipping && m_hDC)
    {
#ifdef __WXWINCE__
        // On a PocketPC device (not necessarily emulator), resetting
        // the clip region as per the old method causes bad display
        // problems. In fact setting a null region is probably OK
        // on desktop WIN32 also, since the WIN32 docs imply that the user
        // clipping region is independent from the paint clipping region.
        ::SelectClipRgn(GetHdc(), 0);
#else        
        // TODO: this should restore the previous clipping region,
        //       so that OnPaint processing works correctly, and the update
        //       clipping region doesn't get destroyed after the first
        //       DestroyClippingRegion.
        HRGN rgn = CreateRectRgn(0, 0, 32000, 32000);
        ::SelectClipRgn(GetHdc(), rgn);
        ::DeleteObject(rgn);
#endif
    }

    wxDCBase::DestroyClippingRegion();
}

// ---------------------------------------------------------------------------
// query capabilities
// ---------------------------------------------------------------------------

bool wxDC::CanDrawBitmap() const
{
    return true;
}

bool wxDC::CanGetTextExtent() const
{
#ifdef __WXMICROWIN__
    // TODO Extend MicroWindows' GetDeviceCaps function
    return true;
#else
    // What sort of display is it?
    int technology = ::GetDeviceCaps(GetHdc(), TECHNOLOGY);

    return (technology == DT_RASDISPLAY) || (technology == DT_RASPRINTER);
#endif
}

int wxDC::GetDepth() const
{
    WXMICROWIN_CHECK_HDC_RET(16)

    return (int)::GetDeviceCaps(GetHdc(), BITSPIXEL);
}

// ---------------------------------------------------------------------------
// drawing
// ---------------------------------------------------------------------------

void wxDC::Clear()
{
    WXMICROWIN_CHECK_HDC

    RECT rect;
    if ( m_canvas )
    {
        GetClientRect((HWND) m_canvas->GetHWND(), &rect);
    }
    else
    {
        // No, I think we should simply ignore this if printing on e.g.
        // a printer DC.
        // wxCHECK_RET( m_selectedBitmap.Ok(), wxT("this DC can't be cleared") );
        if (!m_selectedBitmap.Ok())
            return;

        rect.left = 0; rect.top = 0;
        rect.right = m_selectedBitmap.GetWidth();
        rect.bottom = m_selectedBitmap.GetHeight();
    }

#ifndef __WXWINCE__
    (void) ::SetMapMode(GetHdc(), MM_TEXT);
#endif

    DWORD colour = ::GetBkColor(GetHdc());
    HBRUSH brush = ::CreateSolidBrush(colour);
    ::FillRect(GetHdc(), &rect, brush);
    ::DeleteObject(brush);

#ifndef __WXWINCE__
    int width = DeviceToLogicalXRel(VIEWPORT_EXTENT)*m_signX,
        height = DeviceToLogicalYRel(VIEWPORT_EXTENT)*m_signY;

    ::SetMapMode(GetHdc(), MM_ANISOTROPIC);

    ::SetViewportExtEx(GetHdc(), VIEWPORT_EXTENT, VIEWPORT_EXTENT, NULL);
    ::SetWindowExtEx(GetHdc(), width, height, NULL);
    ::SetViewportOrgEx(GetHdc(), (int)m_deviceOriginX, (int)m_deviceOriginY, NULL);
    ::SetWindowOrgEx(GetHdc(), (int)m_logicalOriginX, (int)m_logicalOriginY, NULL);
#endif
}

bool wxDC::DoFloodFill(wxCoord WXUNUSED_IN_WINCE(x),
                       wxCoord WXUNUSED_IN_WINCE(y),
                       const wxColour& WXUNUSED_IN_WINCE(col),
                       int WXUNUSED_IN_WINCE(style))
{
#ifdef __WXWINCE__
    return false;
#else
    WXMICROWIN_CHECK_HDC_RET(false)

    bool success = (0 != ::ExtFloodFill(GetHdc(), XLOG2DEV(x), YLOG2DEV(y),
                         col.GetPixel(),
                         style == wxFLOOD_SURFACE ? FLOODFILLSURFACE
                                                  : FLOODFILLBORDER) ) ;
    if (!success)
    {
        // quoting from the MSDN docs:
        //
        //      Following are some of the reasons this function might fail:
        //
        //      * The filling could not be completed.
        //      * The specified point has the boundary color specified by the
        //        crColor parameter (if FLOODFILLBORDER was requested).
        //      * The specified point does not have the color specified by
        //        crColor (if FLOODFILLSURFACE was requested)
        //      * The point is outside the clipping region that is, it is not
        //        visible on the device.
        //
        wxLogLastError(wxT("ExtFloodFill"));
    }

    CalcBoundingBox(x, y);

    return success;
#endif
}

bool wxDC::DoGetPixel(wxCoord x, wxCoord y, wxColour *col) const
{
    WXMICROWIN_CHECK_HDC_RET(false)

    wxCHECK_MSG( col, false, _T("NULL colour parameter in wxDC::GetPixel") );

    // get the color of the pixel
    COLORREF pixelcolor = ::GetPixel(GetHdc(), XLOG2DEV(x), YLOG2DEV(y));

    wxRGBToColour(*col, pixelcolor);

    return true;
}

void wxDC::DoCrossHair(wxCoord x, wxCoord y)
{
    WXMICROWIN_CHECK_HDC

    wxCoord x1 = x-VIEWPORT_EXTENT;
    wxCoord y1 = y-VIEWPORT_EXTENT;
    wxCoord x2 = x+VIEWPORT_EXTENT;
    wxCoord y2 = y+VIEWPORT_EXTENT;

    wxDrawLine(GetHdc(), XLOG2DEV(x1), YLOG2DEV(y), XLOG2DEV(x2), YLOG2DEV(y));
    wxDrawLine(GetHdc(), XLOG2DEV(x), YLOG2DEV(y1), XLOG2DEV(x), YLOG2DEV(y2));

    CalcBoundingBox(x1, y1);
    CalcBoundingBox(x2, y2);
}

void wxDC::DoDrawLine(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
{
    WXMICROWIN_CHECK_HDC

    wxDrawLine(GetHdc(), XLOG2DEV(x1), YLOG2DEV(y1), XLOG2DEV(x2), YLOG2DEV(y2));

    CalcBoundingBox(x1, y1);
    CalcBoundingBox(x2, y2);
}

// Draws an arc of a circle, centred on (xc, yc), with starting point (x1, y1)
// and ending at (x2, y2)
void wxDC::DoDrawArc(wxCoord x1, wxCoord y1,
                     wxCoord x2, wxCoord y2,
                     wxCoord xc, wxCoord yc)
{
#ifdef __WXWINCE__
    // Slower emulation since WinCE doesn't support Pie and Arc
    double r = sqrt( (x1-xc)*(x1-xc) + (y1-yc)*(y1-yc) );
    double sa = acos((x1-xc)/r)/M_PI*180; // between 0 and 180
    if( y1>yc ) sa = -sa; // below center
    double ea = atan2(yc-y2, x2-xc)/M_PI*180;
    DoDrawEllipticArcRot( xc-r, yc-r, 2*r, 2*r, sa, ea );
#else

    WXMICROWIN_CHECK_HDC

    wxColourChanger cc(*this); // needed for wxSTIPPLE_MASK_OPAQUE handling

    double dx = xc - x1;
    double dy = yc - y1;
    double radius = (double)sqrt(dx*dx+dy*dy);
    wxCoord r = (wxCoord)radius;

    // treat the special case of full circle separately
    if ( x1 == x2 && y1 == y2 )
    {
        DrawEllipse(xc - r, yc - r, 2*r, 2*r);
        return;
    }

    wxCoord xx1 = XLOG2DEV(x1);
    wxCoord yy1 = YLOG2DEV(y1);
    wxCoord xx2 = XLOG2DEV(x2);
    wxCoord yy2 = YLOG2DEV(y2);
    wxCoord xxc = XLOG2DEV(xc);
    wxCoord yyc = YLOG2DEV(yc);
    wxCoord ray = (wxCoord) sqrt(double((xxc-xx1)*(xxc-xx1)+(yyc-yy1)*(yyc-yy1)));

    wxCoord xxx1 = (wxCoord) (xxc-ray);
    wxCoord yyy1 = (wxCoord) (yyc-ray);
    wxCoord xxx2 = (wxCoord) (xxc+ray);
    wxCoord yyy2 = (wxCoord) (yyc+ray);

    if ( m_brush.Ok() && m_brush.GetStyle() != wxTRANSPARENT )
    {
        // Have to add 1 to bottom-right corner of rectangle
        // to make semi-circles look right (crooked line otherwise).
        // Unfortunately this is not a reliable method, depends
        // on the size of shape.
        // TODO: figure out why this happens!
        Pie(GetHdc(),xxx1,yyy1,xxx2+1,yyy2+1, xx1,yy1,xx2,yy2);
    }
    else
    {
        Arc(GetHdc(),xxx1,yyy1,xxx2,yyy2, xx1,yy1,xx2,yy2);
    }

    CalcBoundingBox(xc - r, yc - r);
    CalcBoundingBox(xc + r, yc + r);
#endif
}

void wxDC::DoDrawCheckMark(wxCoord x1, wxCoord y1,
                           wxCoord width, wxCoord height)
{
    WXMICROWIN_CHECK_HDC

    wxCoord x2 = x1 + width,
            y2 = y1 + height;

#if defined(__WIN32__) && !defined(__SYMANTEC__) && !defined(__WXMICROWIN__)
    RECT rect;
    rect.left   = x1;
    rect.top    = y1;
    rect.right  = x2;
    rect.bottom = y2;

#ifdef __WXWINCE__
    DrawFrameControl(GetHdc(), &rect, DFC_BUTTON, DFCS_BUTTONCHECK);
#else
    DrawFrameControl(GetHdc(), &rect, DFC_MENU, DFCS_MENUCHECK);
#endif
#else // Symantec-MicroWin
    // draw a cross
    HPEN blackPen = ::CreatePen(PS_SOLID, 1, RGB(0, 0, 0));
    HPEN whiteBrush = (HPEN)::GetStockObject(WHITE_BRUSH);
    HPEN hPenOld = (HPEN)::SelectObject(GetHdc(), blackPen);
    HPEN hBrushOld = (HPEN)::SelectObject(GetHdc(), whiteBrush);
    ::SetROP2(GetHdc(), R2_COPYPEN);
    Rectangle(GetHdc(), x1, y1, x2, y2);
    MoveToEx(GetHdc(), x1, y1, NULL);
    LineTo(GetHdc(), x2, y2);
    MoveToEx(GetHdc(), x2, y1, NULL);
    LineTo(GetHdc(), x1, y2);
    ::SelectObject(GetHdc(), hPenOld);
    ::SelectObject(GetHdc(), hBrushOld);
    ::DeleteObject(blackPen);
#endif // Win32/Symantec-MicroWin

    CalcBoundingBox(x1, y1);
    CalcBoundingBox(x2, y2);
}

void wxDC::DoDrawPoint(wxCoord x, wxCoord y)
{
    WXMICROWIN_CHECK_HDC

    COLORREF color = 0x00ffffff;
    if (m_pen.Ok())
    {
        color = m_pen.GetColour().GetPixel();
    }

    SetPixel(GetHdc(), XLOG2DEV(x), YLOG2DEV(y), color);

    CalcBoundingBox(x, y);
}

void wxDC::DoDrawPolygon(int n,
                         wxPoint points[],
                         wxCoord xoffset,
                         wxCoord yoffset,
                         int WXUNUSED_IN_WINCE(fillStyle))
{
    WXMICROWIN_CHECK_HDC

    wxColourChanger cc(*this); // needed for wxSTIPPLE_MASK_OPAQUE handling

    // Do things less efficiently if we have offsets
    if (xoffset != 0 || yoffset != 0)
    {
        POINT *cpoints = new POINT[n];
        int i;
        for (i = 0; i < n; i++)
        {
            cpoints[i].x = (int)(points[i].x + xoffset);
            cpoints[i].y = (int)(points[i].y + yoffset);

            CalcBoundingBox(cpoints[i].x, cpoints[i].y);
        }
#ifndef __WXWINCE__
        int prev = SetPolyFillMode(GetHdc(),fillStyle==wxODDEVEN_RULE?ALTERNATE:WINDING);
#endif
        (void)Polygon(GetHdc(), cpoints, n);
#ifndef __WXWINCE__
        SetPolyFillMode(GetHdc(),prev);
#endif
        delete[] cpoints;
    }
    else
    {
        int i;
        for (i = 0; i < n; i++)
            CalcBoundingBox(points[i].x, points[i].y);

#ifndef __WXWINCE__
        int prev = SetPolyFillMode(GetHdc(),fillStyle==wxODDEVEN_RULE?ALTERNATE:WINDING);
#endif
        (void)Polygon(GetHdc(), (POINT*) points, n);
#ifndef __WXWINCE__
        SetPolyFillMode(GetHdc(),prev);
#endif
    }
}

void
wxDC::DoDrawPolyPolygon(int n,
                        int count[],
                        wxPoint points[],
                        wxCoord xoffset,
                        wxCoord yoffset,
                        int fillStyle)
{
#ifdef __WXWINCE__
    wxDCBase::DoDrawPolyPolygon(n, count, points, xoffset, yoffset, fillStyle);
#else
    WXMICROWIN_CHECK_HDC

    wxColourChanger cc(*this); // needed for wxSTIPPLE_MASK_OPAQUE handling
    int i, cnt;
    for (i = cnt = 0; i < n; i++)
        cnt += count[i];

    // Do things less efficiently if we have offsets
    if (xoffset != 0 || yoffset != 0)
    {
        POINT *cpoints = new POINT[cnt];
        for (i = 0; i < cnt; i++)
        {
            cpoints[i].x = (int)(points[i].x + xoffset);
            cpoints[i].y = (int)(points[i].y + yoffset);

            CalcBoundingBox(cpoints[i].x, cpoints[i].y);
        }
#ifndef __WXWINCE__
        int prev = SetPolyFillMode(GetHdc(),fillStyle==wxODDEVEN_RULE?ALTERNATE:WINDING);
#endif
        (void)PolyPolygon(GetHdc(), cpoints, count, n);
#ifndef __WXWINCE__
        SetPolyFillMode(GetHdc(),prev);
#endif
        delete[] cpoints;
    }
    else
    {
        for (i = 0; i < cnt; i++)
            CalcBoundingBox(points[i].x, points[i].y);

#ifndef __WXWINCE__
        int prev = SetPolyFillMode(GetHdc(),fillStyle==wxODDEVEN_RULE?ALTERNATE:WINDING);
#endif
        (void)PolyPolygon(GetHdc(), (POINT*) points, count, n);
#ifndef __WXWINCE__
        SetPolyFillMode(GetHdc(),prev);
#endif
    }
#endif
  // __WXWINCE__
}

void wxDC::DoDrawLines(int n, wxPoint points[], wxCoord xoffset, wxCoord yoffset)
{
    WXMICROWIN_CHECK_HDC

    // Do things less efficiently if we have offsets
    if (xoffset != 0 || yoffset != 0)
    {
        POINT *cpoints = new POINT[n];
        int i;
        for (i = 0; i < n; i++)
        {
            cpoints[i].x = (int)(points[i].x + xoffset);
            cpoints[i].y = (int)(points[i].y + yoffset);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -