1
votes

Edit: Fixed, I created a compatibleDC for the graphics object, and a handle for the bitmap (using b.gethbitmap), then used the SelectObject function inside GDI to select those two, and used the compatibleDC instead of hDc in the BitBlt function

I've been trying to draw a bitmap to the screen (device 0), however I have encountered a problem copying the graphics using BitBlt.

Initially, I was drawing directly to the desktop using SetPixel (gdi32), but it was slow, so now I am setting the pixels of a bitmap object and then creating graphics from that object, and copying the hdc of the graphics to the screen.

My guess is that I am adding the HDC of the graphics object to an intptr, which essentially gives me the HDC of the container of the graphics object, which is not what I need. However even so, I have not found any information on how I could copy a bitmap to a device other than using BitBlt.

This is my current code (Windows forms app, textbox, button) The textbox is the device to copy to, and the button starts it. For testing purposes, set the textbox text to 0, and press the button. You should see a black box (50x50px) in the top left corner of your screen. The colour should be blue if it is working correctly:

Public Class Form1
Declare Function GetDC Lib "user32.dll" (ByVal hwnd As Int32) As Int32
Declare Function ReleaseDC Lib "user32.dll" (ByVal hwnd As Int32, ByVal hdc As Int32) As Int32
Declare Function SetPixel Lib "gdi32.dll" (ByVal hdc As Integer, ByVal x As Integer, ByVal y As Integer, ByVal crColor As Integer) As Integer
Declare Function BitBlt Lib "gdi32.dll" (ByVal hdcDest As IntPtr, ByVal nXDest As Integer, ByVal nYDest As Integer, ByVal nWidth As Integer, ByVal nHeight As Integer, ByVal hdcSrc As IntPtr, ByVal nXSrc As Integer, ByVal nYSrc As Integer, ByVal dwRop As Int32) As Boolean
Declare Function CreateCompatibleBitmap Lib "gdi32.dll" (ByVal hdc As IntPtr, ByVal nWidth As Integer, ByVal nHeight As Integer) As IntPtr
Declare Function CreateCompatibleDC Lib "gdi32.dll" (ByVal hdc As IntPtr) As IntPtr
Dim x As Integer
Sub setpx(ByVal location As Point, ByVal color As Color)
    b.SetPixel(location.X, location.Y, color)
End Sub
Sub drawrectangle(ByVal device As Integer, ByVal location As Point, ByVal size As Point, ByVal color As Color)
    b = New Bitmap(size.X, size.Y)
    For i = location.X To size.X - 1
        For z = location.Y To size.Y - 1
            setpx(New Point(i, z), color)
        Next
    Next
    g = Graphics.FromImage(b)
    Dim hDc As IntPtr = g.GetHdc
    BitBlt(GetDC(device), location.X, location.Y, size.X, size.Y, hDc, location.X, location.Y, 13369376)
    ReleaseDC(device, GetDC(device))
End Sub
Dim b As Bitmap
Dim g As Graphics
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Buttnon1.Click
    Dim r As New Random
    Dim timestart As Integer = Now.TimeOfDay.TotalMilliseconds
    drawrectangle(TextBox1.Text, New Point(1, 1), New Point(50, 50), Color.Blue)
    MsgBox(Now.TimeOfDay.TotalMilliseconds - timestart)
End Sub
End Class

The way it works is it calls the function setpx, given a location and color from within a loop iterating through all of the pixels in a box (50x50 in my code). The setpx function will then call the setpixel function on a bitmap b. This part is working fine.

Next, it will define a graphics object g from the bitmap, and I use BitBlt to copy g's hdc (g.gethdc) to the screen. This is not working correctly, is this the correct way of doing this?

1

1 Answers

0
votes

You are passing Textbox1.text as a device descriptor, that won't work...You want textbox1.hwnd