2011-12-14 35 views
11

Tôi muốn tắt màn hình hiển thị điều khiển cho một số bitmap để tôi có thể truy cập nhanh vào bitmap đó.Vô hiệu hóa thành bitmap riêng

Thật không may Control.DrawToBitmap dường như rút toàn bộ quyền kiểm soát mà nó được gọi là bao gồm tất cả các điều khiển con của nó. Bên trong nó phát hành một tin nhắn WM_PRINT với DC tự cung cấp cho một bitmap. Bitmap tạm thời này sau đó được blitted vào Bitmap do người dùng cung cấp. Không thể chấp nhận đối với tôi, tôi muốn có bản cập nhật bitmap này khi cần thiết để hiệu suất của tôi đạt khi bitmap là cần thiết được giảm thiểu.

Trong trường hợp lý tưởng, tôi muốn biểu mẫu hoạt động như thể nó hiển thị trên màn hình (nhưng không thể). Điều đó có nghĩa là nếu một số Kiểm soát có thuộc tính Text của nó thay đổi, biểu mẫu sẽ bị vô hiệu một phần. Việc nắm bắt các thông điệp/sự kiện có liên quan sau đó sẽ cho phép tôi chỉ định DC của riêng tôi cho biểu mẫu được vẽ trên hoặc chỉ đơn giản là BitBlt các biểu mẫu DC cho riêng tôi.

Một số hướng dẫn tôi luôn nhìn vào:

  • Các PaintEventArgs tham số trong OnPaint dường như để giữ một thành viên savedGraphicsState, có lẽ nó có thể được sử dụng để tìm ra những gì không yêu cầu hủy bỏ hiệu lực
  • Có các hình thức có thể nhìn thấy nhưng bên ngoài khu vực màn hình. Kiểm soát sau đó không nhận được sơn, mặc dù.
  • thủ gọi RedrawWindow() trên cửa sổ, cùng câu chuyện
+0

Tôi không hoàn toàn rõ ràng về lý do tại sao 'DrawToBitmap' (thông điệp' WM_PRINT') không thể chấp nhận cho việc sử dụng của bạn. Bạn có lo lắng về * hiệu suất *? Nó rất khó có khả năng vẽ vào một bitmap sẽ chậm hơn so với việc vẽ lên màn hình. –

+0

Tôi cần một cơ chế đệm. DrawToBitmap vẽ toàn bộ điều khiển từ đầu, trong khi hệ thống vô hiệu hóa được sử dụng trên các cửa sổ bình thường sẽ chỉ cập nhật các khu vực thực sự thay đổi. –

+0

@Frank, bạn có cân nhắc sử dụng Bitblt không? http://www.codeproject.com/KB/GDI-plus/Bitblt_wrapper_class.aspx –

Trả lời

1

Tôi nghĩ rằng có hai vấn đề:

  1. tìm ra khu vực không hợp lệ của điều khiển (không có sự giúp đỡ từ các cửa sổ)
  2. chỉ render phần không hợp lệ.

Đối với vấn đề đầu tiên, tôi nghĩ rằng bạn phần lớn là của riêng bạn. Bạn nên theo dõi kiểm soát thay đổi và có sổ sách kế toán cần cập nhật.

Đối với vấn đề thứ hai, bạn có thể tự mình gửi bản tin WM_PRINT và cung cấp DC chỉ đề cập đến một bitmap nhỏ. DC API ban đầu cho phép bạn bù đắp và cắt vùng vẽ hợp lệ của HDC. Nếu bạn rất may mắn, cửa sổ sẽ suy ra vùng render từ HDC, và nếu không, hầu hết các lệnh render hoàn toàn nằm ngoài bitmap sẽ khá rẻ vì không có pixel cần thay đổi.

Bạn có thể xác minh điều này bằng cách in tới bitmap 1x1 và kiểm tra xem nó có nhanh hơn không và/hoặc xác minh xem vùng clip được gửi trong WM_PAINT có bị giảm xuống kích thước bitmap hay không.

0

Tôi nghĩ rằng nó sẽ làm việc, nếu kiểm soát được nhân bản vô tính, do đó bạn sẽ có được một điều khiển mà không ngồi trên một hình thức và trong đó không có điều khiển con:

Control ctrl = ControlFactory.CloneCtrl(this.button3); 
Bitmap bmp = new Bitmap(ctrl.Width, ctrl.Height); 
ctrl.DrawToBitmap(bmp, new Rectangle(0, 0, ctrl.Width, ctrl.Height)); 
bmp.Save(@"C:\Users\Oli\Desktop\test.bmp"); 

tôi đã sử dụng được viết bởi lxwde tìm thấy trong The Code Project.

ControlFactory không hoàn hảo, nhưng nó đủ đơn giản và có thể dễ dàng cải thiện.

+0

Xin lỗi, tôi không thấy điều này có liên quan như thế nào. –

+0

Bạn nói rằng giải pháp của bạn không may vẽ điều khiển con. Giải pháp của tôi thì không. Tôi đã thử nó với một bảng điều khiển có chứa các nút. Nó chỉ vẽ bảng điều khiển đến bitmap nhưng không có điều khiển con. Nó cũng hoạt động khi điều khiển không hiển thị trên màn hình. –

+0

Tôi không thực sự hiểu những gì bạn đang cố gắng đạt được. Bạn nói: "Tôi muốn biểu mẫu hoạt động như thể nó hiển thị trên màn hình (nhưng không thể)". Tại sao nó không hiển thị trên màn hình? Tại sao bạn muốn hiển thị biểu mẫu không hiển thị trên màn hình? –

0

Tôi đã tạo một dự án mẫu cho bạn nơi tôi đã hiển thị một số sự kiện onPaint. Nếu bạn không thể nhìn thấy nó được giải quyết theo cách đó, chỉ cần cập nhật ví dụ.

Trân trọng! OnPaint example

Tải ở đây: http://www.goldengel.ch/temp/OnPaintExample.zip

Private Sub Button1_Paint(sender As System.Object, e As System.Windows.Forms.PaintEventArgs) Handles Button1.Paint 
    Dim bm As New Bitmap(Me.Button1.Width, Me.Button1.Height, PixelFormat.Format32bppRgb) 

    Button1.DrawToBitmap(bm, New Rectangle(0, 15, bm.Width -5, bm.Height+2)) 
    Using gr As Graphics = Graphics.FromImage(bm) 
     gr.DrawString(DateTime.Now.ToLongTimeString, Me.Font, Brushes.Lime, 0, 0) 
    End Using 
    Me.PictureBox1.BackgroundImageLayout = ImageLayout.Tile 
    Me.PictureBox1.BackgroundImage = bm 

End Sub 
    Public Class myTextBox 
     Inherits System.Windows.Forms.TextBox 


     Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs) 
      MyBase.OnPaint(e) 
      e.Graphics.Clear(Color.Yellow) 
      e.Graphics.DrawString(DateTime.Now.ToLongTimeString, Me.Font, Brushes.Gray, 0, 0) 
     End Sub 

     Public Sub New() 
      SetStyle(ControlStyles.UserPaint, True) 
     End Sub 
    End Class 
Các vấn đề liên quan