如何将任意一个内存区域的内容拷贝到一个DC上?
我的意思是:自己用内存分配函数malloc分配一块内存,然后这块内存上使用自己的画图函数(不用windows的API)进行画图后,在指定的窗口上显示出来,如何做?
谢谢!

解决方案 »

  1.   

    还是要用GDI建立一个位图然后显示
      

  2.   

    用GDI的话,我自己编写的绘画函数(这些函数是直接操作内存的,他们不调用API与MFC,)如何将内容画到这个位图上?
      

  3.   

    直接操作位图的像素值呀,不需要API和MFC的。给你一段画线的
    // *******************************************
    // PUBLIC METHOD -- class PixelDrawingSurface
    //
    // LineDraw
    //
    //
    // Draws a line between the specified endpoints in color Color. 
    //
    void 
    PixelDrawingSurface::LineDraw(int XStart, int YStart, int XEnd, int YEnd, int Color)
    {
    int Temp, AdjUp, AdjDown, ErrorTerm, XDelta, YDelta;
    int WholeStep, InitialPixelCount, FinalPixelCount, i, RunLength; ASSERT( YStart >= 0 );
    ASSERT( YEnd >= 0 );
    ASSERT( YStart < this->getHeight() );
    ASSERT( YEnd < this->getHeight() );
    ASSERT( XStart >= 0 );
    ASSERT( XEnd >= 0 );
    ASSERT( XStart < this->getWidth() );
    ASSERT( XEnd < this->getWidth() ); /* We'll always draw top to bottom, to reduce the number of cases we have to
    handle, and to make lines between the same endpoints draw the same pixels */
    if (YStart > YEnd) 
    {
    Temp = YStart;
    YStart = YEnd;
    YEnd = Temp;
    Temp = XStart;
    XStart = XEnd;
    XEnd = Temp;
    } /* Point to the bitmap address first pixel to draw */
    m_pLineIterator->SetPos( XStart, YStart ); /* Figure out whether we're going left or right, and how far we're
      going horizontally */
    if ((XDelta = XEnd - XStart) < 0)
    {
    m_pLineIterator->SetXDirection( -1 );
    XDelta = -XDelta;
    }
    else
    {
    m_pLineIterator->SetXDirection( 1 );
    }
    /* Figure out how far we're going vertically */
    YDelta = YEnd - YStart; /* Special-case horizontal, vertical, and diagonal lines, for speed
     and to avoid nasty boundary conditions and division by 0 */
    if (XDelta == 0)
    {
    /* Vertical line */
    for (i=0; i<=YDelta; i++)
    {
    m_pLineIterator->SetPixel( Color );
    m_pLineIterator->AdvanceY();
    }
    return;
    }
    if (YDelta == 0)
    {
    /* Horizontal line */
    for (i=0; i<=XDelta; i++)
    {
    m_pLineIterator->SetPixel( Color );
    m_pLineIterator->AdvanceX() ;
    }
    return;
    }
    if (XDelta == YDelta)
    {
    /* Diagonal line */
    for (i=0; i<=XDelta; i++)
    {
    m_pLineIterator->SetPixel( Color );
    m_pLineIterator->AdvanceX();
    m_pLineIterator->AdvanceY();
    }
    return;
    } /* Determine whether the line is X or Y major, and handle accordingly */
    if (XDelta >= YDelta)
    {
    /* X major line */
    /* Minimum # of pixels in a run in this line */
    WholeStep = XDelta / YDelta; /* Error term adjust each time Y steps by 1; used to tell when one
             extra pixel should be drawn as part of a run, to account for
             fractional steps along the X axis per 1-pixel steps along Y */
    AdjUp = (XDelta % YDelta) * 2; /* Error term adjust when the error term turns over, used to factor
             out the X step made at that time */
    AdjDown = YDelta * 2; /* Initial error term; reflects an initial step of 0.5 along the Y
             axis */
    ErrorTerm = (XDelta % YDelta) - (YDelta * 2); /* The initial and last runs are partial, because Y advances only 0.5
             for these runs, rather than 1. Divide one full run, plus the
             initial pixel, between the initial and last runs */
    InitialPixelCount = (WholeStep / 2) + 1;
    FinalPixelCount = InitialPixelCount; /* If the basic run length is even and there's no fractional
             advance, we have one pixel that could go to either the initial
             or last partial run, which we'll arbitrarily allocate to the
             last run */
    if ((AdjUp == 0) && ((WholeStep & 0x01) == 0))
    {
    InitialPixelCount--;
    }
    /* If there're an odd number of pixels per run, we have 1 pixel that can't
             be allocated to either the initial or last partial run, so we'll add 0.5
             to error term so this pixel will be handled by the normal full-run loop */
    if ((WholeStep & 0x01) != 0)
    {
    ErrorTerm += YDelta;
    }
    /* Draw the first, partial run of pixels */
    drawHorizontalRun( InitialPixelCount, Color);
    /* Draw all full runs */
    for (i=0; i<(YDelta-1); i++)
    {
    RunLength = WholeStep;  /* run is at least this long */
    /* Advance the error term and add an extra pixel if the error
             term so indicates */
    if ((ErrorTerm += AdjUp) > 0)
    {
    RunLength++;
    ErrorTerm -= AdjDown;   /* reset the error term */
    }
    /* Draw this scan line's run */
    drawHorizontalRun( RunLength, Color);
    }
    /* Draw the final run of pixels */
    drawHorizontalRun( FinalPixelCount, Color);
    return;
    }
    else
    {
    /* Y major line */ /* Minimum # of pixels in a run in this line */
    WholeStep = YDelta / XDelta; /* Error term adjust each time X steps by 1; used to tell when 1 extra
             pixel should be drawn as part of a run, to account for
             fractional steps along the Y axis per 1-pixel steps along X */
    AdjUp = (YDelta % XDelta) * 2; /* Error term adjust when the error term turns over, used to factor
             out the Y step made at that time */
    AdjDown = XDelta * 2; /* Initial error term; reflects initial step of 0.5 along the X axis */
    ErrorTerm = (YDelta % XDelta) - (XDelta * 2); /* The initial and last runs are partial, because X advances only 0.5
             for these runs, rather than 1. Divide one full run, plus the
             initial pixel, between the initial and last runs */
    InitialPixelCount = (WholeStep / 2) + 1;
    FinalPixelCount = InitialPixelCount; /* If the basic run length is even and there's no fractional advance, we
             have 1 pixel that could go to either the initial or last partial run,
             which we'll arbitrarily allocate to the last run */
    if ((AdjUp == 0) && ((WholeStep & 0x01) == 0))
    {
    InitialPixelCount--;
    }
    /* If there are an odd number of pixels per run, we have one pixel
    that can't be allocated to either the initial or last partial
    run, so we'll add 0.5 to the error term so this pixel will be
    handled by the normal full-run loop */
    if ((WholeStep & 0x01) != 0)
    {
    ErrorTerm += XDelta;
    }
    /* Draw the first, partial run of pixels */
    drawVerticalRun( InitialPixelCount, Color); /* Draw all full runs */
    for (i=0; i<(XDelta-1); i++)
    {
    RunLength = WholeStep;  /* run is at least this long */
    /* Advance the error term and add an extra pixel if the error
           term so indicates */
    if ((ErrorTerm += AdjUp) > 0)
    {
    RunLength++;
    ErrorTerm -= AdjDown;   /* reset the error term */
    }
    /* Draw this scan line's run */
    drawVerticalRun( RunLength, Color);
    }
    /* Draw the final run of pixels */
    drawVerticalRun( FinalPixelCount, Color);
    return;
    }
    }
      

  4.   

    // *******************************************
    // PRIVATE INTERNAL METHOD -- class PixelDrawingSurface
    //
    // drawHorizontalRun
    //
    // Draws a horizontal run of pixels, then advances the bitmap pointer to
    // the first pixel of the next run. 
    void 
    PixelDrawingSurface::drawHorizontalRun( int RunLength, int Color)
    {
    int i; for (i=0; i<RunLength; i++)
    {
    m_pLineIterator->SetPixel( Color );
    m_pLineIterator->AdvanceX( );
    }
       /* Advance to the next scan line */
    m_pLineIterator->AdvanceY( );
    }
    // *******************************************
    // PRIVATE INTERNAL METHOD -- class PixelDrawingSurface
    //
    // drawVerticalRun
    //
    // Draws a vertical run of pixels, then advances the bitmap pointer to
    //  the first pixel of the next run. 
    void 
    PixelDrawingSurface::drawVerticalRun( int RunLength, int Color)
    {
    int i; for (i=0; i<RunLength; i++)
    {
    m_pLineIterator->SetPixel( Color );
    m_pLineIterator->AdvanceY();
    } /* Advance to the next column */
    m_pLineIterator->AdvanceX();
    }// ******************************************************************
    // CLASS IMPLEMENTATION PixelDrawingSurface
    //
    // CLASS IMPLEMENTATION PixelDrawingSurface::PixelIterator
    // CTOR
    //
    PixelDrawingSurface::PixelIterator::PixelIterator( PixelDrawingSurface *pDrawingSurface )
    {
    this->m_pSurface = pDrawingSurface;
    this->m_pBits = pDrawingSurface->getBits();
    this->m_pPosition = this->m_pBits;
    this->m_iRasterWidth = pDrawingSurface->getWidth() * pDrawingSurface->m_BytesPerPixel;
    }// DTOR
    //
    PixelDrawingSurface::PixelIterator::~PixelIterator( void )
    {
    this->m_pSurface = NULL;
    this->m_pBits = NULL;
    this->m_pPosition = NULL;
    }// SetPos
    //
    void
    PixelDrawingSurface::PixelIterator::SetPos( int x, int y )
    {
    this->m_pPosition = this->m_pSurface->getBits();
    this->m_pPosition += x * this->m_pSurface->m_BytesPerPixel;
    this->m_pPosition += y * this->m_iRasterWidth; // m_iRasterWidth is pre-computed to account for BytesPerPixel
    }void
    PixelDrawingSurface::PixelIterator::SetXDirection( int XDir )
    {
    this->m_iXAdvance = XDir * this->m_pSurface->m_BytesPerPixel;
    }void
    PixelDrawingSurface::PixelIterator::AdvanceX( void )
    {
    this->m_pPosition += this->m_iXAdvance;
    }void
    PixelDrawingSurface::PixelIterator::AdvanceY( void )
    {
    this->m_pPosition += this->m_iRasterWidth;
    }
    // -------------------------
    // Methods for setting pixels
    //
    // We need to do different things if we are in XOR, so I made separate methods.
    // 
    #ifdef INLINEDBELOW
    void
    PixelDrawingSurface::PixelIterator::copyPixel( int color )
    {
    if ( this->m_pSurface->m_BytesPerPixel == 1 )
    {
    *this->m_pPosition = color;
    }
    else if ( this->m_pSurface->m_BytesPerPixel == 2 )
    {
    short *pWord = (short *)this->m_pPosition;
    *pWord = color;
    }
    else if ( this->m_pSurface->m_BytesPerPixel == 3 )
    {
    char *pTemp = (char *)&color;
    this->m_pPosition[0] = pTemp[2];
    this->m_pPosition[1] = pTemp[1];
    this->m_pPosition[2] = pTemp[0];
    }
    else if ( this->m_pSurface->m_BytesPerPixel == 4 )
    {
    char *pTemp = (char *)&color;
    this->m_pPosition[0] = pTemp[2];
    this->m_pPosition[1] = pTemp[1];
    this->m_pPosition[2] = pTemp[0];
    }
    else
    {
    // ACK ACK ACK!
    ASSERT( false );
    }
    }void
    PixelDrawingSurface::PixelIterator::xorPixel( int color )
    {
    if ( this->m_pSurface->m_BytesPerPixel == 1 )
    {
    *this->m_pPosition ^= color;
    }
    else if ( this->m_pSurface->m_BytesPerPixel == 2 )
    {
    short *pWord = (short *)this->m_pPosition;
    *pWord ^= color;
    }
    else if ( this->m_pSurface->m_BytesPerPixel == 3 )
    {
    char *pTemp = (char *)&color;
    this->m_pPosition[0] ^= pTemp[2];
    this->m_pPosition[1] ^= pTemp[1];
    this->m_pPosition[2] ^= pTemp[0];
    }
    else if ( this->m_pSurface->m_BytesPerPixel == 4 )
    {
    char *pTemp = (char *)&color;
    this->m_pPosition[0] ^= pTemp[2];
    this->m_pPosition[1] ^= pTemp[1];
    this->m_pPosition[2] ^= pTemp[0];
    }
    else
    {
    // ACK ACK ACK!
    ASSERT( false );
    } }
    #endifvoid
    PixelDrawingSurface::PixelIterator::SetPixel( int color )
    {  
    if ( this->m_pSurface->GetDrawMode() != RasterConstants::MODE_XOR )
    {
    // copyPixel( color );
    if ( this->m_pSurface->m_BytesPerPixel == 1 )
    {
    *this->m_pPosition = color;
    }
    else if ( this->m_pSurface->m_BytesPerPixel == 2 )
    {
    // short *pWord = (short *)this->m_pPosition;
    // *pWord = color;
    *(short *)this->m_pPosition=color;
    }
    else if ( this->m_pSurface->m_BytesPerPixel == 3 )
    {
    char *pTemp = (char *)&color;
    this->m_pPosition[0] = pTemp[2];
    this->m_pPosition[1] = pTemp[1];
    this->m_pPosition[2] = pTemp[0];
    }
    else if ( this->m_pSurface->m_BytesPerPixel == 4 )
    {
    char *pTemp = (char *)&color;
    this->m_pPosition[0] = pTemp[2];
    this->m_pPosition[1] = pTemp[1];
    this->m_pPosition[2] = pTemp[0];
    }
    else
    {
    // ACK ACK ACK!
    ASSERT( false );
    }
    }
    else
    {
    // xorPixel( color );
    if ( this->m_pSurface->m_BytesPerPixel == 1 )
    {
    *this->m_pPosition ^= color;
    }
    else if ( this->m_pSurface->m_BytesPerPixel == 2 )
    {
    // short *pWord = (short *)this->m_pPosition;
    // *pWord ^= color;
    *(short *)this->m_pPosition^=color;
    }
    else if ( this->m_pSurface->m_BytesPerPixel == 3 )
    {
    char *pTemp = (char *)&color;
    this->m_pPosition[0] ^= pTemp[2];
    this->m_pPosition[1] ^= pTemp[1];
    this->m_pPosition[2] ^= pTemp[0];
    }
    else if ( this->m_pSurface->m_BytesPerPixel == 4 )
    {
    char *pTemp = (char *)&color;
    this->m_pPosition[0] ^= pTemp[2];
    this->m_pPosition[1] ^= pTemp[1];
    this->m_pPosition[2] ^= pTemp[0];
    }
    else
    {
    // ACK ACK ACK!
    ASSERT( false );
    }
    }
    }
    // ************************************
    // CLASS IMPLEMENTATION
    // 
    // PixelDrawingSurface
    //// ************************************
    // CTOR -- class PixelDrawingSurface
    //
    PixelDrawingSurface::PixelDrawingSurface( int sizex, int sizey, void *bits, int bytesperpixel )
    {
    m_SizeX = sizex;
    m_SizeY = sizey;
    m_Bits = bits;
    m_BytesPerPixel = bytesperpixel; m_pLineIterator = new PixelIterator( this ); m_DrawMode = RasterConstants::MODE_COPY;
    }// ***************************************
    // DTOR -- class PixelDrawingSurface
    //
    PixelDrawingSurface::~PixelDrawingSurface( void )
    {
    delete m_pLineIterator;
    m_pLineIterator = NULL;
    }
      

  5.   

    非常谢谢,不过:
    new PixelIterator( this );
    中的PixelIterator是什么类?
    或者说你的这段程序,用到了其他的什么库没有?
      

  6.   

    我有这样的需求,是因为我自己要写一个简单的GUI,
    这个GUI可能要在windows或其他操作系统下做模拟演示,
    除了将内存中的内容显示到屏幕上外,不能使用任何其他的API或类库前面的兄弟给了一段代码,这段代码中有:
    m_pLineIterator->SetPixel( Color );
    也就是说不付要求。其实我就只是要:将指定的任意内存段的内容画到屏幕上,写成函数接口就是:
    putToScreen(const void *pAddr,const int iSize);请您告诉我,如何在windows下实现?
      

  7.   

    再说百点,就是DirectX的页面是如何画到屏幕上的?
    是不是要我自己调用显示驱动程序?
      

  8.   

    我觉得可以用CBitmap类里面的几个函数及结合CDC来达到你的要求:
    其中BOOL CreateCompatibleBitmap( CDC* pDC, int nWidth, int nHeight );
    是最重要的一个函数,其它几个函数,我一时想不起了?!哪位知道的说说!