What am I missing? (painting directly on screen dc using GDI API calls)

J

Joergen Bech

Am trying to paint a simple rectangle directly on the screen DC
using the code below, but nothing happens?!?

Weird. Anyone who can tell me what I am doing wrong? This
ought to be straightforward, but ... :(

TIA,

Joergen Bech

---

'Start new project, add a button to a form, then paste the following
'code:

Private Declare Function GetDesktopWindow Lib "user32" () As Int32
Private Declare Function GetDC Lib "user32" (ByVal hwnd As Int32)
As Int32
Private Declare Function ReleaseDC Lib "user32" (ByVal hwnd As
Int32, ByVal hdc As Int32) As Int32
Private Declare Function SelectObject Lib "gdi32" (ByVal hDC As
Int32, ByVal hObject As Int32) As Int32
Private Declare Function CreatePen Lib "gdi32" (ByVal nPenStyle As
Int32, ByVal nWidth As Int32, ByVal crColor As Int32) As Int32
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject
As Int32) As Int32
Private Declare Function Rectangle Lib "gdi32" (ByVal hDC As
Int32, ByVal X1 As Int32, ByVal Y1 As Int32, ByVal X2 As Int32, ByVal
Y2 As Int32) As Int32
Private Declare Function CreateBrushIndirect Lib "gdi32" (ByRef
lpLogBrush As LOGBRUSH) As Int32

Private Structure LOGBRUSH
Dim lbColor As Int32
Dim lbHatch As Int32
Dim lbStyle As Int32
End Structure

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles Button1.Click
Test()
End Sub

Private Sub Test()
Dim newBrush As Int32
Dim newPen As Int32
Dim oldBrush As Int32
Dim oldPen As Int32

Dim dl As Int32
Dim lb As LOGBRUSH

' Get the desktop size in pixels.
Dim desktop_win As Int32 = GetDesktopWindow()
Dim desktop_dc As Int32 = GetDC(desktop_win)

Debug.WriteLine(desktop_win)
Debug.WriteLine(desktop_dc)

' Do something with the desktop device context
lb.lbStyle = 0 'BS_SOLID
lb.lbColor = 0
lb.lbHatch = 0

newBrush = CreateBrushIndirect(lb)
newPen = CreatePen(0, 10, 0) 'Style=PS_SOLID

oldBrush = SelectObject(desktop_dc, newBrush)
oldPen = SelectObject(desktop_dc, newPen)

Rectangle(desktop_dc, 0, 0, 100, 200)

dl = SelectObject(desktop_dc, oldPen)
dl = SelectObject(desktop_dc, oldBrush)

DeleteObject(newPen)
DeleteObject(newBrush)

' Release the bitmap's and desktop's DCs.
ReleaseDC(desktop_win, desktop_dc)

End Sub
 
M

Mattias Sjögren

Joergen,
Am trying to paint a simple rectangle directly on the screen DC
using the code below, but nothing happens?!?

I believe you want to use GetDC(0) rather than
GetDC(GetDesktopWindow()).

And if you care about 64-bit compatibility, you really should use
IntPtr rather than Int32 for all handle parameters.



Mattias
 
J

Joergen Bech

Joergen,


I believe you want to use GetDC(0) rather than
GetDC(GetDesktopWindow()).

Yep. That was it. I got the GetDesktopWindow() code from
a screen grabber program. Worked great for the screen grabber,
but not for me.
And if you care about 64-bit compatibility, you really should use
IntPtr rather than Int32 for all handle parameters.

OK. Will do. Thanks. I was wondering about that. Seems like
Integer/IntPtr/Int32 are used randomly depending on what
sample code one is looking at. I just picked one.

I converted all handles to IntPtr, but this meant that I could not
use GetDC(0) as the compiler complained about not being able
to convert an integer to intptr.

I used GetDC(Nothing) instead. Check the revised code/definitions
below. Is this correct? Seems to work now.

/Joergen Bech

----

Private Declare Function GetDesktopWindow Lib "user32" () As
IntPtr
Private Declare Function GetDC Lib "user32" (ByVal hwnd As IntPtr)
As IntPtr
Private Declare Function ReleaseDC Lib "user32" (ByVal hwnd As
IntPtr, ByVal hdc As IntPtr) As IntPtr
Private Declare Function SelectObject Lib "gdi32" (ByVal hDC As
IntPtr, ByVal hObject As IntPtr) As IntPtr
Private Declare Function CreatePen Lib "gdi32" (ByVal nPenStyle As
Int32, ByVal nWidth As Int32, ByVal crColor As Int32) As IntPtr
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject
As IntPtr) As Int32
Private Declare Function Rectangle Lib "gdi32" (ByVal hDC As
IntPtr, ByVal X1 As Int32, ByVal Y1 As Int32, ByVal X2 As Int32, ByVal
Y2 As Int32) As Int32
Private Declare Function CreateBrushIndirect Lib "gdi32" (ByRef
lpLogBrush As LOGBRUSH) As IntPtr

Private Structure LOGBRUSH
Dim lbColor As Int32
Dim lbHatch As Int32
Dim lbStyle As Int32
End Structure

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles Button1.Click
Test()
End Sub

Private Sub Test()
Dim newBrush As IntPtr
Dim newPen As IntPtr
Dim oldBrush As IntPtr
Dim oldPen As IntPtr

Dim dl As IntPtr
Dim lb As LOGBRUSH

' Get the desktop size in pixels.
Dim desktop_dc As IntPtr = GetDC(Nothing)

' Do something with the desktop device context
lb.lbStyle = 0 'BS_SOLID
lb.lbColor = 0
lb.lbHatch = 0

newBrush = CreateBrushIndirect(lb)
newPen = CreatePen(0, 10, 0) 'Style=PS_SOLID

oldBrush = SelectObject(desktop_dc, newBrush)
oldPen = SelectObject(desktop_dc, newPen)

Rectangle(desktop_dc, 0, 0, 100, 200)

dl = SelectObject(desktop_dc, oldPen)
dl = SelectObject(desktop_dc, oldBrush)

DeleteObject(newPen)
DeleteObject(newBrush)

' Release the bitmap's and desktop's DCs.
ReleaseDC(Nothing, desktop_dc)

End Sub
 
J

Jay B. Harlow [MVP - Outlook]

Joergen,
OK. Will do. Thanks. I was wondering about that. Seems like
Integer/IntPtr/Int32 are used randomly depending on what
sample code one is looking at. I just picked one.
Integer is an alias for Int32 so you can use them interchangeable. I
normally use Integer for VB.NET code, while I will use Int32 for API calls.


IntPtr represents a platform independent pointer. For the current 32-bit
version of .NET it is a 32-bit pointer, for the 64-bit version of .NET
(available as part of VS.NET 2005, aka Whidbey, due out later in 2005)
IntPtr will be a 64-bit pointer.

I converted all handles to IntPtr, but this meant that I could not
use GetDC(0) as the compiler complained about not being able
to convert an integer to intptr.
I used GetDC(Nothing) instead. Check the revised code/definitions
below. Is this correct? Seems to work now.

I normally IntPtr.Zero when I need to pass a 0 to an IntPtr, Nothing will
work also, as Nothing represents the "default" value for the type, IntPtr is
a structure, so Nothing = 0 for it...

Hope this helps
Jay
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top