2010-01-27 60 views
0

我有一個下載的圖像應用程序在手機上。每次圖像下載成功時,它都會自動繪製到臨時位圖,然後onPaint方法繪製整個臨時位圖。它導致了很多事情發生。用GDI函數繪製圖像

我的老師建議我每次加載一個圖像時使用GDI函數在屏幕上繪製臨時位圖。但他的建議對於這兩種方法是如此普遍。

[DllImport("coredll.dll")] 
    static extern IntPtr GetDC(IntPtr hwnd); 

    [DllImport("coredll.dll")] 
    static extern void ReleaseDC(IntPtr dc); 

因此,在這種情況下,他提出了什麼更明確的建議嗎?提前致謝。

UPDATE

//This is my buffer bitmap 
    private Graphics offGraph; 
    private Bitmap offBitmap; 

    //everytime an image is loaded, it raise an event and then I draw it on buffer. 
    private void ImageLoadDone(object sender, EventArgs e) 
    { 
     ImageObj LoadedImg = (ImageObj)sender; 
     LoadedImg.Render(offGraph); 
     this.BeginInvoke(new EventHandler(ImageUpdate)); 
    } 

    private void ImageUpdate(object sender, EventArgs myE) 
    { 
     this.Render(); 
    } 

    //and then onPaint draw the offbitmap. 
    private void Render() 
    { 
     CtrlGraph.DrawImage(offBitmap,0,0); 
    } 

回答

2

是的 - 您需要進行雙緩衝以防止閃爍問題,但是您可以在GDI +中執行此操作,而無需使用API​​。這裏的本質,你需要做的:

private Bitmap backgroundBitmap; 
private Graphics backgroundGraphics; 
private Rectangle rect; 
private Rectangle srcRect; 

// create background bitmap the same size as your screen 
backgroundBitmap = new Bitmap(this.Width, this.Height); 
// create background buffer 
backgroundGraphics = Graphics.FromImage(backgroundBitmap); 
// get current screen graphics 
g = this.CreateGraphics(); 

rect = new Rectangle(0, 0, this.ClientRectangle.Width, this.ClientRectangle.Height); 
srcRect = new Rectangle(0, 0, bmp.Width, bmp.Height); 


Then when you receive your event and need to update the screen, call your own method: 

Render(); 

private void Render() 
    {    
     // draw your image onto the background buffer 
     backgroundGraphics.DrawImage(bmp, rect, srcRect, GraphicsUnit.Pixel); 
     // draw whatever you need to on the background graphics 
    backgroundGraphics.DrawImage(.....) 


     // after all images are drawn onto the background surface 
     // blit back buffer to on the screen in one go 
     g.DrawImage(backgroundBitmap, this.ClientRectangle, 
      new Rectangle(0, 0, this.ClientRectangle.Width, this.ClientRectangle.Height), GraphicsUnit.Pixel); 

    } 

不叫this.Refresh()或當您嘗試更新屏幕,因爲這是什麼原因造成的閃爍油漆事件,只需調用render()方法直接當你需要更新屏幕時。 你只要調用paint方法時,首先繪製屏幕時,應用程序加載

我從我的緊湊型框架的遊戲把這個代碼

+0

確保您銷燬IDisposable對象。特別是位圖。 http://blog.opennetcf.com/ctacke/PermaLink,guid,987041fc-2e13-4bab-930a-f79021225b74.aspx – Bryan 2010-01-27 22:01:19

+0

我剛剛更新了我的代碼。這非常有幫助。順便說一句,是this.CreateGraphics()最好的選擇,當我們要避免閃爍,忽略onPaint方法? – Thyphuong 2010-01-28 01:47:36

+0

Thyphuong - 是的,忽略onPaint並在每次需要更新屏幕時調用Render()...您需要調用onPaint的唯一時間是當您a)初始繪製屏幕時b)如果窗口已調整大小c)if另一種形式出現在它上面 例如,它可能會在onResize或onActivated事件上調用 – 2010-02-05 15:50:53

0

IIRC,如果你的標籤是正確的,如果你使用C#,那麼你可以使用GDI +。 GDI來自Win32,對於WinForms來說基本上是遺留的。

Check this out for information on GDI+

而且,你所描述的閃爍聽起來像沒有雙緩衝形式的產物。閱讀here以瞭解如何對錶單進行雙緩衝。

+0

也許我誤解你,但你的鏈接剛纔提到關於繪製圖形的方法,這就是不是我所需要的。我認爲我想要的是我當前的Graphic的getDC,並用它來繪製臨時位圖,但不知道如何。 正如我所說,在使用Onpaint方法繪製它之前,我將所有繪製在臨時位圖中,所以我認爲它已經具有雙重緩衝。 – Thyphuong 2010-01-27 10:00:53

+1

雙緩衝將您的位圖繪製到緩衝區,而不是在onPaint期間直接繪製。給文章閱讀哥們,你不會失望。另外,我的第一點是,使用GDI +時不需要getDC/releaseDC,而使用WinForms使用GDI不是一個好主意。 – acron 2010-01-27 10:18:26