На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
  
> Как использовать IntersectClip(...) ?
    Есть большое окно 15000*5000. На всей его плошади что то рисуется. Но если все просто рисовать - будут жуткие тормоза. На C++ я использовал технику IntersectRect() следующим образом:


    void CBrainLogicView_Graph::OnDraw(CDC* pDC)
    {

     CBrainLogicDoc* pDoc = GetDocument();
     ASSERT_VALID(pDoc);
     // TODO: add draw code for native data here
     
     CDC dc;
     CDC* pDrawDC = pDC;
     CBitmap bitmap;
     CBitmap* pOldBitmap;
     
     // --------------------------------------------------------
     // Обновляем только тот участок, который в этом нуждается
     // --------------------------------------------------------

     CRect client;
     pDC->GetClipBox(client);
     CRect rect = client;
     DocToClient(rect);
     
     
     if (!pDC->IsPrinting())
     {
      // draw to offscreen bitmap for fast looking repaints
      if (dc.CreateCompatibleDC(pDC))
      {
       if (bitmap.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height()))
       {
        OnPrepareDC(&dc, NULL);
        pDrawDC = &dc;
       
        dc.OffsetViewportOrg(-rect.left, -rect.top);
        pOldBitmap = dc.SelectObject(&bitmap);
        dc.SetBrushOrg(rect.left % 8, rect.top % 8);
       
        // might as well clip to the same rectangle
        dc.IntersectClipRect(client);
       }
      }
     }
     
     // --------------------------------------------------------
     // Очищаем задний фон
     // --------------------------------------------------------

     CBrush brush;
     if (!brush.CreateSolidBrush(RGB(255,255,255)))
      return;
     
     brush.UnrealizeObject();
     pDrawDC->FillRect(client, &brush);
     
     // --------------------------------------------------------
     // Здесь на pDrawDC я рисую абсолютно на всей площади окна
     // --------------------------------------------------------
     
     
     if (pDrawDC != pDC)
     {
      pDC->SetViewportOrg(0, 0);
      pDC->SetWindowOrg(0,0);
      pDC->SetMapMode(MM_TEXT);
      dc.SetViewportOrg(0, 0);
      dc.SetWindowOrg(0,0);
      dc.SetMapMode(MM_TEXT);
      pDC->BitBlt(rect.left, rect.top, rect.Width(), rect.Height(),
       &dc, 0, 0, SRCCOPY);
      dc.SelectObject(pOldBitmap);
     }


    }


    А как сделать текое же на С#? Двойную буфферизацию я сделал вот так:


    class Form1{

         private Image memImage_;      
         private Graphics memGraphics_;

         private void Form1_Load(object sender, System.EventArgs e)
         {
            memImage_ = new Bitmap(this.Width,this.Height);
            memGraphics_ = Graphics.FromImage(memImage_);
         }

         private void Form1_Resize(object sender, System.EventArgs e)
         {
            memImage_ = new Bitmap(Size.Width, Size.Height);
            memGraphics_ = Graphics.FromImage(memImage_);
         }

         private void Form1_Paint(object sender,
            System.Windows.Forms.PaintEventArgs e)
         {
            memGraphics_.DrawRectangle(new Pen(Color.Red),10,10,80,80);
            e.Graphics.DrawImageUnscaled(memImage_,0,0);
         }

       
    }



    А вот использовать IntersectClip не получается ... Хотя в MSDNе и написано как это счастье использовать -
    ms-help://MS.MSDNQTR.2003JUL.1033/cpref/html/frlrfsystemdrawinggraphicsclassintersectcliptopic.htm
    Может кто нить и в этом шарит ???
      Если кому интересно, ну или просто в благодарность тем кто не поленился прочитать весь предидущий бред ... Сделать окно большого размера, со скролами, и чтобы прорисовывалась только область нуждающаяся в прорисовке можно так:



      private Image memImage_;      
      private Graphics memGraphics_;
      static SolidBrush bkgndBrush_ = new SolidBrush(Color.White);
      static SolidBrush blackBrush_ = new SolidBrush(Color.Black);

      private void Form1_Load(object sender, System.EventArgs e)
      {
       memImage_ = new Bitmap(this.ClientSize.Width,this.ClientSize.Height);
       memGraphics_ = Graphics.FromImage(memImage_);
      }

      private void Form1_Resize(object sender, System.EventArgs e)
      {
       memImage_ = new Bitmap(this.ClientSize.Width,this.ClientSize.Height);
       memGraphics_ = Graphics.FromImage(memImage_);
       Invalidate();
      }

      private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
      {
       // Сбрасываем начало координат в 0,0 и очищаем фон
       memGraphics_.TranslateTransform(-memGraphics_.Transform.OffsetX,
        -memGraphics_.Transform.OffsetY, MatrixOrder.Append);
       memGraphics_.FillRectangle(bkgndBrush_,0,0,this.ClientSize.Width,this.ClientSize.Height);
       memGraphics_.TranslateTransform(this.AutoScrollPosition.X-e.ClipRectangle.X,
        this.AutoScrollPosition.Y-e.ClipRectangle.Y, MatrixOrder.Append);
         
       // Здесь можно рисовать на memGraphics_
       memGraphics_.FillRectangle(blackBrush_,30,30,70,70);

       e.Graphics.DrawImageUnscaled(memImage_,e.ClipRectangle.X,e.ClipRectangle.Y,    e.ClipRectangle.Width, e.ClipRectangle.Height);
      }


      protected override void OnPaintBackground(PaintEventArgs pevent)
      {
       // Не вызываем базовую функцию прорисовки фона
       // base.OnPaintBackground (pevent);
      }




      Ну вот и все ... Скорость прорисовки окна 15000*30000 очень хорошая, хотя вся площадь испещрена графикой.

      1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
      0 пользователей:


      Рейтинг@Mail.ru
      [ Script execution time: 0,0168 ]   [ 15 queries used ]   [ Generated: 31.05.24, 09:22 GMT ]