Connecting Tech Pros Worldwide Forums | Help | Site Map

Drawing on a .Net device context from a vb6 dll

Metallicraft
Guest
 
Posts: n/a
#1: Nov 20 '05
I have a vb6 application. On the main form is a picture
box with one or two images and several pieces of text
displayed in it. These are created on the fly using gdi32
routines that are all in a referenced, custom dll. I call
a PrintImage routine in the dll and pass it only the the
Picturebox.hdc from the main form. The dll's print routine
draws to the hdc and it shows up in the picturebox
perfectly.

I would like to do a similar thing with an asp.net page
using my same vb6 custom printing dll. Where Display.aspx
has and IMG tag with src="Image.aspx". Now, in the
Image.aspx.vb code, I make the necessary calls to my dll
to preload some data, then I call the PrintImage routine.
What I get back is a black box. Since it's an asp.net page
I don't have a picturebox to draw to (even if I did, I'm
not sure the picturebox's Handle would be the same as
vb6's hdc). So I'm trying to create a bitmap in .net where
i can eventually get an hdc that I can send to my printing
routine in the vb6 dll. Below is the code I use to do this:

Dim bm As Bitmap = New Bitmap(728, 312)
Dim gfx As Graphics = Graphics.FromImage(bm)
gfx.Clear(Color.White)
Dim hDC As IntPtr = gfx.GetHdc()
prt.hdc = hDC.ToInt32 'prt.hdc is the property in my vb6
dll that receives the hdc to print to

The code runs without error, I save the bitmap to a file,
read it into a bytearray, and do a
Response.Binarywrite...I get a black box (well, now I get
a white box since I added the gfx.Clear line above).

Why can't my vb6 printing dll draw to a .net hdc?

PS. I eventually don't want to have to save the bitmap to
a file. If I can get the correct drawing on a device
context, I'd like to be able to stream that directly to a
byte array and do a Response.Binarywrite.

If an expert can help with my main issue and my PS. I
would greatly appreciate it.



Dmitriy Lapshin [C# / .NET MVP]
Guest
 
Posts: n/a
#2: Nov 20 '05

re: Drawing on a .Net device context from a vb6 dll


Hi,

You can try calling ReleaseDC after the VB6 dll has finished drawing. The
rest of .NET code looks correct. You might also want to debug your VB6 dll
to see where it possibly fails.

--
Dmitriy Lapshin [C# / .NET MVP]
X-Unity Test Studio
http://x-unity.miik.com.ua/teststudio.aspx
Bring the power of unit testing to VS .NET IDE

"Metallicraft" <anonymous@discussions.microsoft.com> wrote in message
news:066e01c3a3a4$58879370$a001280a@phx.gbl...[color=blue]
> I have a vb6 application. On the main form is a picture
> box with one or two images and several pieces of text
> displayed in it. These are created on the fly using gdi32
> routines that are all in a referenced, custom dll. I call
> a PrintImage routine in the dll and pass it only the the
> Picturebox.hdc from the main form. The dll's print routine
> draws to the hdc and it shows up in the picturebox
> perfectly.
>
> I would like to do a similar thing with an asp.net page
> using my same vb6 custom printing dll. Where Display.aspx
> has and IMG tag with src="Image.aspx". Now, in the
> Image.aspx.vb code, I make the necessary calls to my dll
> to preload some data, then I call the PrintImage routine.
> What I get back is a black box. Since it's an asp.net page
> I don't have a picturebox to draw to (even if I did, I'm
> not sure the picturebox's Handle would be the same as
> vb6's hdc). So I'm trying to create a bitmap in .net where
> i can eventually get an hdc that I can send to my printing
> routine in the vb6 dll. Below is the code I use to do this:
>
> Dim bm As Bitmap = New Bitmap(728, 312)
> Dim gfx As Graphics = Graphics.FromImage(bm)
> gfx.Clear(Color.White)
> Dim hDC As IntPtr = gfx.GetHdc()
> prt.hdc = hDC.ToInt32 'prt.hdc is the property in my vb6
> dll that receives the hdc to print to
>
> The code runs without error, I save the bitmap to a file,
> read it into a bytearray, and do a
> Response.Binarywrite...I get a black box (well, now I get
> a white box since I added the gfx.Clear line above).
>
> Why can't my vb6 printing dll draw to a .net hdc?
>
> PS. I eventually don't want to have to save the bitmap to
> a file. If I can get the correct drawing on a device
> context, I'd like to be able to stream that directly to a
> byte array and do a Response.Binarywrite.
>
> If an expert can help with my main issue and my PS. I
> would greatly appreciate it.[/color]

Metallicraft
Guest
 
Posts: n/a
#3: Nov 20 '05

re: Drawing on a .Net device context from a vb6 dll


Thanks for responding.

I dispose of my bitmap and release the dc after I write
the bitmap to a file further down in the code. I know the
vb6 dll works in vb6. The vb6 dll is production software
already working in the hands of hundreds of clients.

I can do a:

gfx.DrawString("test", New Font("Arial", 24.0F),
Brushes.Black, 0, 0)
gfx.DrawRectangle(New Pen(Color.Black), New
Rectangle(2, 1, 725, 309))

....inside vb.net and get a bitmap with text and a
rectangle, but when passing the graphic's hdc
(Graphic.GetHdc.ToInt32) I get no drawing whatsoever from
the vb6 dll.
[color=blue]
>-----Original Message-----
>Hi,
>
>You can try calling ReleaseDC after the VB6 dll has[/color]
finished drawing. The[color=blue]
>rest of .NET code looks correct. You might also want to[/color]
debug your VB6 dll[color=blue]
>to see where it possibly fails.
>
>--
>Dmitriy Lapshin [C# / .NET MVP]
>X-Unity Test Studio
>http://x-unity.miik.com.ua/teststudio.aspx
>Bring the power of unit testing to VS .NET IDE
>
>"Metallicraft" <anonymous@discussions.microsoft.com>[/color]
wrote in message[color=blue]
>news:066e01c3a3a4$58879370$a001280a@phx.gbl...[color=green]
>> I have a vb6 application. On the main form is a picture
>> box with one or two images and several pieces of text
>> displayed in it. These are created on the fly using[/color][/color]
gdi32[color=blue][color=green]
>> routines that are all in a referenced, custom dll. I[/color][/color]
call[color=blue][color=green]
>> a PrintImage routine in the dll and pass it only the the
>> Picturebox.hdc from the main form. The dll's print[/color][/color]
routine[color=blue][color=green]
>> draws to the hdc and it shows up in the picturebox
>> perfectly.
>>
>> I would like to do a similar thing with an asp.net page
>> using my same vb6 custom printing dll. Where[/color][/color]
Display.aspx[color=blue][color=green]
>> has and IMG tag with src="Image.aspx". Now, in the
>> Image.aspx.vb code, I make the necessary calls to my dll
>> to preload some data, then I call the PrintImage[/color][/color]
routine.[color=blue][color=green]
>> What I get back is a black box. Since it's an asp.net[/color][/color]
page[color=blue][color=green]
>> I don't have a picturebox to draw to (even if I did, I'm
>> not sure the picturebox's Handle would be the same as
>> vb6's hdc). So I'm trying to create a bitmap in .net[/color][/color]
where[color=blue][color=green]
>> i can eventually get an hdc that I can send to my[/color][/color]
printing[color=blue][color=green]
>> routine in the vb6 dll. Below is the code I use to do[/color][/color]
this:[color=blue][color=green]
>>
>> Dim bm As Bitmap = New Bitmap(728, 312)
>> Dim gfx As Graphics = Graphics.FromImage(bm)
>> gfx.Clear(Color.White)
>> Dim hDC As IntPtr = gfx.GetHdc()
>> prt.hdc = hDC.ToInt32 'prt.hdc is the property in my vb6
>> dll that receives the hdc to print to
>>
>> The code runs without error, I save the bitmap to a[/color][/color]
file,[color=blue][color=green]
>> read it into a bytearray, and do a
>> Response.Binarywrite...I get a black box (well, now I[/color][/color]
get[color=blue][color=green]
>> a white box since I added the gfx.Clear line above).
>>
>> Why can't my vb6 printing dll draw to a .net hdc?
>>
>> PS. I eventually don't want to have to save the bitmap[/color][/color]
to[color=blue][color=green]
>> a file. If I can get the correct drawing on a device
>> context, I'd like to be able to stream that directly to[/color][/color]
a[color=blue][color=green]
>> byte array and do a Response.Binarywrite.
>>
>> If an expert can help with my main issue and my PS. I
>> would greatly appreciate it.[/color]
>
>.
>[/color]
Dmitriy Lapshin [C# / .NET MVP]
Guest
 
Posts: n/a
#4: Nov 20 '05

re: Drawing on a .Net device context from a vb6 dll


You can try calling a raw GDI function through P/Invoke on the HDC obtained
and see whether it works that way. If yes, you at least know the HDC being
passed is valid.

There also could be problems with VB6 COM DLL running on a separate thread
(as it runs in the Single-Threaded Apartment and ASP .NET is
multi-threaded), and I am not sure HDCs can be passed "as is" between
threads.

--
Dmitriy Lapshin [C# / .NET MVP]
X-Unity Test Studio
http://x-unity.miik.com.ua/teststudio.aspx
Bring the power of unit testing to VS .NET IDE

"Metallicraft" <anonymous@discussions.microsoft.com> wrote in message
news:083501c3a3af$6ff09d30$a001280a@phx.gbl...[color=blue]
> Thanks for responding.
>
> I dispose of my bitmap and release the dc after I write
> the bitmap to a file further down in the code. I know the
> vb6 dll works in vb6. The vb6 dll is production software
> already working in the hands of hundreds of clients.
>
> I can do a:
>
> gfx.DrawString("test", New Font("Arial", 24.0F),
> Brushes.Black, 0, 0)
> gfx.DrawRectangle(New Pen(Color.Black), New
> Rectangle(2, 1, 725, 309))
>
> ...inside vb.net and get a bitmap with text and a
> rectangle, but when passing the graphic's hdc
> (Graphic.GetHdc.ToInt32) I get no drawing whatsoever from
> the vb6 dll.
>[color=green]
> >-----Original Message-----
> >Hi,
> >
> >You can try calling ReleaseDC after the VB6 dll has[/color]
> finished drawing. The[color=green]
> >rest of .NET code looks correct. You might also want to[/color]
> debug your VB6 dll[color=green]
> >to see where it possibly fails.
> >
> >--
> >Dmitriy Lapshin [C# / .NET MVP]
> >X-Unity Test Studio
> >http://x-unity.miik.com.ua/teststudio.aspx
> >Bring the power of unit testing to VS .NET IDE
> >
> >"Metallicraft" <anonymous@discussions.microsoft.com>[/color]
> wrote in message[color=green]
> >news:066e01c3a3a4$58879370$a001280a@phx.gbl...[color=darkred]
> >> I have a vb6 application. On the main form is a picture
> >> box with one or two images and several pieces of text
> >> displayed in it. These are created on the fly using[/color][/color]
> gdi32[color=green][color=darkred]
> >> routines that are all in a referenced, custom dll. I[/color][/color]
> call[color=green][color=darkred]
> >> a PrintImage routine in the dll and pass it only the the
> >> Picturebox.hdc from the main form. The dll's print[/color][/color]
> routine[color=green][color=darkred]
> >> draws to the hdc and it shows up in the picturebox
> >> perfectly.
> >>
> >> I would like to do a similar thing with an asp.net page
> >> using my same vb6 custom printing dll. Where[/color][/color]
> Display.aspx[color=green][color=darkred]
> >> has and IMG tag with src="Image.aspx". Now, in the
> >> Image.aspx.vb code, I make the necessary calls to my dll
> >> to preload some data, then I call the PrintImage[/color][/color]
> routine.[color=green][color=darkred]
> >> What I get back is a black box. Since it's an asp.net[/color][/color]
> page[color=green][color=darkred]
> >> I don't have a picturebox to draw to (even if I did, I'm
> >> not sure the picturebox's Handle would be the same as
> >> vb6's hdc). So I'm trying to create a bitmap in .net[/color][/color]
> where[color=green][color=darkred]
> >> i can eventually get an hdc that I can send to my[/color][/color]
> printing[color=green][color=darkred]
> >> routine in the vb6 dll. Below is the code I use to do[/color][/color]
> this:[color=green][color=darkred]
> >>
> >> Dim bm As Bitmap = New Bitmap(728, 312)
> >> Dim gfx As Graphics = Graphics.FromImage(bm)
> >> gfx.Clear(Color.White)
> >> Dim hDC As IntPtr = gfx.GetHdc()
> >> prt.hdc = hDC.ToInt32 'prt.hdc is the property in my vb6
> >> dll that receives the hdc to print to
> >>
> >> The code runs without error, I save the bitmap to a[/color][/color]
> file,[color=green][color=darkred]
> >> read it into a bytearray, and do a
> >> Response.Binarywrite...I get a black box (well, now I[/color][/color]
> get[color=green][color=darkred]
> >> a white box since I added the gfx.Clear line above).
> >>
> >> Why can't my vb6 printing dll draw to a .net hdc?
> >>
> >> PS. I eventually don't want to have to save the bitmap[/color][/color]
> to[color=green][color=darkred]
> >> a file. If I can get the correct drawing on a device
> >> context, I'd like to be able to stream that directly to[/color][/color]
> a[color=green][color=darkred]
> >> byte array and do a Response.Binarywrite.
> >>
> >> If an expert can help with my main issue and my PS. I
> >> would greatly appreciate it.[/color]
> >
> >.
> >[/color][/color]

Metallicraft
Guest
 
Posts: n/a
#5: Nov 20 '05

re: Drawing on a .Net device context from a vb6 dll


Well, I've tried a couple different things.

I created a vb6 dll with the following code:

Option Explicit

Private Declare Function TextOut Lib "gdi32"
Alias "TextOutA" (ByVal hdc As Long, ByVal X As Long,
ByVal Y As Long, ByVal lpString As String, ByVal nCount As
Long) As Long

Public Sub DrawText(ByRef hdc As Long)
Dim dl As Long
dl = TextOut(hdc, 0, 0, "TEST", Len("TEST"))
End Sub

....and I compiled it.

I then created a vb application (referencing that dll)
with the following code:

Option Explicit

Private Sub Form_Load()
Picture1.AutoRedraw = True

Dim dt As DrawText.clsDrawText
Set dt = New DrawText.clsDrawText
dt.DrawText (Picture1.hDC)

Picture1.Refresh
End Sub

....the form contains one picture box.

When I run the app, I get the word "TEST" in the picture
box as I would expect.

Next, I created a vb.net Windows app, with only one form,
one button, and a picture box. I referenced my simple dll
above and the only code exists in the button_click:

Dim dt As New DrawText.clsDrawTextClass
dt.DrawText(PictureBox1.Handle.ToInt32)
dt = Nothing

PictureBox1.Refresh()

....I run the app, press the button, and get no text. I've
tried this with and without the Refresh and with and
without the PictureBox (using the form's handle instead)
with the same results.

I have also tried, in a vb.net app, adding this:

<System.Runtime.InteropServices.DllImportAttribu te
("gdi32.dll")> _
Private Shared Function TextOut(ByVal hdc As IntPtr,
ByVal X As Integer, ByVal Y As Integer, ByVal lpString As
String, ByVal nCount As Integer) As Integer
End Function

....to the top and in a button_click adding this:

TextOut(Me.Handle, 100, 100, "TESTING", 7)

....running it, pressing button, and getting no text.

So, even taking my dll and the graphics object out of the
equation, I can't get a gdi32 function, like TextOut, to
write on a .Net device context.

I understand that Object.GetHdc is a pointer, but is
Object.GetHdc.ToInt32 the same as a gdi32 device context
or vb6 picturebox.hdc?
[color=blue]
>-----Original Message-----
>You can try calling a raw GDI function through P/Invoke[/color]
on the HDC obtained[color=blue]
>and see whether it works that way. If yes, you at least[/color]
know the HDC being[color=blue]
>passed is valid.
>
>There also could be problems with VB6 COM DLL running on[/color]
a separate thread[color=blue]
>(as it runs in the Single-Threaded Apartment and ASP .NET[/color]
is[color=blue]
>multi-threaded), and I am not sure HDCs can be passed "as[/color]
is" between[color=blue]
>threads.
>
>--
>Dmitriy Lapshin [C# / .NET MVP]
>X-Unity Test Studio
>http://x-unity.miik.com.ua/teststudio.aspx
>Bring the power of unit testing to VS .NET IDE
>
>"Metallicraft" <anonymous@discussions.microsoft.com>[/color]
wrote in message[color=blue]
>news:083501c3a3af$6ff09d30$a001280a@phx.gbl...[color=green]
>> Thanks for responding.
>>
>> I dispose of my bitmap and release the dc after I write
>> the bitmap to a file further down in the code. I know[/color][/color]
the[color=blue][color=green]
>> vb6 dll works in vb6. The vb6 dll is production[/color][/color]
software[color=blue][color=green]
>> already working in the hands of hundreds of clients.
>>
>> I can do a:
>>
>> gfx.DrawString("test", New Font("Arial", 24.0F),
>> Brushes.Black, 0, 0)
>> gfx.DrawRectangle(New Pen(Color.Black), New
>> Rectangle(2, 1, 725, 309))
>>
>> ...inside vb.net and get a bitmap with text and a
>> rectangle, but when passing the graphic's hdc
>> (Graphic.GetHdc.ToInt32) I get no drawing whatsoever[/color][/color]
from[color=blue][color=green]
>> the vb6 dll.
>>[color=darkred]
>> >-----Original Message-----
>> >Hi,
>> >
>> >You can try calling ReleaseDC after the VB6 dll has[/color]
>> finished drawing. The[color=darkred]
>> >rest of .NET code looks correct. You might also want to[/color]
>> debug your VB6 dll[color=darkred]
>> >to see where it possibly fails.
>> >
>> >--
>> >Dmitriy Lapshin [C# / .NET MVP]
>> >X-Unity Test Studio
>> >http://x-unity.miik.com.ua/teststudio.aspx
>> >Bring the power of unit testing to VS .NET IDE
>> >
>> >"Metallicraft" <anonymous@discussions.microsoft.com>[/color]
>> wrote in message[color=darkred]
>> >news:066e01c3a3a4$58879370$a001280a@phx.gbl...
>> >> I have a vb6 application. On the main form is a[/color][/color][/color]
picture[color=blue][color=green][color=darkred]
>> >> box with one or two images and several pieces of text
>> >> displayed in it. These are created on the fly using[/color]
>> gdi32[color=darkred]
>> >> routines that are all in a referenced, custom dll. I[/color]
>> call[color=darkred]
>> >> a PrintImage routine in the dll and pass it only the[/color][/color][/color]
the[color=blue][color=green][color=darkred]
>> >> Picturebox.hdc from the main form. The dll's print[/color]
>> routine[color=darkred]
>> >> draws to the hdc and it shows up in the picturebox
>> >> perfectly.
>> >>
>> >> I would like to do a similar thing with an asp.net[/color][/color][/color]
page[color=blue][color=green][color=darkred]
>> >> using my same vb6 custom printing dll. Where[/color]
>> Display.aspx[color=darkred]
>> >> has and IMG tag with src="Image.aspx". Now, in the
>> >> Image.aspx.vb code, I make the necessary calls to my[/color][/color][/color]
dll[color=blue][color=green][color=darkred]
>> >> to preload some data, then I call the PrintImage[/color]
>> routine.[color=darkred]
>> >> What I get back is a black box. Since it's an asp.net[/color]
>> page[color=darkred]
>> >> I don't have a picturebox to draw to (even if I did,[/color][/color][/color]
I'm[color=blue][color=green][color=darkred]
>> >> not sure the picturebox's Handle would be the same as
>> >> vb6's hdc). So I'm trying to create a bitmap in .net[/color]
>> where[color=darkred]
>> >> i can eventually get an hdc that I can send to my[/color]
>> printing[color=darkred]
>> >> routine in the vb6 dll. Below is the code I use to do[/color]
>> this:[color=darkred]
>> >>
>> >> Dim bm As Bitmap = New Bitmap(728, 312)
>> >> Dim gfx As Graphics = Graphics.FromImage(bm)
>> >> gfx.Clear(Color.White)
>> >> Dim hDC As IntPtr = gfx.GetHdc()
>> >> prt.hdc = hDC.ToInt32 'prt.hdc is the property in my[/color][/color][/color]
vb6[color=blue][color=green][color=darkred]
>> >> dll that receives the hdc to print to
>> >>
>> >> The code runs without error, I save the bitmap to a[/color]
>> file,[color=darkred]
>> >> read it into a bytearray, and do a
>> >> Response.Binarywrite...I get a black box (well, now I[/color]
>> get[color=darkred]
>> >> a white box since I added the gfx.Clear line above).
>> >>
>> >> Why can't my vb6 printing dll draw to a .net hdc?
>> >>
>> >> PS. I eventually don't want to have to save the[/color][/color][/color]
bitmap[color=blue][color=green]
>> to[color=darkred]
>> >> a file. If I can get the correct drawing on a device
>> >> context, I'd like to be able to stream that directly[/color][/color][/color]
to[color=blue][color=green]
>> a[color=darkred]
>> >> byte array and do a Response.Binarywrite.
>> >>
>> >> If an expert can help with my main issue and my PS. I
>> >> would greatly appreciate it.
>> >
>> >.
>> >[/color][/color]
>
>.
>[/color]
Dmitriy Lapshin [C# / .NET MVP]
Guest
 
Posts: n/a
#6: Nov 20 '05

re: Drawing on a .Net device context from a vb6 dll


> I understand that Object.GetHdc is a pointer, but is[color=blue]
> Object.GetHdc.ToInt32 the same as a gdi32 device context
> or vb6 picturebox.hdc?[/color]

Yes, they SHOULD be the same according to MSDN. But:
[color=blue]
> ...to the top and in a button_click adding this:
>
> TextOut(Me.Handle, 100, 100, "TESTING", 7)[/color]

What is Me.Handle here? I suppose it is actually HWND and not HDC?
Does your static Main function is marked as [STAThread] by the way?

--
Dmitriy Lapshin [C# / .NET MVP]
X-Unity Test Studio
http://x-unity.miik.com.ua/teststudio.aspx
Bring the power of unit testing to VS .NET IDE

"Metallicraft" <anonymous@discussions.microsoft.com> wrote in message
news:0f8501c3a3bd$44102100$a501280a@phx.gbl...[color=blue]
> Well, I've tried a couple different things.
>
> I created a vb6 dll with the following code:
>
> Option Explicit
>
> Private Declare Function TextOut Lib "gdi32"
> Alias "TextOutA" (ByVal hdc As Long, ByVal X As Long,
> ByVal Y As Long, ByVal lpString As String, ByVal nCount As
> Long) As Long
>
> Public Sub DrawText(ByRef hdc As Long)
> Dim dl As Long
> dl = TextOut(hdc, 0, 0, "TEST", Len("TEST"))
> End Sub
>
> ...and I compiled it.
>
> I then created a vb application (referencing that dll)
> with the following code:
>
> Option Explicit
>
> Private Sub Form_Load()
> Picture1.AutoRedraw = True
>
> Dim dt As DrawText.clsDrawText
> Set dt = New DrawText.clsDrawText
> dt.DrawText (Picture1.hDC)
>
> Picture1.Refresh
> End Sub
>
> ...the form contains one picture box.
>
> When I run the app, I get the word "TEST" in the picture
> box as I would expect.
>
> Next, I created a vb.net Windows app, with only one form,
> one button, and a picture box. I referenced my simple dll
> above and the only code exists in the button_click:
>
> Dim dt As New DrawText.clsDrawTextClass
> dt.DrawText(PictureBox1.Handle.ToInt32)
> dt = Nothing
>
> PictureBox1.Refresh()
>
> ...I run the app, press the button, and get no text. I've
> tried this with and without the Refresh and with and
> without the PictureBox (using the form's handle instead)
> with the same results.
>
> I have also tried, in a vb.net app, adding this:
>
> <System.Runtime.InteropServices.DllImportAttribu te
> ("gdi32.dll")> _
> Private Shared Function TextOut(ByVal hdc As IntPtr,
> ByVal X As Integer, ByVal Y As Integer, ByVal lpString As
> String, ByVal nCount As Integer) As Integer
> End Function
>
> ...to the top and in a button_click adding this:
>
> TextOut(Me.Handle, 100, 100, "TESTING", 7)
>
> ...running it, pressing button, and getting no text.
>
> So, even taking my dll and the graphics object out of the
> equation, I can't get a gdi32 function, like TextOut, to
> write on a .Net device context.
>
> I understand that Object.GetHdc is a pointer, but is
> Object.GetHdc.ToInt32 the same as a gdi32 device context
> or vb6 picturebox.hdc?
>[color=green]
> >-----Original Message-----
> >You can try calling a raw GDI function through P/Invoke[/color]
> on the HDC obtained[color=green]
> >and see whether it works that way. If yes, you at least[/color]
> know the HDC being[color=green]
> >passed is valid.
> >
> >There also could be problems with VB6 COM DLL running on[/color]
> a separate thread[color=green]
> >(as it runs in the Single-Threaded Apartment and ASP .NET[/color]
> is[color=green]
> >multi-threaded), and I am not sure HDCs can be passed "as[/color]
> is" between[color=green]
> >threads.
> >
> >--
> >Dmitriy Lapshin [C# / .NET MVP]
> >X-Unity Test Studio
> >http://x-unity.miik.com.ua/teststudio.aspx
> >Bring the power of unit testing to VS .NET IDE
> >
> >"Metallicraft" <anonymous@discussions.microsoft.com>[/color]
> wrote in message[color=green]
> >news:083501c3a3af$6ff09d30$a001280a@phx.gbl...[color=darkred]
> >> Thanks for responding.
> >>
> >> I dispose of my bitmap and release the dc after I write
> >> the bitmap to a file further down in the code. I know[/color][/color]
> the[color=green][color=darkred]
> >> vb6 dll works in vb6. The vb6 dll is production[/color][/color]
> software[color=green][color=darkred]
> >> already working in the hands of hundreds of clients.
> >>
> >> I can do a:
> >>
> >> gfx.DrawString("test", New Font("Arial", 24.0F),
> >> Brushes.Black, 0, 0)
> >> gfx.DrawRectangle(New Pen(Color.Black), New
> >> Rectangle(2, 1, 725, 309))
> >>
> >> ...inside vb.net and get a bitmap with text and a
> >> rectangle, but when passing the graphic's hdc
> >> (Graphic.GetHdc.ToInt32) I get no drawing whatsoever[/color][/color]
> from[color=green][color=darkred]
> >> the vb6 dll.
> >>
> >> >-----Original Message-----
> >> >Hi,
> >> >
> >> >You can try calling ReleaseDC after the VB6 dll has
> >> finished drawing. The
> >> >rest of .NET code looks correct. You might also want to
> >> debug your VB6 dll
> >> >to see where it possibly fails.
> >> >
> >> >--
> >> >Dmitriy Lapshin [C# / .NET MVP]
> >> >X-Unity Test Studio
> >> >http://x-unity.miik.com.ua/teststudio.aspx
> >> >Bring the power of unit testing to VS .NET IDE
> >> >
> >> >"Metallicraft" <anonymous@discussions.microsoft.com>
> >> wrote in message
> >> >news:066e01c3a3a4$58879370$a001280a@phx.gbl...
> >> >> I have a vb6 application. On the main form is a[/color][/color]
> picture[color=green][color=darkred]
> >> >> box with one or two images and several pieces of text
> >> >> displayed in it. These are created on the fly using
> >> gdi32
> >> >> routines that are all in a referenced, custom dll. I
> >> call
> >> >> a PrintImage routine in the dll and pass it only the[/color][/color]
> the[color=green][color=darkred]
> >> >> Picturebox.hdc from the main form. The dll's print
> >> routine
> >> >> draws to the hdc and it shows up in the picturebox
> >> >> perfectly.
> >> >>
> >> >> I would like to do a similar thing with an asp.net[/color][/color]
> page[color=green][color=darkred]
> >> >> using my same vb6 custom printing dll. Where
> >> Display.aspx
> >> >> has and IMG tag with src="Image.aspx". Now, in the
> >> >> Image.aspx.vb code, I make the necessary calls to my[/color][/color]
> dll[color=green][color=darkred]
> >> >> to preload some data, then I call the PrintImage
> >> routine.
> >> >> What I get back is a black box. Since it's an asp.net
> >> page
> >> >> I don't have a picturebox to draw to (even if I did,[/color][/color]
> I'm[color=green][color=darkred]
> >> >> not sure the picturebox's Handle would be the same as
> >> >> vb6's hdc). So I'm trying to create a bitmap in .net
> >> where
> >> >> i can eventually get an hdc that I can send to my
> >> printing
> >> >> routine in the vb6 dll. Below is the code I use to do
> >> this:
> >> >>
> >> >> Dim bm As Bitmap = New Bitmap(728, 312)
> >> >> Dim gfx As Graphics = Graphics.FromImage(bm)
> >> >> gfx.Clear(Color.White)
> >> >> Dim hDC As IntPtr = gfx.GetHdc()
> >> >> prt.hdc = hDC.ToInt32 'prt.hdc is the property in my[/color][/color]
> vb6[color=green][color=darkred]
> >> >> dll that receives the hdc to print to
> >> >>
> >> >> The code runs without error, I save the bitmap to a
> >> file,
> >> >> read it into a bytearray, and do a
> >> >> Response.Binarywrite...I get a black box (well, now I
> >> get
> >> >> a white box since I added the gfx.Clear line above).
> >> >>
> >> >> Why can't my vb6 printing dll draw to a .net hdc?
> >> >>
> >> >> PS. I eventually don't want to have to save the[/color][/color]
> bitmap[color=green][color=darkred]
> >> to
> >> >> a file. If I can get the correct drawing on a device
> >> >> context, I'd like to be able to stream that directly[/color][/color]
> to[color=green][color=darkred]
> >> a
> >> >> byte array and do a Response.Binarywrite.
> >> >>
> >> >> If an expert can help with my main issue and my PS. I
> >> >> would greatly appreciate it.
> >> >
> >> >.
> >> >[/color]
> >
> >.
> >[/color][/color]

Metallicraft
Guest
 
Posts: n/a
#7: Nov 20 '05

re: Drawing on a .Net device context from a vb6 dll


Me.Handle refers to the form's handle when I tried to just
TextOut to the form instead of a PictureBox. I do believe
it's an hWnd. You'll note in the declaration:

<System.Runtime.InteropServices.DllImportAttribu te
("gdi32.dll")> _
Private Shared Function TextOut(ByVal hdc As IntPtr,
ByVal X As Integer, ByVal Y As Integer, ByVal lpString
As String, ByVal nCount As Integer) As Integer
End Function

....hdc is defined as an "IntPtr". I've seen this done in
many examples with APIs that require an hDc that's
normally a Long type, though I don't understand how people
can just change the API declaration like that and have it
still work (I always thought API declarations were very
strict). Nevertheless, I've tried it both ways:

hDc As IntPtr and TextOut(Me.Handle, etc....

-AND-

hDc As Integer and TextOut(Me.Handle.ToInt32, etc...

Neither work.

I'm afraid I don't understand your last question
about "[STAThread]".
[color=blue]
>-----Original Message-----[color=green]
>> I understand that Object.GetHdc is a pointer, but is
>> Object.GetHdc.ToInt32 the same as a gdi32 device context
>> or vb6 picturebox.hdc?[/color]
>
>Yes, they SHOULD be the same according to MSDN. But:
>[color=green]
>> ...to the top and in a button_click adding this:
>>
>> TextOut(Me.Handle, 100, 100, "TESTING", 7)[/color]
>
>What is Me.Handle here? I suppose it is actually HWND and[/color]
not HDC?[color=blue]
>Does your static Main function is marked as [STAThread][/color]
by the way?[color=blue]
>
>--
>Dmitriy Lapshin [C# / .NET MVP]
>X-Unity Test Studio
>http://x-unity.miik.com.ua/teststudio.aspx
>Bring the power of unit testing to VS .NET IDE
>
>"Metallicraft" <anonymous@discussions.microsoft.com>[/color]
wrote in message[color=blue]
>news:0f8501c3a3bd$44102100$a501280a@phx.gbl...[color=green]
>> Well, I've tried a couple different things.
>>
>> I created a vb6 dll with the following code:
>>
>> Option Explicit
>>
>> Private Declare Function TextOut Lib "gdi32"
>> Alias "TextOutA" (ByVal hdc As Long, ByVal X As Long,
>> ByVal Y As Long, ByVal lpString As String, ByVal nCount[/color][/color]
As[color=blue][color=green]
>> Long) As Long
>>
>> Public Sub DrawText(ByRef hdc As Long)
>> Dim dl As Long
>> dl = TextOut(hdc, 0, 0, "TEST", Len("TEST"))
>> End Sub
>>
>> ...and I compiled it.
>>
>> I then created a vb application (referencing that dll)
>> with the following code:
>>
>> Option Explicit
>>
>> Private Sub Form_Load()
>> Picture1.AutoRedraw = True
>>
>> Dim dt As DrawText.clsDrawText
>> Set dt = New DrawText.clsDrawText
>> dt.DrawText (Picture1.hDC)
>>
>> Picture1.Refresh
>> End Sub
>>
>> ...the form contains one picture box.
>>
>> When I run the app, I get the word "TEST" in the picture
>> box as I would expect.
>>
>> Next, I created a vb.net Windows app, with only one[/color][/color]
form,[color=blue][color=green]
>> one button, and a picture box. I referenced my simple[/color][/color]
dll[color=blue][color=green]
>> above and the only code exists in the button_click:
>>
>> Dim dt As New DrawText.clsDrawTextClass
>> dt.DrawText(PictureBox1.Handle.ToInt32)
>> dt = Nothing
>>
>> PictureBox1.Refresh()
>>
>> ...I run the app, press the button, and get no text.[/color][/color]
I've[color=blue][color=green]
>> tried this with and without the Refresh and with and
>> without the PictureBox (using the form's handle instead)
>> with the same results.
>>
>> I have also tried, in a vb.net app, adding this:
>>
>> <System.Runtime.InteropServices.DllImportAttribu te
>> ("gdi32.dll")> _
>> Private Shared Function TextOut(ByVal hdc As IntPtr,
>> ByVal X As Integer, ByVal Y As Integer, ByVal lpString[/color][/color]
As[color=blue][color=green]
>> String, ByVal nCount As Integer) As Integer
>> End Function
>>
>> ...to the top and in a button_click adding this:
>>
>> TextOut(Me.Handle, 100, 100, "TESTING", 7)
>>
>> ...running it, pressing button, and getting no text.
>>
>> So, even taking my dll and the graphics object out of[/color][/color]
the[color=blue][color=green]
>> equation, I can't get a gdi32 function, like TextOut, to
>> write on a .Net device context.
>>
>> I understand that Object.GetHdc is a pointer, but is
>> Object.GetHdc.ToInt32 the same as a gdi32 device context
>> or vb6 picturebox.hdc?
>>[color=darkred]
>> >-----Original Message-----
>> >You can try calling a raw GDI function through P/Invoke[/color]
>> on the HDC obtained[color=darkred]
>> >and see whether it works that way. If yes, you at least[/color]
>> know the HDC being[color=darkred]
>> >passed is valid.
>> >
>> >There also could be problems with VB6 COM DLL running[/color][/color][/color]
on[color=blue][color=green]
>> a separate thread[color=darkred]
>> >(as it runs in the Single-Threaded Apartment and[/color][/color][/color]
ASP .NET[color=blue][color=green]
>> is[color=darkred]
>> >multi-threaded), and I am not sure HDCs can be[/color][/color][/color]
passed "as[color=blue][color=green]
>> is" between[color=darkred]
>> >threads.
>> >
>> >--
>> >Dmitriy Lapshin [C# / .NET MVP]
>> >X-Unity Test Studio
>> >http://x-unity.miik.com.ua/teststudio.aspx
>> >Bring the power of unit testing to VS .NET IDE
>> >
>> >"Metallicraft" <anonymous@discussions.microsoft.com>[/color]
>> wrote in message[color=darkred]
>> >news:083501c3a3af$6ff09d30$a001280a@phx.gbl...
>> >> Thanks for responding.
>> >>
>> >> I dispose of my bitmap and release the dc after I[/color][/color][/color]
write[color=blue][color=green][color=darkred]
>> >> the bitmap to a file further down in the code. I[/color][/color][/color]
know[color=blue][color=green]
>> the[color=darkred]
>> >> vb6 dll works in vb6. The vb6 dll is production[/color]
>> software[color=darkred]
>> >> already working in the hands of hundreds of clients.
>> >>
>> >> I can do a:
>> >>
>> >> gfx.DrawString("test", New Font("Arial",[/color][/color][/color]
24.0F),[color=blue][color=green][color=darkred]
>> >> Brushes.Black, 0, 0)
>> >> gfx.DrawRectangle(New Pen(Color.Black), New
>> >> Rectangle(2, 1, 725, 309))
>> >>
>> >> ...inside vb.net and get a bitmap with text and a
>> >> rectangle, but when passing the graphic's hdc
>> >> (Graphic.GetHdc.ToInt32) I get no drawing whatsoever[/color]
>> from[color=darkred]
>> >> the vb6 dll.
>> >>
>> >> >-----Original Message-----
>> >> >Hi,
>> >> >
>> >> >You can try calling ReleaseDC after the VB6 dll has
>> >> finished drawing. The
>> >> >rest of .NET code looks correct. You might also[/color][/color][/color]
want to[color=blue][color=green][color=darkred]
>> >> debug your VB6 dll
>> >> >to see where it possibly fails.
>> >> >
>> >> >--
>> >> >Dmitriy Lapshin [C# / .NET MVP]
>> >> >X-Unity Test Studio
>> >> >http://x-unity.miik.com.ua/teststudio.aspx
>> >> >Bring the power of unit testing to VS .NET IDE
>> >> >
>> >> >"Metallicraft" <anonymous@discussions.microsoft.com>
>> >> wrote in message
>> >> >news:066e01c3a3a4$58879370$a001280a@phx.gbl...
>> >> >> I have a vb6 application. On the main form is a[/color]
>> picture[color=darkred]
>> >> >> box with one or two images and several pieces of[/color][/color][/color]
text[color=blue][color=green][color=darkred]
>> >> >> displayed in it. These are created on the fly[/color][/color][/color]
using[color=blue][color=green][color=darkred]
>> >> gdi32
>> >> >> routines that are all in a referenced, custom[/color][/color][/color]
dll. I[color=blue][color=green][color=darkred]
>> >> call
>> >> >> a PrintImage routine in the dll and pass it only[/color][/color][/color]
the[color=blue][color=green]
>> the[color=darkred]
>> >> >> Picturebox.hdc from the main form. The dll's print
>> >> routine
>> >> >> draws to the hdc and it shows up in the picturebox
>> >> >> perfectly.
>> >> >>
>> >> >> I would like to do a similar thing with an asp.net[/color]
>> page[color=darkred]
>> >> >> using my same vb6 custom printing dll. Where
>> >> Display.aspx
>> >> >> has and IMG tag with src="Image.aspx". Now, in the
>> >> >> Image.aspx.vb code, I make the necessary calls to[/color][/color][/color]
my[color=blue][color=green]
>> dll[color=darkred]
>> >> >> to preload some data, then I call the PrintImage
>> >> routine.
>> >> >> What I get back is a black box. Since it's an[/color][/color][/color]
asp.net[color=blue][color=green][color=darkred]
>> >> page
>> >> >> I don't have a picturebox to draw to (even if I[/color][/color][/color]
did,[color=blue][color=green]
>> I'm[color=darkred]
>> >> >> not sure the picturebox's Handle would be the[/color][/color][/color]
same as[color=blue][color=green][color=darkred]
>> >> >> vb6's hdc). So I'm trying to create a bitmap[/color][/color][/color]
in .net[color=blue][color=green][color=darkred]
>> >> where
>> >> >> i can eventually get an hdc that I can send to my
>> >> printing
>> >> >> routine in the vb6 dll. Below is the code I use[/color][/color][/color]
to do[color=blue][color=green][color=darkred]
>> >> this:
>> >> >>
>> >> >> Dim bm As Bitmap = New Bitmap(728, 312)
>> >> >> Dim gfx As Graphics = Graphics.FromImage(bm)
>> >> >> gfx.Clear(Color.White)
>> >> >> Dim hDC As IntPtr = gfx.GetHdc()
>> >> >> prt.hdc = hDC.ToInt32 'prt.hdc is the property in[/color][/color][/color]
my[color=blue][color=green]
>> vb6[color=darkred]
>> >> >> dll that receives the hdc to print to
>> >> >>
>> >> >> The code runs without error, I save the bitmap to[/color][/color][/color]
a[color=blue][color=green][color=darkred]
>> >> file,
>> >> >> read it into a bytearray, and do a
>> >> >> Response.Binarywrite...I get a black box (well,[/color][/color][/color]
now I[color=blue][color=green][color=darkred]
>> >> get
>> >> >> a white box since I added the gfx.Clear line[/color][/color][/color]
above).[color=blue][color=green][color=darkred]
>> >> >>
>> >> >> Why can't my vb6 printing dll draw to a .net hdc?
>> >> >>
>> >> >> PS. I eventually don't want to have to save the[/color]
>> bitmap[color=darkred]
>> >> to
>> >> >> a file. If I can get the correct drawing on a[/color][/color][/color]
device[color=blue][color=green][color=darkred]
>> >> >> context, I'd like to be able to stream that[/color][/color][/color]
directly[color=blue][color=green]
>> to[color=darkred]
>> >> a
>> >> >> byte array and do a Response.Binarywrite.
>> >> >>
>> >> >> If an expert can help with my main issue and my[/color][/color][/color]
PS. I[color=blue][color=green][color=darkred]
>> >> >> would greatly appreciate it.
>> >> >
>> >> >.
>> >> >
>> >
>> >.
>> >[/color][/color]
>
>.
>[/color]
Dmitriy Lapshin [C# / .NET MVP]
Guest
 
Posts: n/a
#8: Nov 20 '05

re: Drawing on a .Net device context from a vb6 dll


Just to be safe: HDC and HWND are NOT the same and are NOT interchangeable.
And therefore neither of the below will work as it seems you are passing
HWND
where HDC is expected.
[color=blue]
> hDc As IntPtr and TextOut(Me.Handle, etc....
>
> -AND-
>
> hDc As Integer and TextOut(Me.Handle.ToInt32, etc...[/color]

From my experience there's no big difference whether you declare an API
function parameter as Int32 or IntPtr (the latter is preferred as you'll
avoid explicit type casts in your code) - both ways work.
[color=blue]
> I'm afraid I don't understand your last question
> about "[STAThread]".[/color]

Oops, it's C# syntax. In VB .NET it should look like <STAThread()> or
something like that. It's an attribute that indicated the application is
single-thread and no call to a COM object will be originated by a thread
other that the main one. This is important to the COM subsystem to ensure
instantiated COM objects (and your VB6 DLL is an ActiveX DLL, isn't it?) run
in the expected apartment. This is STA in case of VB6 ActiveX DLLs.

--
Dmitriy Lapshin [C# / .NET MVP]
X-Unity Test Studio
http://x-unity.miik.com.ua/teststudio.aspx
Bring the power of unit testing to VS .NET IDE

"Metallicraft" <anonymous@discussions.microsoft.com> wrote in message
news:0a9201c3a470$087fc6f0$a601280a@phx.gbl...[color=blue]
> Me.Handle refers to the form's handle when I tried to just
> TextOut to the form instead of a PictureBox. I do believe
> it's an hWnd. You'll note in the declaration:
>
> <System.Runtime.InteropServices.DllImportAttribu te
> ("gdi32.dll")> _
> Private Shared Function TextOut(ByVal hdc As IntPtr,
> ByVal X As Integer, ByVal Y As Integer, ByVal lpString
> As String, ByVal nCount As Integer) As Integer
> End Function
>
> ...hdc is defined as an "IntPtr". I've seen this done in
> many examples with APIs that require an hDc that's
> normally a Long type, though I don't understand how people
> can just change the API declaration like that and have it
> still work (I always thought API declarations were very
> strict). Nevertheless, I've tried it both ways:
>
> hDc As IntPtr and TextOut(Me.Handle, etc....
>
> -AND-
>
> hDc As Integer and TextOut(Me.Handle.ToInt32, etc...
>
> Neither work.
>
> I'm afraid I don't understand your last question
> about "[STAThread]".
>[color=green]
> >-----Original Message-----[color=darkred]
> >> I understand that Object.GetHdc is a pointer, but is
> >> Object.GetHdc.ToInt32 the same as a gdi32 device context
> >> or vb6 picturebox.hdc?[/color]
> >
> >Yes, they SHOULD be the same according to MSDN. But:
> >[color=darkred]
> >> ...to the top and in a button_click adding this:
> >>
> >> TextOut(Me.Handle, 100, 100, "TESTING", 7)[/color]
> >
> >What is Me.Handle here? I suppose it is actually HWND and[/color]
> not HDC?[color=green]
> >Does your static Main function is marked as [STAThread][/color]
> by the way?[color=green]
> >
> >--
> >Dmitriy Lapshin [C# / .NET MVP]
> >X-Unity Test Studio
> >http://x-unity.miik.com.ua/teststudio.aspx
> >Bring the power of unit testing to VS .NET IDE
> >
> >"Metallicraft" <anonymous@discussions.microsoft.com>[/color]
> wrote in message[color=green]
> >news:0f8501c3a3bd$44102100$a501280a@phx.gbl...[color=darkred]
> >> Well, I've tried a couple different things.
> >>
> >> I created a vb6 dll with the following code:
> >>
> >> Option Explicit
> >>
> >> Private Declare Function TextOut Lib "gdi32"
> >> Alias "TextOutA" (ByVal hdc As Long, ByVal X As Long,
> >> ByVal Y As Long, ByVal lpString As String, ByVal nCount[/color][/color]
> As[color=green][color=darkred]
> >> Long) As Long
> >>
> >> Public Sub DrawText(ByRef hdc As Long)
> >> Dim dl As Long
> >> dl = TextOut(hdc, 0, 0, "TEST", Len("TEST"))
> >> End Sub
> >>
> >> ...and I compiled it.
> >>
> >> I then created a vb application (referencing that dll)
> >> with the following code:
> >>
> >> Option Explicit
> >>
> >> Private Sub Form_Load()
> >> Picture1.AutoRedraw = True
> >>
> >> Dim dt As DrawText.clsDrawText
> >> Set dt = New DrawText.clsDrawText
> >> dt.DrawText (Picture1.hDC)
> >>
> >> Picture1.Refresh
> >> End Sub
> >>
> >> ...the form contains one picture box.
> >>
> >> When I run the app, I get the word "TEST" in the picture
> >> box as I would expect.
> >>
> >> Next, I created a vb.net Windows app, with only one[/color][/color]
> form,[color=green][color=darkred]
> >> one button, and a picture box. I referenced my simple[/color][/color]
> dll[color=green][color=darkred]
> >> above and the only code exists in the button_click:
> >>
> >> Dim dt As New DrawText.clsDrawTextClass
> >> dt.DrawText(PictureBox1.Handle.ToInt32)
> >> dt = Nothing
> >>
> >> PictureBox1.Refresh()
> >>
> >> ...I run the app, press the button, and get no text.[/color][/color]
> I've[color=green][color=darkred]
> >> tried this with and without the Refresh and with and
> >> without the PictureBox (using the form's handle instead)
> >> with the same results.
> >>
> >> I have also tried, in a vb.net app, adding this:
> >>
> >> <System.Runtime.InteropServices.DllImportAttribu te
> >> ("gdi32.dll")> _
> >> Private Shared Function TextOut(ByVal hdc As IntPtr,
> >> ByVal X As Integer, ByVal Y As Integer, ByVal lpString[/color][/color]
> As[color=green][color=darkred]
> >> String, ByVal nCount As Integer) As Integer
> >> End Function
> >>
> >> ...to the top and in a button_click adding this:
> >>
> >> TextOut(Me.Handle, 100, 100, "TESTING", 7)
> >>
> >> ...running it, pressing button, and getting no text.
> >>
> >> So, even taking my dll and the graphics object out of[/color][/color]
> the[color=green][color=darkred]
> >> equation, I can't get a gdi32 function, like TextOut, to
> >> write on a .Net device context.
> >>
> >> I understand that Object.GetHdc is a pointer, but is
> >> Object.GetHdc.ToInt32 the same as a gdi32 device context
> >> or vb6 picturebox.hdc?
> >>
> >> >-----Original Message-----
> >> >You can try calling a raw GDI function through P/Invoke
> >> on the HDC obtained
> >> >and see whether it works that way. If yes, you at least
> >> know the HDC being
> >> >passed is valid.
> >> >
> >> >There also could be problems with VB6 COM DLL running[/color][/color]
> on[color=green][color=darkred]
> >> a separate thread
> >> >(as it runs in the Single-Threaded Apartment and[/color][/color]
> ASP .NET[color=green][color=darkred]
> >> is
> >> >multi-threaded), and I am not sure HDCs can be[/color][/color]
> passed "as[color=green][color=darkred]
> >> is" between
> >> >threads.
> >> >
> >> >--
> >> >Dmitriy Lapshin [C# / .NET MVP]
> >> >X-Unity Test Studio
> >> >http://x-unity.miik.com.ua/teststudio.aspx
> >> >Bring the power of unit testing to VS .NET IDE
> >> >
> >> >"Metallicraft" <anonymous@discussions.microsoft.com>
> >> wrote in message
> >> >news:083501c3a3af$6ff09d30$a001280a@phx.gbl...
> >> >> Thanks for responding.
> >> >>
> >> >> I dispose of my bitmap and release the dc after I[/color][/color]
> write[color=green][color=darkred]
> >> >> the bitmap to a file further down in the code. I[/color][/color]
> know[color=green][color=darkred]
> >> the
> >> >> vb6 dll works in vb6. The vb6 dll is production
> >> software
> >> >> already working in the hands of hundreds of clients.
> >> >>
> >> >> I can do a:
> >> >>
> >> >> gfx.DrawString("test", New Font("Arial",[/color][/color]
> 24.0F),[color=green][color=darkred]
> >> >> Brushes.Black, 0, 0)
> >> >> gfx.DrawRectangle(New Pen(Color.Black), New
> >> >> Rectangle(2, 1, 725, 309))
> >> >>
> >> >> ...inside vb.net and get a bitmap with text and a
> >> >> rectangle, but when passing the graphic's hdc
> >> >> (Graphic.GetHdc.ToInt32) I get no drawing whatsoever
> >> from
> >> >> the vb6 dll.
> >> >>
> >> >> >-----Original Message-----
> >> >> >Hi,
> >> >> >
> >> >> >You can try calling ReleaseDC after the VB6 dll has
> >> >> finished drawing. The
> >> >> >rest of .NET code looks correct. You might also[/color][/color]
> want to[color=green][color=darkred]
> >> >> debug your VB6 dll
> >> >> >to see where it possibly fails.
> >> >> >
> >> >> >--
> >> >> >Dmitriy Lapshin [C# / .NET MVP]
> >> >> >X-Unity Test Studio
> >> >> >http://x-unity.miik.com.ua/teststudio.aspx
> >> >> >Bring the power of unit testing to VS .NET IDE
> >> >> >
> >> >> >"Metallicraft" <anonymous@discussions.microsoft.com>
> >> >> wrote in message
> >> >> >news:066e01c3a3a4$58879370$a001280a@phx.gbl...
> >> >> >> I have a vb6 application. On the main form is a
> >> picture
> >> >> >> box with one or two images and several pieces of[/color][/color]
> text[color=green][color=darkred]
> >> >> >> displayed in it. These are created on the fly[/color][/color]
> using[color=green][color=darkred]
> >> >> gdi32
> >> >> >> routines that are all in a referenced, custom[/color][/color]
> dll. I[color=green][color=darkred]
> >> >> call
> >> >> >> a PrintImage routine in the dll and pass it only[/color][/color]
> the[color=green][color=darkred]
> >> the
> >> >> >> Picturebox.hdc from the main form. The dll's print
> >> >> routine
> >> >> >> draws to the hdc and it shows up in the picturebox
> >> >> >> perfectly.
> >> >> >>
> >> >> >> I would like to do a similar thing with an asp.net
> >> page
> >> >> >> using my same vb6 custom printing dll. Where
> >> >> Display.aspx
> >> >> >> has and IMG tag with src="Image.aspx". Now, in the
> >> >> >> Image.aspx.vb code, I make the necessary calls to[/color][/color]
> my[color=green][color=darkred]
> >> dll
> >> >> >> to preload some data, then I call the PrintImage
> >> >> routine.
> >> >> >> What I get back is a black box. Since it's an[/color][/color]
> asp.net[color=green][color=darkred]
> >> >> page
> >> >> >> I don't have a picturebox to draw to (even if I[/color][/color]
> did,[color=green][color=darkred]
> >> I'm
> >> >> >> not sure the picturebox's Handle would be the[/color][/color]
> same as[color=green][color=darkred]
> >> >> >> vb6's hdc). So I'm trying to create a bitmap[/color][/color]
> in .net[color=green][color=darkred]
> >> >> where
> >> >> >> i can eventually get an hdc that I can send to my
> >> >> printing
> >> >> >> routine in the vb6 dll. Below is the code I use[/color][/color]
> to do[color=green][color=darkred]
> >> >> this:
> >> >> >>
> >> >> >> Dim bm As Bitmap = New Bitmap(728, 312)
> >> >> >> Dim gfx As Graphics = Graphics.FromImage(bm)
> >> >> >> gfx.Clear(Color.White)
> >> >> >> Dim hDC As IntPtr = gfx.GetHdc()
> >> >> >> prt.hdc = hDC.ToInt32 'prt.hdc is the property in[/color][/color]
> my[color=green][color=darkred]
> >> vb6
> >> >> >> dll that receives the hdc to print to
> >> >> >>
> >> >> >> The code runs without error, I save the bitmap to[/color][/color]
> a[color=green][color=darkred]
> >> >> file,
> >> >> >> read it into a bytearray, and do a
> >> >> >> Response.Binarywrite...I get a black box (well,[/color][/color]
> now I[color=green][color=darkred]
> >> >> get
> >> >> >> a white box since I added the gfx.Clear line[/color][/color]
> above).[color=green][color=darkred]
> >> >> >>
> >> >> >> Why can't my vb6 printing dll draw to a .net hdc?
> >> >> >>
> >> >> >> PS. I eventually don't want to have to save the
> >> bitmap
> >> >> to
> >> >> >> a file. If I can get the correct drawing on a[/color][/color]
> device[color=green][color=darkred]
> >> >> >> context, I'd like to be able to stream that[/color][/color]
> directly[color=green][color=darkred]
> >> to
> >> >> a
> >> >> >> byte array and do a Response.Binarywrite.
> >> >> >>
> >> >> >> If an expert can help with my main issue and my[/color][/color]
> PS. I[color=green][color=darkred]
> >> >> >> would greatly appreciate it.
> >> >> >
> >> >> >.
> >> >> >
> >> >
> >> >.
> >> >[/color]
> >
> >.
> >[/color][/color]

Metallicraft
Guest
 
Posts: n/a
#9: Nov 20 '05

re: Drawing on a .Net device context from a vb6 dll


I understand what you're saying about the HDC and HWND,
but I thought Handle.ToInt32 was the same as Integer...
where Handle.ToInt32 is the integer representation of the
handle...which is the object's hDc, is this not true?

When I'd pass a Handle to the TextOut API, I have the hDc
in the TextOut declaration defined as an IntPtr. Are
Handle and IntPtr different?

If not, how would one declare the TextOut, for example,
and what would be passed to the hDc parameter?

Maybe that's not important because the REAL dll I'm trying
to get to work cannot be changed. So I need to know if I
can pass a .Net-something into a VB6 Long variable and
have them both be refering to the same hDc.

I understand what you mean about the single-threading, but
I'm still not sure where the "<STAThread()>" would go or
how it's used. I have very little experience dealing with
threads.
[color=blue]
>-----Original Message-----
>Just to be safe: HDC and HWND are NOT the same and are[/color]
NOT interchangeable.[color=blue]
>And therefore neither of the below will work as it seems[/color]
you are passing[color=blue]
>HWND
>where HDC is expected.
>[color=green]
>> hDc As IntPtr and TextOut(Me.Handle, etc....
>>
>> -AND-
>>
>> hDc As Integer and TextOut(Me.Handle.ToInt32, etc...[/color]
>
>From my experience there's no big difference whether you[/color]
declare an API[color=blue]
>function parameter as Int32 or IntPtr (the latter is[/color]
preferred as you'll[color=blue]
>avoid explicit type casts in your code) - both ways work.
>[color=green]
>> I'm afraid I don't understand your last question
>> about "[STAThread]".[/color]
>
>Oops, it's C# syntax. In VB .NET it should look like[/color]
<STAThread()> or[color=blue]
>something like that. It's an attribute that indicated the[/color]
application is[color=blue]
>single-thread and no call to a COM object will be[/color]
originated by a thread[color=blue]
>other that the main one. This is important to the COM[/color]
subsystem to ensure[color=blue]
>instantiated COM objects (and your VB6 DLL is an ActiveX[/color]
DLL, isn't it?) run[color=blue]
>in the expected apartment. This is STA in case of VB6[/color]
ActiveX DLLs.[color=blue]
>
>--
>Dmitriy Lapshin [C# / .NET MVP]
>X-Unity Test Studio
>http://x-unity.miik.com.ua/teststudio.aspx
>Bring the power of unit testing to VS .NET IDE
>
>"Metallicraft" <anonymous@discussions.microsoft.com>[/color]
wrote in message[color=blue]
>news:0a9201c3a470$087fc6f0$a601280a@phx.gbl...[color=green]
>> Me.Handle refers to the form's handle when I tried to[/color][/color]
just[color=blue][color=green]
>> TextOut to the form instead of a PictureBox. I do[/color][/color]
believe[color=blue][color=green]
>> it's an hWnd. You'll note in the declaration:
>>
>> <System.Runtime.InteropServices.DllImportAttribu te
>> ("gdi32.dll")> _
>> Private Shared Function TextOut(ByVal hdc As IntPtr,
>> ByVal X As Integer, ByVal Y As Integer, ByVal[/color][/color]
lpString[color=blue][color=green]
>> As String, ByVal nCount As Integer) As Integer
>> End Function
>>
>> ...hdc is defined as an "IntPtr". I've seen this done[/color][/color]
in[color=blue][color=green]
>> many examples with APIs that require an hDc that's
>> normally a Long type, though I don't understand how[/color][/color]
people[color=blue][color=green]
>> can just change the API declaration like that and have[/color][/color]
it[color=blue][color=green]
>> still work (I always thought API declarations were very
>> strict). Nevertheless, I've tried it both ways:
>>
>> hDc As IntPtr and TextOut(Me.Handle, etc....
>>
>> -AND-
>>
>> hDc As Integer and TextOut(Me.Handle.ToInt32, etc...
>>
>> Neither work.
>>
>> I'm afraid I don't understand your last question
>> about "[STAThread]".
>>[color=darkred]
>> >-----Original Message-----
>> >> I understand that Object.GetHdc is a pointer, but is
>> >> Object.GetHdc.ToInt32 the same as a gdi32 device[/color][/color][/color]
context[color=blue][color=green][color=darkred]
>> >> or vb6 picturebox.hdc?
>> >
>> >Yes, they SHOULD be the same according to MSDN. But:
>> >
>> >> ...to the top and in a button_click adding this:
>> >>
>> >> TextOut(Me.Handle, 100, 100, "TESTING", 7)
>> >
>> >What is Me.Handle here? I suppose it is actually HWND[/color][/color][/color]
and[color=blue][color=green]
>> not HDC?[color=darkred]
>> >Does your static Main function is marked as [STAThread][/color]
>> by the way?[color=darkred]
>> >
>> >--
>> >Dmitriy Lapshin [C# / .NET MVP]
>> >X-Unity Test Studio
>> >http://x-unity.miik.com.ua/teststudio.aspx
>> >Bring the power of unit testing to VS .NET IDE
>> >
>> >"Metallicraft" <anonymous@discussions.microsoft.com>[/color]
>> wrote in message[color=darkred]
>> >news:0f8501c3a3bd$44102100$a501280a@phx.gbl...
>> >> Well, I've tried a couple different things.
>> >>
>> >> I created a vb6 dll with the following code:
>> >>
>> >> Option Explicit
>> >>
>> >> Private Declare Function TextOut Lib "gdi32"
>> >> Alias "TextOutA" (ByVal hdc As Long, ByVal X As Long,
>> >> ByVal Y As Long, ByVal lpString As String, ByVal[/color][/color][/color]
nCount[color=blue][color=green]
>> As[color=darkred]
>> >> Long) As Long
>> >>
>> >> Public Sub DrawText(ByRef hdc As Long)
>> >> Dim dl As Long
>> >> dl = TextOut(hdc, 0, 0, "TEST", Len("TEST"))
>> >> End Sub
>> >>
>> >> ...and I compiled it.
>> >>
>> >> I then created a vb application (referencing that[/color][/color][/color]
dll)[color=blue][color=green][color=darkred]
>> >> with the following code:
>> >>
>> >> Option Explicit
>> >>
>> >> Private Sub Form_Load()
>> >> Picture1.AutoRedraw = True
>> >>
>> >> Dim dt As DrawText.clsDrawText
>> >> Set dt = New DrawText.clsDrawText
>> >> dt.DrawText (Picture1.hDC)
>> >>
>> >> Picture1.Refresh
>> >> End Sub
>> >>
>> >> ...the form contains one picture box.
>> >>
>> >> When I run the app, I get the word "TEST" in the[/color][/color][/color]
picture[color=blue][color=green][color=darkred]
>> >> box as I would expect.
>> >>
>> >> Next, I created a vb.net Windows app, with only one[/color]
>> form,[color=darkred]
>> >> one button, and a picture box. I referenced my[/color][/color][/color]
simple[color=blue][color=green]
>> dll[color=darkred]
>> >> above and the only code exists in the button_click:
>> >>
>> >> Dim dt As New DrawText.clsDrawTextClass
>> >> dt.DrawText(PictureBox1.Handle.ToInt32)
>> >> dt = Nothing
>> >>
>> >> PictureBox1.Refresh()
>> >>
>> >> ...I run the app, press the button, and get no text.[/color]
>> I've[color=darkred]
>> >> tried this with and without the Refresh and with and
>> >> without the PictureBox (using the form's handle[/color][/color][/color]
instead)[color=blue][color=green][color=darkred]
>> >> with the same results.
>> >>
>> >> I have also tried, in a vb.net app, adding this:
>> >>
>> >>[/color][/color][/color]
<System.Runtime.InteropServices.DllImportAttribu te[color=blue][color=green][color=darkred]
>> >> ("gdi32.dll")> _
>> >> Private Shared Function TextOut(ByVal hdc As[/color][/color][/color]
IntPtr,[color=blue][color=green][color=darkred]
>> >> ByVal X As Integer, ByVal Y As Integer, ByVal[/color][/color][/color]
lpString[color=blue][color=green]
>> As[color=darkred]
>> >> String, ByVal nCount As Integer) As Integer
>> >> End Function
>> >>
>> >> ...to the top and in a button_click adding this:
>> >>
>> >> TextOut(Me.Handle, 100, 100, "TESTING", 7)
>> >>
>> >> ...running it, pressing button, and getting no text.
>> >>
>> >> So, even taking my dll and the graphics object out of[/color]
>> the[color=darkred]
>> >> equation, I can't get a gdi32 function, like[/color][/color][/color]
TextOut, to[color=blue][color=green][color=darkred]
>> >> write on a .Net device context.
>> >>
>> >> I understand that Object.GetHdc is a pointer, but is
>> >> Object.GetHdc.ToInt32 the same as a gdi32 device[/color][/color][/color]
context[color=blue][color=green][color=darkred]
>> >> or vb6 picturebox.hdc?
>> >>
>> >> >-----Original Message-----
>> >> >You can try calling a raw GDI function through[/color][/color][/color]
P/Invoke[color=blue][color=green][color=darkred]
>> >> on the HDC obtained
>> >> >and see whether it works that way. If yes, you at[/color][/color][/color]
least[color=blue][color=green][color=darkred]
>> >> know the HDC being
>> >> >passed is valid.
>> >> >
>> >> >There also could be problems with VB6 COM DLL[/color][/color][/color]
running[color=blue][color=green]
>> on[color=darkred]
>> >> a separate thread
>> >> >(as it runs in the Single-Threaded Apartment and[/color]
>> ASP .NET[color=darkred]
>> >> is
>> >> >multi-threaded), and I am not sure HDCs can be[/color]
>> passed "as[color=darkred]
>> >> is" between
>> >> >threads.
>> >> >
>> >> >--
>> >> >Dmitriy Lapshin [C# / .NET MVP]
>> >> >X-Unity Test Studio
>> >> >http://x-unity.miik.com.ua/teststudio.aspx
>> >> >Bring the power of unit testing to VS .NET IDE
>> >> >
>> >> >"Metallicraft" <anonymous@discussions.microsoft.com>
>> >> wrote in message
>> >> >news:083501c3a3af$6ff09d30$a001280a@phx.gbl...
>> >> >> Thanks for responding.
>> >> >>
>> >> >> I dispose of my bitmap and release the dc after I[/color]
>> write[color=darkred]
>> >> >> the bitmap to a file further down in the code. I[/color]
>> know[color=darkred]
>> >> the
>> >> >> vb6 dll works in vb6. The vb6 dll is production
>> >> software
>> >> >> already working in the hands of hundreds of[/color][/color][/color]
clients.[color=blue][color=green][color=darkred]
>> >> >>
>> >> >> I can do a:
>> >> >>
>> >> >> gfx.DrawString("test", New Font("Arial",[/color]
>> 24.0F),[color=darkred]
>> >> >> Brushes.Black, 0, 0)
>> >> >> gfx.DrawRectangle(New Pen(Color.Black),[/color][/color][/color]
New[color=blue][color=green][color=darkred]
>> >> >> Rectangle(2, 1, 725, 309))
>> >> >>
>> >> >> ...inside vb.net and get a bitmap with text and a
>> >> >> rectangle, but when passing the graphic's hdc
>> >> >> (Graphic.GetHdc.ToInt32) I get no drawing[/color][/color][/color]
whatsoever[color=blue][color=green][color=darkred]
>> >> from
>> >> >> the vb6 dll.
>> >> >>
>> >> >> >-----Original Message-----
>> >> >> >Hi,
>> >> >> >
>> >> >> >You can try calling ReleaseDC after the VB6 dll[/color][/color][/color]
has[color=blue][color=green][color=darkred]
>> >> >> finished drawing. The
>> >> >> >rest of .NET code looks correct. You might also[/color]
>> want to[color=darkred]
>> >> >> debug your VB6 dll
>> >> >> >to see where it possibly fails.
>> >> >> >
>> >> >> >--
>> >> >> >Dmitriy Lapshin [C# / .NET MVP]
>> >> >> >X-Unity Test Studio
>> >> >> >http://x-unity.miik.com.ua/teststudio.aspx
>> >> >> >Bring the power of unit testing to VS .NET IDE
>> >> >> >
>> >> >> >"Metallicraft"[/color][/color][/color]
<anonymous@discussions.microsoft.com>[color=blue][color=green][color=darkred]
>> >> >> wrote in message
>> >> >> >news:066e01c3a3a4$58879370$a001280a@phx.gbl...
>> >> >> >> I have a vb6 application. On the main form is a
>> >> picture
>> >> >> >> box with one or two images and several pieces[/color][/color][/color]
of[color=blue][color=green]
>> text[color=darkred]
>> >> >> >> displayed in it. These are created on the fly[/color]
>> using[color=darkred]
>> >> >> gdi32
>> >> >> >> routines that are all in a referenced, custom[/color]
>> dll. I[color=darkred]
>> >> >> call
>> >> >> >> a PrintImage routine in the dll and pass it[/color][/color][/color]
only[color=blue][color=green]
>> the[color=darkred]
>> >> the
>> >> >> >> Picturebox.hdc from the main form. The dll's[/color][/color][/color]
print[color=blue][color=green][color=darkred]
>> >> >> routine
>> >> >> >> draws to the hdc and it shows up in the[/color][/color][/color]
picturebox[color=blue][color=green][color=darkred]
>> >> >> >> perfectly.
>> >> >> >>
>> >> >> >> I would like to do a similar thing with an[/color][/color][/color]
asp.net[color=blue][color=green][color=darkred]
>> >> page
>> >> >> >> using my same vb6 custom printing dll. Where
>> >> >> Display.aspx
>> >> >> >> has and IMG tag with src="Image.aspx". Now, in[/color][/color][/color]
the[color=blue][color=green][color=darkred]
>> >> >> >> Image.aspx.vb code, I make the necessary calls[/color][/color][/color]
to[color=blue][color=green]
>> my[color=darkred]
>> >> dll
>> >> >> >> to preload some data, then I call the[/color][/color][/color]
PrintImage[color=blue][color=green][color=darkred]
>> >> >> routine.
>> >> >> >> What I get back is a black box. Since it's an[/color]
>> asp.net[color=darkred]
>> >> >> page
>> >> >> >> I don't have a picturebox to draw to (even if I[/color]
>> did,[color=darkred]
>> >> I'm
>> >> >> >> not sure the picturebox's Handle would be the[/color]
>> same as[color=darkred]
>> >> >> >> vb6's hdc). So I'm trying to create a bitmap[/color]
>> in .net[color=darkred]
>> >> >> where
>> >> >> >> i can eventually get an hdc that I can send to[/color][/color][/color]
my[color=blue][color=green][color=darkred]
>> >> >> printing
>> >> >> >> routine in the vb6 dll. Below is the code I use[/color]
>> to do[color=darkred]
>> >> >> this:
>> >> >> >>
>> >> >> >> Dim bm As Bitmap = New Bitmap(728, 312)
>> >> >> >> Dim gfx As Graphics = Graphics.FromImage(bm)
>> >> >> >> gfx.Clear(Color.White)
>> >> >> >> Dim hDC As IntPtr = gfx.GetHdc()
>> >> >> >> prt.hdc = hDC.ToInt32 'prt.hdc is the property[/color][/color][/color]
in[color=blue][color=green]
>> my[color=darkred]
>> >> vb6
>> >> >> >> dll that receives the hdc to print to
>> >> >> >>
>> >> >> >> The code runs without error, I save the bitmap[/color][/color][/color]
to[color=blue][color=green]
>> a[color=darkred]
>> >> >> file,
>> >> >> >> read it into a bytearray, and do a
>> >> >> >> Response.Binarywrite...I get a black box (well,[/color]
>> now I[color=darkred]
>> >> >> get
>> >> >> >> a white box since I added the gfx.Clear line[/color]
>> above).[color=darkred]
>> >> >> >>
>> >> >> >> Why can't my vb6 printing dll draw to a .net[/color][/color][/color]
hdc?[color=blue][color=green][color=darkred]
>> >> >> >>
>> >> >> >> PS. I eventually don't want to have to save the
>> >> bitmap
>> >> >> to
>> >> >> >> a file. If I can get the correct drawing on a[/color]
>> device[color=darkred]
>> >> >> >> context, I'd like to be able to stream that[/color]
>> directly[color=darkred]
>> >> to
>> >> >> a
>> >> >> >> byte array and do a Response.Binarywrite.
>> >> >> >>
>> >> >> >> If an expert can help with my main issue and my[/color]
>> PS. I[color=darkred]
>> >> >> >> would greatly appreciate it.
>> >> >> >
>> >> >> >.
>> >> >> >
>> >> >
>> >> >.
>> >> >
>> >
>> >.
>> >[/color][/color]
>
>.
>[/color]
Dmitriy Lapshin [C# / .NET MVP]
Guest
 
Posts: n/a
#10: Nov 20 '05

re: Drawing on a .Net device context from a vb6 dll


> where Handle.ToInt32 is the integer representation of the[color=blue]
> handle...which is the object's hDc, is this not true?[/color]

Handle.ToInt32 _IS_ the integer representation of a handle, but Form.Handle
is a window handle (HWND),
not a GDI device context handle (HDC). To obtain an HDC for a form or a
control, you should employ
the Graphics class and contruct it by using the static FromHwnd method:

Dim g AsGraphics = Graphics.FromHwnd(Me.Handle)

Dim hdc As IntPtr = g.GetHdc()
TextOut(hdc, 100, 100, "TESTING", 7)
g.ReleaseHdc(hdc)

--
Dmitriy Lapshin [C# / .NET MVP]
X-Unity Test Studio
http://x-unity.miik.com.ua/teststudio.aspx
Bring the power of unit testing to VS .NET IDE

"Metallicraft" <anonymous@discussions.microsoft.com> wrote in message
news:0c4d01c3a47a$26d38e70$a501280a@phx.gbl...[color=blue]
> I understand what you're saying about the HDC and HWND,
> but I thought Handle.ToInt32 was the same as Integer...
> where Handle.ToInt32 is the integer representation of the
> handle...which is the object's hDc, is this not true?
>
> When I'd pass a Handle to the TextOut API, I have the hDc
> in the TextOut declaration defined as an IntPtr. Are
> Handle and IntPtr different?
>
> If not, how would one declare the TextOut, for example,
> and what would be passed to the hDc parameter?
>
> Maybe that's not important because the REAL dll I'm trying
> to get to work cannot be changed. So I need to know if I
> can pass a .Net-something into a VB6 Long variable and
> have them both be refering to the same hDc.
>
> I understand what you mean about the single-threading, but
> I'm still not sure where the "<STAThread()>" would go or
> how it's used. I have very little experience dealing with
> threads.
>[color=green]
> >-----Original Message-----
> >Just to be safe: HDC and HWND are NOT the same and are[/color]
> NOT interchangeable.[color=green]
> >And therefore neither of the below will work as it seems[/color]
> you are passing[color=green]
> >HWND
> >where HDC is expected.
> >[color=darkred]
> >> hDc As IntPtr and TextOut(Me.Handle, etc....
> >>
> >> -AND-
> >>
> >> hDc As Integer and TextOut(Me.Handle.ToInt32, etc...[/color]
> >
> >From my experience there's no big difference whether you[/color]
> declare an API[color=green]
> >function parameter as Int32 or IntPtr (the latter is[/color]
> preferred as you'll[color=green]
> >avoid explicit type casts in your code) - both ways work.
> >[color=darkred]
> >> I'm afraid I don't understand your last question
> >> about "[STAThread]".[/color]
> >
> >Oops, it's C# syntax. In VB .NET it should look like[/color]
> <STAThread()> or[color=green]
> >something like that. It's an attribute that indicated the[/color]
> application is[color=green]
> >single-thread and no call to a COM object will be[/color]
> originated by a thread[color=green]
> >other that the main one. This is important to the COM[/color]
> subsystem to ensure[color=green]
> >instantiated COM objects (and your VB6 DLL is an ActiveX[/color]
> DLL, isn't it?) run[color=green]
> >in the expected apartment. This is STA in case of VB6[/color]
> ActiveX DLLs.[color=green]
> >
> >--
> >Dmitriy Lapshin [C# / .NET MVP]
> >X-Unity Test Studio
> >http://x-unity.miik.com.ua/teststudio.aspx
> >Bring the power of unit testing to VS .NET IDE
> >
> >"Metallicraft" <anonymous@discussions.microsoft.com>[/color]
> wrote in message[color=green]
> >news:0a9201c3a470$087fc6f0$a601280a@phx.gbl...[color=darkred]
> >> Me.Handle refers to the form's handle when I tried to[/color][/color]
> just[color=green][color=darkred]
> >> TextOut to the form instead of a PictureBox. I do[/color][/color]
> believe[color=green][color=darkred]
> >> it's an hWnd. You'll note in the declaration:
> >>
> >> <System.Runtime.InteropServices.DllImportAttribu te
> >> ("gdi32.dll")> _
> >> Private Shared Function TextOut(ByVal hdc As IntPtr,
> >> ByVal X As Integer, ByVal Y As Integer, ByVal[/color][/color]
> lpString[color=green][color=darkred]
> >> As String, ByVal nCount As Integer) As Integer
> >> End Function
> >>
> >> ...hdc is defined as an "IntPtr". I've seen this done[/color][/color]
> in[color=green][color=darkred]
> >> many examples with APIs that require an hDc that's
> >> normally a Long type, though I don't understand how[/color][/color]
> people[color=green][color=darkred]
> >> can just change the API declaration like that and have[/color][/color]
> it[color=green][color=darkred]
> >> still work (I always thought API declarations were very
> >> strict). Nevertheless, I've tried it both ways:
> >>
> >> hDc As IntPtr and TextOut(Me.Handle, etc....
> >>
> >> -AND-
> >>
> >> hDc As Integer and TextOut(Me.Handle.ToInt32, etc...
> >>
> >> Neither work.
> >>
> >> I'm afraid I don't understand your last question
> >> about "[STAThread]".
> >>
> >> >-----Original Message-----
> >> >> I understand that Object.GetHdc is a pointer, but is
> >> >> Object.GetHdc.ToInt32 the same as a gdi32 device[/color][/color]
> context[color=green][color=darkred]
> >> >> or vb6 picturebox.hdc?
> >> >
> >> >Yes, they SHOULD be the same according to MSDN. But:
> >> >
> >> >> ...to the top and in a button_click adding this:
> >> >>
> >> >> TextOut(Me.Handle, 100, 100, "TESTING", 7)
> >> >
> >> >What is Me.Handle here? I suppose it is actually HWND[/color][/color]
> and[color=green][color=darkred]
> >> not HDC?
> >> >Does your static Main function is marked as [STAThread]
> >> by the way?
> >> >
> >> >--
> >> >Dmitriy Lapshin [C# / .NET MVP]
> >> >X-Unity Test Studio
> >> >http://x-unity.miik.com.ua/teststudio.aspx
> >> >Bring the power of unit testing to VS .NET IDE
> >> >
> >> >"Metallicraft" <anonymous@discussions.microsoft.com>
> >> wrote in message
> >> >news:0f8501c3a3bd$44102100$a501280a@phx.gbl...
> >> >> Well, I've tried a couple different things.
> >> >>
> >> >> I created a vb6 dll with the following code:
> >> >>
> >> >> Option Explicit
> >> >>
> >> >> Private Declare Function TextOut Lib "gdi32"
> >> >> Alias "TextOutA" (ByVal hdc As Long, ByVal X As Long,
> >> >> ByVal Y As Long, ByVal lpString As String, ByVal[/color][/color]
> nCount[color=green][color=darkred]
> >> As
> >> >> Long) As Long
> >> >>
> >> >> Public Sub DrawText(ByRef hdc As Long)
> >> >> Dim dl As Long
> >> >> dl = TextOut(hdc, 0, 0, "TEST", Len("TEST"))
> >> >> End Sub
> >> >>
> >> >> ...and I compiled it.
> >> >>
> >> >> I then created a vb application (referencing that[/color][/color]
> dll)[color=green][color=darkred]
> >> >> with the following code:
> >> >>
> >> >> Option Explicit
> >> >>
> >> >> Private Sub Form_Load()
> >> >> Picture1.AutoRedraw = True
> >> >>
> >> >> Dim dt As DrawText.clsDrawText
> >> >> Set dt = New DrawText.clsDrawText
> >> >> dt.DrawText (Picture1.hDC)
> >> >>
> >> >> Picture1.Refresh
> >> >> End Sub
> >> >>
> >> >> ...the form contains one picture box.
> >> >>
> >> >> When I run the app, I get the word "TEST" in the[/color][/color]
> picture[color=green][color=darkred]
> >> >> box as I would expect.
> >> >>
> >> >> Next, I created a vb.net Windows app, with only one
> >> form,
> >> >> one button, and a picture box. I referenced my[/color][/color]
> simple[color=green][color=darkred]
> >> dll
> >> >> above and the only code exists in the button_click:
> >> >>
> >> >> Dim dt As New DrawText.clsDrawTextClass
> >> >> dt.DrawText(PictureBox1.Handle.ToInt32)
> >> >> dt = Nothing
> >> >>
> >> >> PictureBox1.Refresh()
> >> >>
> >> >> ...I run the app, press the button, and get no text.
> >> I've
> >> >> tried this with and without the Refresh and with and
> >> >> without the PictureBox (using the form's handle[/color][/color]
> instead)[color=green][color=darkred]
> >> >> with the same results.
> >> >>
> >> >> I have also tried, in a vb.net app, adding this:
> >> >>
> >> >>[/color][/color]
> <System.Runtime.InteropServices.DllImportAttribu te[color=green][color=darkred]
> >> >> ("gdi32.dll")> _
> >> >> Private Shared Function TextOut(ByVal hdc As[/color][/color]
> IntPtr,[color=green][color=darkred]
> >> >> ByVal X As Integer, ByVal Y As Integer, ByVal[/color][/color]
> lpString[color=green][color=darkred]
> >> As
> >> >> String, ByVal nCount As Integer) As Integer
> >> >> End Function
> >> >>
> >> >> ...to the top and in a button_click adding this:
> >> >>
> >> >> TextOut(Me.Handle, 100, 100, "TESTING", 7)
> >> >>
> >> >> ...running it, pressing button, and getting no text.
> >> >>
> >> >> So, even taking my dll and the graphics object out of
> >> the
> >> >> equation, I can't get a gdi32 function, like[/color][/color]
> TextOut, to[color=green][color=darkred]
> >> >> write on a .Net device context.
> >> >>
> >> >> I understand that Object.GetHdc is a pointer, but is
> >> >> Object.GetHdc.ToInt32 the same as a gdi32 device[/color][/color]
> context[color=green][color=darkred]
> >> >> or vb6 picturebox.hdc?
> >> >>
> >> >> >-----Original Message-----
> >> >> >You can try calling a raw GDI function through[/color][/color]
> P/Invoke[color=green][color=darkred]
> >> >> on the HDC obtained
> >> >> >and see whether it works that way. If yes, you at[/color][/color]
> least[color=green][color=darkred]
> >> >> know the HDC being
> >> >> >passed is valid.
> >> >> >
> >> >> >There also could be problems with VB6 COM DLL[/color][/color]
> running[color=green][color=darkred]
> >> on
> >> >> a separate thread
> >> >> >(as it runs in the Single-Threaded Apartment and
> >> ASP .NET
> >> >> is
> >> >> >multi-threaded), and I am not sure HDCs can be
> >> passed "as
> >> >> is" between
> >> >> >threads.
> >> >> >
> >> >> >--
> >> >> >Dmitriy Lapshin [C# / .NET MVP]
> >> >> >X-Unity Test Studio
> >> >> >http://x-unity.miik.com.ua/teststudio.aspx
> >> >> >Bring the power of unit testing to VS .NET IDE
> >> >> >
> >> >> >"Metallicraft" <anonymous@discussions.microsoft.com>
> >> >> wrote in message
> >> >> >news:083501c3a3af$6ff09d30$a001280a@phx.gbl...
> >> >> >> Thanks for responding.
> >> >> >>
> >> >> >> I dispose of my bitmap and release the dc after I
> >> write
> >> >> >> the bitmap to a file further down in the code. I
> >> know
> >> >> the
> >> >> >> vb6 dll works in vb6. The vb6 dll is production
> >> >> software
> >> >> >> already working in the hands of hundreds of[/color][/color]
> clients.[color=green][color=darkred]
> >> >> >>
> >> >> >> I can do a:
> >> >> >>
> >> >> >> gfx.DrawString("test", New Font("Arial",
> >> 24.0F),
> >> >> >> Brushes.Black, 0, 0)
> >> >> >> gfx.DrawRectangle(New Pen(Color.Black),[/color][/color]
> New[color=green][color=darkred]
> >> >> >> Rectangle(2, 1, 725, 309))
> >> >> >>
> >> >> >> ...inside vb.net and get a bitmap with text and a
> >> >> >> rectangle, but when passing the graphic's hdc
> >> >> >> (Graphic.GetHdc.ToInt32) I get no drawing[/color][/color]
> whatsoever[color=green][color=darkred]
> >> >> from
> >> >> >> the vb6 dll.
> >> >> >>
> >> >> >> >-----Original Message-----
> >> >> >> >Hi,
> >> >> >> >
> >> >> >> >You can try calling ReleaseDC after the VB6 dll[/color][/color]
> has[color=green][color=darkred]
> >> >> >> finished drawing. The
> >> >> >> >rest of .NET code looks correct. You might also
> >> want to
> >> >> >> debug your VB6 dll
> >> >> >> >to see where it possibly fails.
> >> >> >> >
> >> >> >> >--
> >> >> >> >Dmitriy Lapshin [C# / .NET MVP]
> >> >> >> >X-Unity Test Studio
> >> >> >> >http://x-unity.miik.com.ua/teststudio.aspx
> >> >> >> >Bring the power of unit testing to VS .NET IDE
> >> >> >> >
> >> >> >> >"Metallicraft"[/color][/color]
> <anonymous@discussions.microsoft.com>[color=green][color=darkred]
> >> >> >> wrote in message
> >> >> >> >news:066e01c3a3a4$58879370$a001280a@phx.gbl...
> >> >> >> >> I have a vb6 application. On the main form is a
> >> >> picture
> >> >> >> >> box with one or two images and several pieces[/color][/color]
> of[color=green][color=darkred]
> >> text
> >> >> >> >> displayed in it. These are created on the fly
> >> using
> >> >> >> gdi32
> >> >> >> >> routines that are all in a referenced, custom
> >> dll. I
> >> >> >> call
> >> >> >> >> a PrintImage routine in the dll and pass it[/color][/color]
> only[color=green][color=darkred]
> >> the
> >> >> the
> >> >> >> >> Picturebox.hdc from the main form. The dll's[/color][/color]
> print[color=green][color=darkred]
> >> >> >> routine
> >> >> >> >> draws to the hdc and it shows up in the[/color][/color]
> picturebox[color=green][color=darkred]
> >> >> >> >> perfectly.
> >> >> >> >>
> >> >> >> >> I would like to do a similar thing with an[/color][/color]
> asp.net[color=green][color=darkred]
> >> >> page
> >> >> >> >> using my same vb6 custom printing dll. Where
> >> >> >> Display.aspx
> >> >> >> >> has and IMG tag with src="Image.aspx". Now, in[/color][/color]
> the[color=green][color=darkred]
> >> >> >> >> Image.aspx.vb code, I make the necessary calls[/color][/color]
> to[color=green][color=darkred]
> >> my
> >> >> dll
> >> >> >> >> to preload some data, then I call the[/color][/color]
> PrintImage[color=green][color=darkred]
> >> >> >> routine.
> >> >> >> >> What I get back is a black box. Since it's an
> >> asp.net
> >> >> >> page
> >> >> >> >> I don't have a picturebox to draw to (even if I
> >> did,
> >> >> I'm
> >> >> >> >> not sure the picturebox's Handle would be the
> >> same as
> >> >> >> >> vb6's hdc). So I'm trying to create a bitmap
> >> in .net
> >> >> >> where
> >> >> >> >> i can eventually get an hdc that I can send to[/color][/color]
> my[color=green][color=darkred]
> >> >> >> printing
> >> >> >> >> routine in the vb6 dll. Below is the code I use
> >> to do
> >> >> >> this:
> >> >> >> >>
> >> >> >> >> Dim bm As Bitmap = New Bitmap(728, 312)
> >> >> >> >> Dim gfx As Graphics = Graphics.FromImage(bm)
> >> >> >> >> gfx.Clear(Color.White)
> >> >> >> >> Dim hDC As IntPtr = gfx.GetHdc()
> >> >> >> >> prt.hdc = hDC.ToInt32 'prt.hdc is the property[/color][/color]
> in[color=green][color=darkred]
> >> my
> >> >> vb6
> >> >> >> >> dll that receives the hdc to print to
> >> >> >> >>
> >> >> >> >> The code runs without error, I save the bitmap[/color][/color]
> to[color=green][color=darkred]
> >> a
> >> >> >> file,
> >> >> >> >> read it into a bytearray, and do a
> >> >> >> >> Response.Binarywrite...I get a black box (well,
> >> now I
> >> >> >> get
> >> >> >> >> a white box since I added the gfx.Clear line
> >> above).
> >> >> >> >>
> >> >> >> >> Why can't my vb6 printing dll draw to a .net[/color][/color]
> hdc?[color=green][color=darkred]
> >> >> >> >>
> >> >> >> >> PS. I eventually don't want to have to save the
> >> >> bitmap
> >> >> >> to
> >> >> >> >> a file. If I can get the correct drawing on a
> >> device
> >> >> >> >> context, I'd like to be able to stream that
> >> directly
> >> >> to
> >> >> >> a
> >> >> >> >> byte array and do a Response.Binarywrite.
> >> >> >> >>
> >> >> >> >> If an expert can help with my main issue and my
> >> PS. I
> >> >> >> >> would greatly appreciate it.
> >> >> >> >
> >> >> >> >.
> >> >> >> >
> >> >> >
> >> >> >.
> >> >> >
> >> >
> >> >.
> >> >[/color]
> >
> >.
> >[/color][/color]

Metallicraft
Guest
 
Posts: n/a
#11: Nov 20 '05

re: Drawing on a .Net device context from a vb6 dll


Let me start off by saying thank you for sticking with me
for the last few days, I really appreciate your time.

On to your last post....that's great. Now I know how to
draw to form and control objects in .net using a gdi32 api.

However, I tried tweaking what you sent to get a usable
hdc from a bitmap and I couldn't.

Based on my previous question (and the first thing you
responded to in your last post)... Is a
GRAPHICS.getHdc.ToInt32 an integer representation of a
bitmap's hdc? One that VB6 can use... Remember my
original problem:

Dim bm As Bitmap = New Bitmap(728, 312)
Dim gfx As Graphics = Graphics.FromImage(bm)
gfx.Clear(Color.White)
Dim gfxhDC As IntPtr = gfx.GetHdc()
prt.hdc = gfxhDC.ToInt32
prt.Draw
bm.Save(sTempFile,
System.Drawing.Imaging.ImageFormat.Bmp)
bm.Dispose()
gfx.ReleaseHdc(gfxhDC)

Where prt.hdc is the property in my vb6 dll that holds the
device context to draw to and prt.Draw tells the vb6 dll
to go ahead and draw its data to the given hdc.
[color=blue]
>-----Original Message-----[color=green]
>> where Handle.ToInt32 is the integer representation of[/color][/color]
the[color=blue][color=green]
>> handle...which is the object's hDc, is this not true?[/color]
>
>Handle.ToInt32 _IS_ the integer representation of a[/color]
handle, but Form.Handle[color=blue]
>is a window handle (HWND),
>not a GDI device context handle (HDC). To obtain an HDC[/color]
for a form or a[color=blue]
>control, you should employ
>the Graphics class and contruct it by using the static[/color]
FromHwnd method:[color=blue]
>
>Dim g AsGraphics = Graphics.FromHwnd(Me.Handle)
>
>Dim hdc As IntPtr = g.GetHdc()
>TextOut(hdc, 100, 100, "TESTING", 7)
>g.ReleaseHdc(hdc)
>
>--
>Dmitriy Lapshin [C# / .NET MVP]
>X-Unity Test Studio
>http://x-unity.miik.com.ua/teststudio.aspx
>Bring the power of unit testing to VS .NET IDE
>
>"Metallicraft" <anonymous@discussions.microsoft.com>[/color]
wrote in message[color=blue]
>news:0c4d01c3a47a$26d38e70$a501280a@phx.gbl...[color=green]
>> I understand what you're saying about the HDC and HWND,
>> but I thought Handle.ToInt32 was the same as Integer...
>> where Handle.ToInt32 is the integer representation of[/color][/color]
the[color=blue][color=green]
>> handle...which is the object's hDc, is this not true?
>>
>> When I'd pass a Handle to the TextOut API, I have the[/color][/color]
hDc[color=blue][color=green]
>> in the TextOut declaration defined as an IntPtr. Are
>> Handle and IntPtr different?
>>
>> If not, how would one declare the TextOut, for example,
>> and what would be passed to the hDc parameter?
>>
>> Maybe that's not important because the REAL dll I'm[/color][/color]
trying[color=blue][color=green]
>> to get to work cannot be changed. So I need to know if[/color][/color]
I[color=blue][color=green]
>> can pass a .Net-something into a VB6 Long variable and
>> have them both be refering to the same hDc.
>>
>> I understand what you mean about the single-threading,[/color][/color]
but[color=blue][color=green]
>> I'm still not sure where the "<STAThread()>" would go or
>> how it's used. I have very little experience dealing[/color][/color]
with[color=blue][color=green]
>> threads.
>>[color=darkred]
>> >-----Original Message-----
>> >Just to be safe: HDC and HWND are NOT the same and are[/color]
>> NOT interchangeable.[color=darkred]
>> >And therefore neither of the below will work as it[/color][/color][/color]
seems[color=blue][color=green]
>> you are passing[color=darkred]
>> >HWND
>> >where HDC is expected.
>> >
>> >> hDc As IntPtr and TextOut(Me.Handle, etc....
>> >>
>> >> -AND-
>> >>
>> >> hDc As Integer and TextOut(Me.Handle.ToInt32, etc...
>> >
>> >From my experience there's no big difference whether[/color][/color][/color]
you[color=blue][color=green]
>> declare an API[color=darkred]
>> >function parameter as Int32 or IntPtr (the latter is[/color]
>> preferred as you'll[color=darkred]
>> >avoid explicit type casts in your code) - both ways[/color][/color][/color]
work.[color=blue][color=green][color=darkred]
>> >
>> >> I'm afraid I don't understand your last question
>> >> about "[STAThread]".
>> >
>> >Oops, it's C# syntax. In VB .NET it should look like[/color]
>> <STAThread()> or[color=darkred]
>> >something like that. It's an attribute that indicated[/color][/color][/color]
the[color=blue][color=green]
>> application is[color=darkred]
>> >single-thread and no call to a COM object will be[/color]
>> originated by a thread[color=darkred]
>> >other that the main one. This is important to the COM[/color]
>> subsystem to ensure[color=darkred]
>> >instantiated COM objects (and your VB6 DLL is an[/color][/color][/color]
ActiveX[color=blue][color=green]
>> DLL, isn't it?) run[color=darkred]
>> >in the expected apartment. This is STA in case of VB6[/color]
>> ActiveX DLLs.[color=darkred]
>> >
>> >--
>> >Dmitriy Lapshin [C# / .NET MVP]
>> >X-Unity Test Studio
>> >http://x-unity.miik.com.ua/teststudio.aspx
>> >Bring the power of unit testing to VS .NET IDE
>> >
>> >"Metallicraft" <anonymous@discussions.microsoft.com>[/color]
>> wrote in message[color=darkred]
>> >news:0a9201c3a470$087fc6f0$a601280a@phx.gbl...
>> >> Me.Handle refers to the form's handle when I tried to[/color]
>> just[color=darkred]
>> >> TextOut to the form instead of a PictureBox. I do[/color]
>> believe[color=darkred]
>> >> it's an hWnd. You'll note in the declaration:
>> >>
>> >> <System.Runtime.InteropServices.DllImportAttribu te
>> >> ("gdi32.dll")> _
>> >> Private Shared Function TextOut(ByVal hdc As IntPtr,
>> >> ByVal X As Integer, ByVal Y As Integer, ByVal[/color]
>> lpString[color=darkred]
>> >> As String, ByVal nCount As Integer) As Integer
>> >> End Function
>> >>
>> >> ...hdc is defined as an "IntPtr". I've seen this[/color][/color][/color]
done[color=blue][color=green]
>> in[color=darkred]
>> >> many examples with APIs that require an hDc that's
>> >> normally a Long type, though I don't understand how[/color]
>> people[color=darkred]
>> >> can just change the API declaration like that and[/color][/color][/color]
have[color=blue][color=green]
>> it[color=darkred]
>> >> still work (I always thought API declarations were[/color][/color][/color]
very[color=blue][color=green][color=darkred]
>> >> strict). Nevertheless, I've tried it both ways:
>> >>
>> >> hDc As IntPtr and TextOut(Me.Handle, etc....
>> >>
>> >> -AND-
>> >>
>> >> hDc As Integer and TextOut(Me.Handle.ToInt32, etc...
>> >>
>> >> Neither work.
>> >>
>> >> I'm afraid I don't understand your last question
>> >> about "[STAThread]".
>> >>
>> >> >-----Original Message-----
>> >> >> I understand that Object.GetHdc is a pointer, but[/color][/color][/color]
is[color=blue][color=green][color=darkred]
>> >> >> Object.GetHdc.ToInt32 the same as a gdi32 device[/color]
>> context[color=darkred]
>> >> >> or vb6 picturebox.hdc?
>> >> >
>> >> >Yes, they SHOULD be the same according to MSDN. But:
>> >> >
>> >> >> ...to the top and in a button_click adding this:
>> >> >>
>> >> >> TextOut(Me.Handle, 100, 100, "TESTING", 7)
>> >> >
>> >> >What is Me.Handle here? I suppose it is actually[/color][/color][/color]
HWND[color=blue][color=green]
>> and[color=darkred]
>> >> not HDC?
>> >> >Does your static Main function is marked as[/color][/color][/color]
[STAThread][color=blue][color=green][color=darkred]
>> >> by the way?
>> >> >
>> >> >--
>> >> >Dmitriy Lapshin [C# / .NET MVP]
>> >> >X-Unity Test Studio
>> >> >http://x-unity.miik.com.ua/teststudio.aspx
>> >> >Bring the power of unit testing to VS .NET IDE
>> >> >
>> >> >"Metallicraft" <anonymous@discussions.microsoft.com>
>> >> wrote in message
>> >> >news:0f8501c3a3bd$44102100$a501280a@phx.gbl...
>> >> >> Well, I've tried a couple different things.
>> >> >>
>> >> >> I created a vb6 dll with the following code:
>> >> >>
>> >> >> Option Explicit
>> >> >>
>> >> >> Private Declare Function TextOut Lib "gdi32"
>> >> >> Alias "TextOutA" (ByVal hdc As Long, ByVal X As[/color][/color][/color]
Long,[color=blue][color=green][color=darkred]
>> >> >> ByVal Y As Long, ByVal lpString As String, ByVal[/color]
>> nCount[color=darkred]
>> >> As
>> >> >> Long) As Long
>> >> >>
>> >> >> Public Sub DrawText(ByRef hdc As Long)
>> >> >> Dim dl As Long
>> >> >> dl = TextOut(hdc, 0, 0, "TEST", Len("TEST"))
>> >> >> End Sub
>> >> >>
>> >> >> ...and I compiled it.
>> >> >>
>> >> >> I then created a vb application (referencing that[/color]
>> dll)[color=darkred]
>> >> >> with the following code:
>> >> >>
>> >> >> Option Explicit
>> >> >>
>> >> >> Private Sub Form_Load()
>> >> >> Picture1.AutoRedraw = True
>> >> >>
>> >> >> Dim dt As DrawText.clsDrawText
>> >> >> Set dt = New DrawText.clsDrawText
>> >> >> dt.DrawText (Picture1.hDC)
>> >> >>
>> >> >> Picture1.Refresh
>> >> >> End Sub
>> >> >>
>> >> >> ...the form contains one picture box.
>> >> >>
>> >> >> When I run the app, I get the word "TEST" in the[/color]
>> picture[color=darkred]
>> >> >> box as I would expect.
>> >> >>
>> >> >> Next, I created a vb.net Windows app, with only[/color][/color][/color]
one[color=blue][color=green][color=darkred]
>> >> form,
>> >> >> one button, and a picture box. I referenced my[/color]
>> simple[color=darkred]
>> >> dll
>> >> >> above and the only code exists in the[/color][/color][/color]
button_click:[color=blue][color=green][color=darkred]
>> >> >>
>> >> >> Dim dt As New DrawText.clsDrawTextClass
>> >> >> dt.DrawText(PictureBox1.Handle.ToInt32)
>> >> >> dt = Nothing
>> >> >>
>> >> >> PictureBox1.Refresh()
>> >> >>
>> >> >> ...I run the app, press the button, and get no[/color][/color][/color]
text.[color=blue][color=green][color=darkred]
>> >> I've
>> >> >> tried this with and without the Refresh and with[/color][/color][/color]
and[color=blue][color=green][color=darkred]
>> >> >> without the PictureBox (using the form's handle[/color]
>> instead)[color=darkred]
>> >> >> with the same results.
>> >> >>
>> >> >> I have also tried, in a vb.net app, adding this:
>> >> >>
>> >> >>[/color]
>> <System.Runtime.InteropServices.DllImportAttribu te[color=darkred]
>> >> >> ("gdi32.dll")> _
>> >> >> Private Shared Function TextOut(ByVal hdc As[/color]
>> IntPtr,[color=darkred]
>> >> >> ByVal X As Integer, ByVal Y As Integer, ByVal[/color]
>> lpString[color=darkred]
>> >> As
>> >> >> String, ByVal nCount As Integer) As Integer
>> >> >> End Function
>> >> >>
>> >> >> ...to the top and in a button_click adding this:
>> >> >>
>> >> >> TextOut(Me.Handle, 100, 100, "TESTING", 7)
>> >> >>
>> >> >> ...running it, pressing button, and getting no[/color][/color][/color]
text.[color=blue][color=green][color=darkred]
>> >> >>
>> >> >> So, even taking my dll and the graphics object[/color][/color][/color]
out of[color=blue][color=green][color=darkred]
>> >> the
>> >> >> equation, I can't get a gdi32 function, like[/color]
>> TextOut, to[color=darkred]
>> >> >> write on a .Net device context.
>> >> >>
>> >> >> I understand that Object.GetHdc is a pointer, but[/color][/color][/color]
is[color=blue][color=green][color=darkred]
>> >> >> Object.GetHdc.ToInt32 the same as a gdi32 device[/color]
>> context[color=darkred]
>> >> >> or vb6 picturebox.hdc?
>> >> >>
>> >> >> >-----Original Message-----
>> >> >> >You can try calling a raw GDI function through[/color]
>> P/Invoke[color=darkred]
>> >> >> on the HDC obtained
>> >> >> >and see whether it works that way. If yes, you at[/color]
>> least[color=darkred]
>> >> >> know the HDC being
>> >> >> >passed is valid.
>> >> >> >
>> >> >> >There also could be problems with VB6 COM DLL[/color]
>> running[color=darkred]
>> >> on
>> >> >> a separate thread
>> >> >> >(as it runs in the Single-Threaded Apartment and
>> >> ASP .NET
>> >> >> is
>> >> >> >multi-threaded), and I am not sure HDCs can be
>> >> passed "as
>> >> >> is" between
>> >> >> >threads.
>> >> >> >
>> >> >> >--
>> >> >> >Dmitriy Lapshin [C# / .NET MVP]
>> >> >> >X-Unity Test Studio
>> >> >> >http://x-unity.miik.com.ua/teststudio.aspx
>> >> >> >Bring the power of unit testing to VS .NET IDE
>> >> >> >
>> >> >> >"Metallicraft"[/color][/color][/color]
<anonymous@discussions.microsoft.com>[color=blue][color=green][color=darkred]
>> >> >> wrote in message
>> >> >> >news:083501c3a3af$6ff09d30$a001280a@phx.gbl...
>> >> >> >> Thanks for responding.
>> >> >> >>
>> >> >> >> I dispose of my bitmap and release the dc[/color][/color][/color]
after I[color=blue][color=green][color=darkred]
>> >> write
>> >> >> >> the bitmap to a file further down in the[/color][/color][/color]
code. I[color=blue][color=green][color=darkred]
>> >> know
>> >> >> the
>> >> >> >> vb6 dll works in vb6. The vb6 dll is[/color][/color][/color]
production[color=blue][color=green][color=darkred]
>> >> >> software
>> >> >> >> already working in the hands of hundreds of[/color]
>> clients.[color=darkred]
>> >> >> >>
>> >> >> >> I can do a:
>> >> >> >>
>> >> >> >> gfx.DrawString("test", New Font[/color][/color][/color]
("Arial",[color=blue][color=green][color=darkred]
>> >> 24.0F),
>> >> >> >> Brushes.Black, 0, 0)
>> >> >> >> gfx.DrawRectangle(New Pen(Color.Black),[/color]
>> New[color=darkred]
>> >> >> >> Rectangle(2, 1, 725, 309))
>> >> >> >>
>> >> >> >> ...inside vb.net and get a bitmap with text[/color][/color][/color]
and a[color=blue][color=green][color=darkred]
>> >> >> >> rectangle, but when passing the graphic's hdc
>> >> >> >> (Graphic.GetHdc.ToInt32) I get no drawing[/color]
>> whatsoever[color=darkred]
>> >> >> from
>> >> >> >> the vb6 dll.
>> >> >> >>
>> >> >> >> >-----Original Message-----
>> >> >> >> >Hi,
>> >> >> >> >
>> >> >> >> >You can try calling ReleaseDC after the VB6[/color][/color][/color]
dll[color=blue][color=green]
>> has[color=darkred]
>> >> >> >> finished drawing. The
>> >> >> >> >rest of .NET code looks correct. You might[/color][/color][/color]
also[color=blue][color=green][color=darkred]
>> >> want to
>> >> >> >> debug your VB6 dll
>> >> >> >> >to see where it possibly fails.
>> >> >> >> >
>> >> >> >> >--
>> >> >> >> >Dmitriy Lapshin [C# / .NET MVP]
>> >> >> >> >X-Unity Test Studio
>> >> >> >> >http://x-unity.miik.com.ua/teststudio.aspx
>> >> >> >> >Bring the power of unit testing to VS .NET IDE
>> >> >> >> >
>> >> >> >> >"Metallicraft"[/color]
>> <anonymous@discussions.microsoft.com>[color=darkred]
>> >> >> >> wrote in message
>> >> >> >> >news:066e01c3a3a4$58879370$a001280a@phx.gbl...
>> >> >> >> >> I have a vb6 application. On the main form[/color][/color][/color]
is a[color=blue][color=green][color=darkred]
>> >> >> picture
>> >> >> >> >> box with one or two images and several[/color][/color][/color]
pieces[color=blue][color=green]
>> of[color=darkred]
>> >> text
>> >> >> >> >> displayed in it. These are created on the[/color][/color][/color]
fly[color=blue][color=green][color=darkred]
>> >> using
>> >> >> >> gdi32
>> >> >> >> >> routines that are all in a referenced,[/color][/color][/color]
custom[color=blue][color=green][color=darkred]
>> >> dll. I
>> >> >> >> call
>> >> >> >> >> a PrintImage routine in the dll and pass it[/color]
>> only[color=darkred]
>> >> the
>> >> >> the
>> >> >> >> >> Picturebox.hdc from the main form. The dll's[/color]
>> print[color=darkred]
>> >> >> >> routine
>> >> >> >> >> draws to the hdc and it shows up in the[/color]
>> picturebox[color=darkred]
>> >> >> >> >> perfectly.
>> >> >> >> >>
>> >> >> >> >> I would like to do a similar thing with an[/color]
>> asp.net[color=darkred]
>> >> >> page
>> >> >> >> >> using my same vb6 custom printing dll. Where
>> >> >> >> Display.aspx
>> >> >> >> >> has and IMG tag with src="Image.aspx". Now,[/color][/color][/color]
in[color=blue][color=green]
>> the[color=darkred]
>> >> >> >> >> Image.aspx.vb code, I make the necessary[/color][/color][/color]
calls[color=blue][color=green]
>> to[color=darkred]
>> >> my
>> >> >> dll
>> >> >> >> >> to preload some data, then I call the[/color]
>> PrintImage[color=darkred]
>> >> >> >> routine.
>> >> >> >> >> What I get back is a black box. Since it's[/color][/color][/color]
an[color=blue][color=green][color=darkred]
>> >> asp.net
>> >> >> >> page
>> >> >> >> >> I don't have a picturebox to draw to (even[/color][/color][/color]
if I[color=blue][color=green][color=darkred]
>> >> did,
>> >> >> I'm
>> >> >> >> >> not sure the picturebox's Handle would be[/color][/color][/color]
the[color=blue][color=green][color=darkred]
>> >> same as
>> >> >> >> >> vb6's hdc). So I'm trying to create a bitmap
>> >> in .net
>> >> >> >> where
>> >> >> >> >> i can eventually get an hdc that I can send[/color][/color][/color]
to[color=blue][color=green]
>> my[color=darkred]
>> >> >> >> printing
>> >> >> >> >> routine in the vb6 dll. Below is the code I[/color][/color][/color]
use[color=blue][color=green][color=darkred]
>> >> to do
>> >> >> >> this:
>> >> >> >> >>
>> >> >> >> >> Dim bm As Bitmap = New Bitmap(728, 312)
>> >> >> >> >> Dim gfx As Graphics = Graphics.FromImage(bm)
>> >> >> >> >> gfx.Clear(Color.White)
>> >> >> >> >> Dim hDC As IntPtr = gfx.GetHdc()
>> >> >> >> >> prt.hdc = hDC.ToInt32 'prt.hdc is the[/color][/color][/color]
property[color=blue][color=green]
>> in[color=darkred]
>> >> my
>> >> >> vb6
>> >> >> >> >> dll that receives the hdc to print to
>> >> >> >> >>
>> >> >> >> >> The code runs without error, I save the[/color][/color][/color]
bitmap[color=blue][color=green]
>> to[color=darkred]
>> >> a
>> >> >> >> file,
>> >> >> >> >> read it into a bytearray, and do a
>> >> >> >> >> Response.Binarywrite...I get a black box[/color][/color][/color]
(well,[color=blue][color=green][color=darkred]
>> >> now I
>> >> >> >> get
>> >> >> >> >> a white box since I added the gfx.Clear line
>> >> above).
>> >> >> >> >>
>> >> >> >> >> Why can't my vb6 printing dll draw to a .net[/color]
>> hdc?[color=darkred]
>> >> >> >> >>
>> >> >> >> >> PS. I eventually don't want to have to save[/color][/color][/color]
the[color=blue][color=green][color=darkred]
>> >> >> bitmap
>> >> >> >> to
>> >> >> >> >> a file. If I can get the correct drawing on[/color][/color][/color]
a[color=blue][color=green][color=darkred]
>> >> device
>> >> >> >> >> context, I'd like to be able to stream that
>> >> directly
>> >> >> to
>> >> >> >> a
>> >> >> >> >> byte array and do a Response.Binarywrite.
>> >> >> >> >>
>> >> >> >> >> If an expert can help with my main issue[/color][/color][/color]
and my[color=blue][color=green][color=darkred]
>> >> PS. I
>> >> >> >> >> would greatly appreciate it.
>> >> >> >> >
>> >> >> >> >.
>> >> >> >> >
>> >> >> >
>> >> >> >.
>> >> >> >
>> >> >
>> >> >.
>> >> >
>> >
>> >.
>> >[/color][/color]
>
>.
>[/color]
Metallicraft
Guest
 
Posts: n/a
#12: Nov 20 '05

re: Drawing on a .Net device context from a vb6 dll


Remember several posts ago I said I created a simple vb6
dll that had one public sub in it with "hdc as long" as
the only parameter? I applied what you mentioned to the
simple .Net windows app that I had (where I referenced the
simple dll) and it worked! I passed the form's hdc to the
vb6 dll and its TextOut api drew to the .net form.
Excellent! It doesn't solve my problem, but progress is
being made.

Is there a way to get whatever's drawn on a picturebox
into a bitmap? The reason I ask is maybe instead of
creating a bitmap in my aspx code and trying to draw to
it, I can import System.Windows.Forms, Dim pic as
PictureBox, send pic's hdc to my dll, then take whatever's
draw on "pic" in memory and create a bitmap (or better
yet, stream it to a byte array).
[color=blue]
>-----Original Message-----
>Let me start off by saying thank you for sticking with me
>for the last few days, I really appreciate your time.
>
>On to your last post....that's great. Now I know how to
>draw to form and control objects in .net using a gdi32[/color]
api.[color=blue]
>
>However, I tried tweaking what you sent to get a usable
>hdc from a bitmap and I couldn't.
>
>Based on my previous question (and the first thing you
>responded to in your last post)... Is a
>GRAPHICS.getHdc.ToInt32 an integer representation of a
>bitmap's hdc? One that VB6 can use... Remember my
>original problem:
>
> Dim bm As Bitmap = New Bitmap(728, 312)
> Dim gfx As Graphics = Graphics.FromImage(bm)
> gfx.Clear(Color.White)
> Dim gfxhDC As IntPtr = gfx.GetHdc()
> prt.hdc = gfxhDC.ToInt32
> prt.Draw
> bm.Save(sTempFile,
>System.Drawing.Imaging.ImageFormat.Bmp)
> bm.Dispose()
> gfx.ReleaseHdc(gfxhDC)
>
>Where prt.hdc is the property in my vb6 dll that holds[/color]
the[color=blue]
>device context to draw to and prt.Draw tells the vb6 dll
>to go ahead and draw its data to the given hdc.
>[color=green]
>>-----Original Message-----[color=darkred]
>>> where Handle.ToInt32 is the integer representation of[/color][/color]
>the[color=green][color=darkred]
>>> handle...which is the object's hDc, is this not true?[/color]
>>
>>Handle.ToInt32 _IS_ the integer representation of a[/color]
>handle, but Form.Handle[color=green]
>>is a window handle (HWND),
>>not a GDI device context handle (HDC). To obtain an HDC[/color]
>for a form or a[color=green]
>>control, you should employ
>>the Graphics class and contruct it by using the static[/color]
>FromHwnd method:[color=green]
>>
>>Dim g AsGraphics = Graphics.FromHwnd(Me.Handle)
>>
>>Dim hdc As IntPtr = g.GetHdc()
>>TextOut(hdc, 100, 100, "TESTING", 7)
>>g.ReleaseHdc(hdc)
>>
>>--
>>Dmitriy Lapshin [C# / .NET MVP]
>>X-Unity Test Studio
>>http://x-unity.miik.com.ua/teststudio.aspx
>>Bring the power of unit testing to VS .NET IDE
>>
>>"Metallicraft" <anonymous@discussions.microsoft.com>[/color]
>wrote in message[color=green]
>>news:0c4d01c3a47a$26d38e70$a501280a@phx.gbl...[color=darkred]
>>> I understand what you're saying about the HDC and HWND,
>>> but I thought Handle.ToInt32 was the same as Integer...
>>> where Handle.ToInt32 is the integer representation of[/color][/color]
>the[color=green][color=darkred]
>>> handle...which is the object's hDc, is this not true?
>>>
>>> When I'd pass a Handle to the TextOut API, I have the[/color][/color]
>hDc[color=green][color=darkred]
>>> in the TextOut declaration defined as an IntPtr. Are
>>> Handle and IntPtr different?
>>>
>>> If not, how would one declare the TextOut, for example,
>>> and what would be passed to the hDc parameter?
>>>
>>> Maybe that's not important because the REAL dll I'm[/color][/color]
>trying[color=green][color=darkred]
>>> to get to work cannot be changed. So I need to know[/color][/color][/color]
if[color=blue]
>I[color=green][color=darkred]
>>> can pass a .Net-something into a VB6 Long variable and
>>> have them both be refering to the same hDc.
>>>
>>> I understand what you mean about the single-threading,[/color][/color]
>but[color=green][color=darkred]
>>> I'm still not sure where the "<STAThread()>" would go[/color][/color][/color]
or[color=blue][color=green][color=darkred]
>>> how it's used. I have very little experience dealing[/color][/color]
>with[color=green][color=darkred]
>>> threads.
>>>
>>> >-----Original Message-----
>>> >Just to be safe: HDC and HWND are NOT the same and are
>>> NOT interchangeable.
>>> >And therefore neither of the below will work as it[/color][/color]
>seems[color=green][color=darkred]
>>> you are passing
>>> >HWND
>>> >where HDC is expected.
>>> >
>>> >> hDc As IntPtr and TextOut(Me.Handle, etc....
>>> >>
>>> >> -AND-
>>> >>
>>> >> hDc As Integer and TextOut(Me.Handle.ToInt32, etc...
>>> >
>>> >From my experience there's no big difference whether[/color][/color]
>you[color=green][color=darkred]
>>> declare an API
>>> >function parameter as Int32 or IntPtr (the latter is
>>> preferred as you'll
>>> >avoid explicit type casts in your code) - both ways[/color][/color]
>work.[color=green][color=darkred]
>>> >
>>> >> I'm afraid I don't understand your last question
>>> >> about "[STAThread]".
>>> >
>>> >Oops, it's C# syntax. In VB .NET it should look like
>>> <STAThread()> or
>>> >something like that. It's an attribute that indicated[/color][/color]
>the[color=green][color=darkred]
>>> application is
>>> >single-thread and no call to a COM object will be
>>> originated by a thread
>>> >other that the main one. This is important to the COM
>>> subsystem to ensure
>>> >instantiated COM objects (and your VB6 DLL is an[/color][/color]
>ActiveX[color=green][color=darkred]
>>> DLL, isn't it?) run
>>> >in the expected apartment. This is STA in case of VB6
>>> ActiveX DLLs.
>>> >
>>> >--
>>> >Dmitriy Lapshin [C# / .NET MVP]
>>> >X-Unity Test Studio
>>> >http://x-unity.miik.com.ua/teststudio.aspx
>>> >Bring the power of unit testing to VS .NET IDE
>>> >
>>> >"Metallicraft" <anonymous@discussions.microsoft.com>
>>> wrote in message
>>> >news:0a9201c3a470$087fc6f0$a601280a@phx.gbl...
>>> >> Me.Handle refers to the form's handle when I tried[/color][/color][/color]
to[color=blue][color=green][color=darkred]
>>> just
>>> >> TextOut to the form instead of a PictureBox. I do
>>> believe
>>> >> it's an hWnd. You'll note in the declaration:
>>> >>
>>> >> <System.Runtime.InteropServices.DllImportAttribu te
>>> >> ("gdi32.dll")> _
>>> >> Private Shared Function TextOut(ByVal hdc As[/color][/color][/color]
IntPtr,[color=blue][color=green][color=darkred]
>>> >> ByVal X As Integer, ByVal Y As Integer, ByVal
>>> lpString
>>> >> As String, ByVal nCount As Integer) As Integer
>>> >> End Function
>>> >>
>>> >> ...hdc is defined as an "IntPtr". I've seen this[/color][/color]
>done[color=green][color=darkred]
>>> in
>>> >> many examples with APIs that require an hDc that's
>>> >> normally a Long type, though I don't understand how
>>> people
>>> >> can just change the API declaration like that and[/color][/color]
>have[color=green][color=darkred]
>>> it
>>> >> still work (I always thought API declarations were[/color][/color]
>very[color=green][color=darkred]
>>> >> strict). Nevertheless, I've tried it both ways:
>>> >>
>>> >> hDc As IntPtr and TextOut(Me.Handle, etc....
>>> >>
>>> >> -AND-
>>> >>
>>> >> hDc As Integer and TextOut(Me.Handle.ToInt32, etc...
>>> >>
>>> >> Neither work.
>>> >>
>>> >> I'm afraid I don't understand your last question
>>> >> about "[STAThread]".
>>> >>
>>> >> >-----Original Message-----
>>> >> >> I understand that Object.GetHdc is a pointer,[/color][/color][/color]
but[color=blue]
>is[color=green][color=darkred]
>>> >> >> Object.GetHdc.ToInt32 the same as a gdi32 device
>>> context
>>> >> >> or vb6 picturebox.hdc?
>>> >> >
>>> >> >Yes, they SHOULD be the same according to MSDN.[/color][/color][/color]
But:[color=blue][color=green][color=darkred]
>>> >> >
>>> >> >> ...to the top and in a button_click adding this:
>>> >> >>
>>> >> >> TextOut(Me.Handle, 100, 100, "TESTING", 7)
>>> >> >
>>> >> >What is Me.Handle here? I suppose it is actually[/color][/color]
>HWND[color=green][color=darkred]
>>> and
>>> >> not HDC?
>>> >> >Does your static Main function is marked as[/color][/color]
>[STAThread][color=green][color=darkred]
>>> >> by the way?
>>> >> >
>>> >> >--
>>> >> >Dmitriy Lapshin [C# / .NET MVP]
>>> >> >X-Unity Test Studio
>>> >> >http://x-unity.miik.com.ua/teststudio.aspx
>>> >> >Bring the power of unit testing to VS .NET IDE
>>> >> >
>>> >> >"Metallicraft"[/color][/color][/color]
<anonymous@discussions.microsoft.com>[color=blue][color=green][color=darkred]
>>> >> wrote in message
>>> >> >news:0f8501c3a3bd$44102100$a501280a@phx.gbl...
>>> >> >> Well, I've tried a couple different things.
>>> >> >>
>>> >> >> I created a vb6 dll with the following code:
>>> >> >>
>>> >> >> Option Explicit
>>> >> >>
>>> >> >> Private Declare Function TextOut Lib "gdi32"
>>> >> >> Alias "TextOutA" (ByVal hdc As Long, ByVal X As[/color][/color]
>Long,[color=green][color=darkred]
>>> >> >> ByVal Y As Long, ByVal lpString As String, ByVal
>>> nCount
>>> >> As
>>> >> >> Long) As Long
>>> >> >>
>>> >> >> Public Sub DrawText(ByRef hdc As Long)
>>> >> >> Dim dl As Long
>>> >> >> dl = TextOut(hdc, 0, 0, "TEST", Len("TEST"))
>>> >> >> End Sub
>>> >> >>
>>> >> >> ...and I compiled it.
>>> >> >>
>>> >> >> I then created a vb application (referencing that
>>> dll)
>>> >> >> with the following code:
>>> >> >>
>>> >> >> Option Explicit
>>> >> >>
>>> >> >> Private Sub Form_Load()
>>> >> >> Picture1.AutoRedraw = True
>>> >> >>
>>> >> >> Dim dt As DrawText.clsDrawText
>>> >> >> Set dt = New DrawText.clsDrawText
>>> >> >> dt.DrawText (Picture1.hDC)
>>> >> >>
>>> >> >> Picture1.Refresh
>>> >> >> End Sub
>>> >> >>
>>> >> >> ...the form contains one picture box.
>>> >> >>
>>> >> >> When I run the app, I get the word "TEST" in the
>>> picture
>>> >> >> box as I would expect.
>>> >> >>
>>> >> >> Next, I created a vb.net Windows app, with only[/color][/color]
>one[color=green][color=darkred]
>>> >> form,
>>> >> >> one button, and a picture box. I referenced my
>>> simple
>>> >> dll
>>> >> >> above and the only code exists in the[/color][/color]
>button_click:[color=green][color=darkred]
>>> >> >>
>>> >> >> Dim dt As New DrawText.clsDrawTextClass
>>> >> >> dt.DrawText(PictureBox1.Handle.ToInt32)
>>> >> >> dt = Nothing
>>> >> >>
>>> >> >> PictureBox1.Refresh()
>>> >> >>
>>> >> >> ...I run the app, press the button, and get no[/color][/color]
>text.[color=green][color=darkred]
>>> >> I've
>>> >> >> tried this with and without the Refresh and with[/color][/color]
>and[color=green][color=darkred]
>>> >> >> without the PictureBox (using the form's handle
>>> instead)
>>> >> >> with the same results.
>>> >> >>
>>> >> >> I have also tried, in a vb.net app, adding this:
>>> >> >>
>>> >> >>
>>> <System.Runtime.InteropServices.DllImportAttribu te
>>> >> >> ("gdi32.dll")> _
>>> >> >> Private Shared Function TextOut(ByVal hdc As
>>> IntPtr,
>>> >> >> ByVal X As Integer, ByVal Y As Integer, ByVal
>>> lpString
>>> >> As
>>> >> >> String, ByVal nCount As Integer) As Integer
>>> >> >> End Function
>>> >> >>
>>> >> >> ...to the top and in a button_click adding this:
>>> >> >>
>>> >> >> TextOut(Me.Handle, 100, 100, "TESTING", 7)
>>> >> >>
>>> >> >> ...running it, pressing button, and getting no[/color][/color]
>text.[color=green][color=darkred]
>>> >> >>
>>> >> >> So, even taking my dll and the graphics object[/color][/color]
>out of[color=green][color=darkred]
>>> >> the
>>> >> >> equation, I can't get a gdi32 function, like
>>> TextOut, to
>>> >> >> write on a .Net device context.
>>> >> >>
>>> >> >> I understand that Object.GetHdc is a pointer,[/color][/color][/color]
but[color=blue]
>is[color=green][color=darkred]
>>> >> >> Object.GetHdc.ToInt32 the same as a gdi32 device
>>> context
>>> >> >> or vb6 picturebox.hdc?
>>> >> >>
>>> >> >> >-----Original Message-----
>>> >> >> >You can try calling a raw GDI function through
>>> P/Invoke
>>> >> >> on the HDC obtained
>>> >> >> >and see whether it works that way. If yes, you[/color][/color][/color]
at[color=blue][color=green][color=darkred]
>>> least
>>> >> >> know the HDC being
>>> >> >> >passed is valid.
>>> >> >> >
>>> >> >> >There also could be problems with VB6 COM DLL
>>> running
>>> >> on
>>> >> >> a separate thread
>>> >> >> >(as it runs in the Single-Threaded Apartment and
>>> >> ASP .NET
>>> >> >> is
>>> >> >> >multi-threaded), and I am not sure HDCs can be
>>> >> passed "as
>>> >> >> is" between
>>> >> >> >threads.
>>> >> >> >
>>> >> >> >--
>>> >> >> >Dmitriy Lapshin [C# / .NET MVP]
>>> >> >> >X-Unity Test Studio
>>> >> >> >http://x-unity.miik.com.ua/teststudio.aspx
>>> >> >> >Bring the power of unit testing to VS .NET IDE
>>> >> >> >
>>> >> >> >"Metallicraft"[/color][/color]
><anonymous@discussions.microsoft.com>[color=green][color=darkred]
>>> >> >> wrote in message
>>> >> >> >news:083501c3a3af$6ff09d30$a001280a@phx.gbl...
>>> >> >> >> Thanks for responding.
>>> >> >> >>
>>> >> >> >> I dispose of my bitmap and release the dc[/color][/color]
>after I[color=green][color=darkred]
>>> >> write
>>> >> >> >> the bitmap to a file further down in the[/color][/color]
>code. I[color=green][color=darkred]
>>> >> know
>>> >> >> the
>>> >> >> >> vb6 dll works in vb6. The vb6 dll is[/color][/color]
>production[color=green][color=darkred]
>>> >> >> software
>>> >> >> >> already working in the hands of hundreds of
>>> clients.
>>> >> >> >>
>>> >> >> >> I can do a:
>>> >> >> >>
>>> >> >> >> gfx.DrawString("test", New Font[/color][/color]
>("Arial",[color=green][color=darkred]
>>> >> 24.0F),
>>> >> >> >> Brushes.Black, 0, 0)
>>> >> >> >> gfx.DrawRectangle(New Pen[/color][/color][/color]
(Color.Black),[color=blue][color=green][color=darkred]
>>> New
>>> >> >> >> Rectangle(2, 1, 725, 309))
>>> >> >> >>
>>> >> >> >> ...inside vb.net and get a bitmap with text[/color][/color]
>and a[color=green][color=darkred]
>>> >> >> >> rectangle, but when passing the graphic's hdc
>>> >> >> >> (Graphic.GetHdc.ToInt32) I get no drawing
>>> whatsoever
>>> >> >> from
>>> >> >> >> the vb6 dll.
>>> >> >> >>
>>> >> >> >> >-----Original Message-----
>>> >> >> >> >Hi,
>>> >> >> >> >
>>> >> >> >> >You can try calling ReleaseDC after the VB6[/color][/color]
>dll[color=green][color=darkred]
>>> has
>>> >> >> >> finished drawing. The
>>> >> >> >> >rest of .NET code looks correct. You might[/color][/color]
>also[color=green][color=darkred]
>>> >> want to
>>> >> >> >> debug your VB6 dll
>>> >> >> >> >to see where it possibly fails.
>>> >> >> >> >
>>> >> >> >> >--
>>> >> >> >> >Dmitriy Lapshin [C# / .NET MVP]
>>> >> >> >> >X-Unity Test Studio
>>> >> >> >> >http://x-unity.miik.com.ua/teststudio.aspx
>>> >> >> >> >Bring the power of unit testing to VS .NET[/color][/color][/color]
IDE[color=blue][color=green][color=darkred]
>>> >> >> >> >
>>> >> >> >> >"Metallicraft"
>>> <anonymous@discussions.microsoft.com>
>>> >> >> >> wrote in message
>>> >> >> >> >news:066e01c3a3a4$58879370[/color][/color][/color]
$a001280a@phx.gbl...[color=blue][color=green][color=darkred]
>>> >> >> >> >> I have a vb6 application. On the main form[/color][/color]
>is a[color=green][color=darkred]
>>> >> >> picture
>>> >> >> >> >> box with one or two images and several[/color][/color]
>pieces[color=green][color=darkred]
>>> of
>>> >> text
>>> >> >> >> >> displayed in it. These are created on the[/color][/color]
>fly[color=green][color=darkred]
>>> >> using
>>> >> >> >> gdi32
>>> >> >> >> >> routines that are all in a referenced,[/color][/color]
>custom[color=green][color=darkred]
>>> >> dll. I
>>> >> >> >> call
>>> >> >> >> >> a PrintImage routine in the dll and pass it
>>> only
>>> >> the
>>> >> >> the
>>> >> >> >> >> Picturebox.hdc from the main form. The[/color][/color][/color]
dll's[color=blue][color=green][color=darkred]
>>> print
>>> >> >> >> routine
>>> >> >> >> >> draws to the hdc and it shows up in the
>>> picturebox
>>> >> >> >> >> perfectly.
>>> >> >> >> >>
>>> >> >> >> >> I would like to do a similar thing with an
>>> asp.net
>>> >> >> page
>>> >> >> >> >> using my same vb6 custom printing dll.[/color][/color][/color]
Where[color=blue][color=green][color=darkred]
>>> >> >> >> Display.aspx
>>> >> >> >> >> has and IMG tag with src="Image.aspx".[/color][/color][/color]
Now,[color=blue]
>in[color=green][color=darkred]
>>> the
>>> >> >> >> >> Image.aspx.vb code, I make the necessary[/color][/color]
>calls[color=green][color=darkred]
>>> to
>>> >> my
>>> >> >> dll
>>> >> >> >> >> to preload some data, then I call the
>>> PrintImage
>>> >> >> >> routine.
>>> >> >> >> >> What I get back is a black box. Since it's[/color][/color]
>an[color=green][color=darkred]
>>> >> asp.net
>>> >> >> >> page
>>> >> >> >> >> I don't have a picturebox to draw to (even[/color][/color]
>if I[color=green][color=darkred]
>>> >> did,
>>> >> >> I'm
>>> >> >> >> >> not sure the picturebox's Handle would be[/color][/color]
>the[color=green][color=darkred]
>>> >> same as
>>> >> >> >> >> vb6's hdc). So I'm trying to create a[/color][/color][/color]
bitmap[color=blue][color=green][color=darkred]
>>> >> in .net
>>> >> >> >> where
>>> >> >> >> >> i can eventually get an hdc that I can[/color][/color][/color]
send[color=blue]
>to[color=green][color=darkred]
>>> my
>>> >> >> >> printing
>>> >> >> >> >> routine in the vb6 dll. Below is the code[/color][/color][/color]
I[color=blue]
>use[color=green][color=darkred]
>>> >> to do
>>> >> >> >> this:
>>> >> >> >> >>
>>> >> >> >> >> Dim bm As Bitmap = New Bitmap(728, 312)
>>> >> >> >> >> Dim gfx As Graphics = Graphics.FromImage[/color][/color][/color]
(bm)[color=blue][color=green][color=darkred]
>>> >> >> >> >> gfx.Clear(Color.White)
>>> >> >> >> >> Dim hDC As IntPtr = gfx.GetHdc()
>>> >> >> >> >> prt.hdc = hDC.ToInt32 'prt.hdc is the[/color][/color]
>property[color=green][color=darkred]
>>> in
>>> >> my
>>> >> >> vb6
>>> >> >> >> >> dll that receives the hdc to print to
>>> >> >> >> >>
>>> >> >> >> >> The code runs without error, I save the[/color][/color]
>bitmap[color=green][color=darkred]
>>> to
>>> >> a
>>> >> >> >> file,
>>> >> >> >> >> read it into a bytearray, and do a
>>> >> >> >> >> Response.Binarywrite...I get a black box[/color][/color]
>(well,[color=green][color=darkred]
>>> >> now I
>>> >> >> >> get
>>> >> >> >> >> a white box since I added the gfx.Clear[/color][/color][/color]
line[color=blue][color=green][color=darkred]
>>> >> above).
>>> >> >> >> >>
>>> >> >> >> >> Why can't my vb6 printing dll draw to[/color][/color][/color]
a .net[color=blue][color=green][color=darkred]
>>> hdc?
>>> >> >> >> >>
>>> >> >> >> >> PS. I eventually don't want to have to[/color][/color][/color]
save[color=blue]
>the[color=green][color=darkred]
>>> >> >> bitmap
>>> >> >> >> to
>>> >> >> >> >> a file. If I can get the correct drawing[/color][/color][/color]
on[color=blue]
>a[color=green][color=darkred]
>>> >> device
>>> >> >> >> >> context, I'd like to be able to stream that
>>> >> directly
>>> >> >> to
>>> >> >> >> a
>>> >> >> >> >> byte array and do a Response.Binarywrite.
>>> >> >> >> >>
>>> >> >> >> >> If an expert can help with my main issue[/color][/color]
>and my[color=green][color=darkred]
>>> >> PS. I
>>> >> >> >> >> would greatly appreciate it.
>>> >> >> >> >
>>> >> >> >> >.
>>> >> >> >> >
>>> >> >> >
>>> >> >> >.
>>> >> >> >
>>> >> >
>>> >> >.
>>> >> >
>>> >
>>> >.
>>> >[/color]
>>
>>.
>>[/color]
>.
>[/color]
Dmitriy Lapshin [C# / .NET MVP]
Guest
 
Posts: n/a
#13: Nov 20 '05

re: Drawing on a .Net device context from a vb6 dll


> Is a GRAPHICS.getHdc.ToInt32 an integer representation of a[color=blue]
> bitmap's hdc? One that VB6 can use...[/color]

Yes, at least theoretically it is. And there are some 'BUT's:

1. A bitmap by itself cannot have HDC. In raw GDI terms, it can be
*selected* into some HDC, and then one can perform drawing on it or blit it
to another HDC. The .NET's representation of HDC is the Graphics class.

2. I suppose your problem is not related to HDC correctness. The code
snippet you have given in the latest post looks absolutely fine - except
that I'd recommend releasing the HDC *before* you attempt to save the
bitmap. I wonder if you could paste this snippet into a simple Windows Forms
application and test it there first. If it works that way, the problem is
obviously not with the HDC, but with threading I assume.

3. Mind the color depth. The Bitmap instance you've created has 32-bit color
depth by default (unless requested otherwise in the constructor) and make
sure your VB6 DLL can handle such bitmaps right.

--
Dmitriy Lapshin [C# / .NET MVP]
X-Unity Test Studio
http://x-unity.miik.com.ua/teststudio.aspx
Bring the power of unit testing to VS .NET IDE

"Metallicraft" <anonymous@discussions.microsoft.com> wrote in message
news:0a5601c3a53d$5f9b57b0$a601280a@phx.gbl...[color=blue]
> Let me start off by saying thank you for sticking with me
> for the last few days, I really appreciate your time.
>
> On to your last post....that's great. Now I know how to
> draw to form and control objects in .net using a gdi32 api.
>
> However, I tried tweaking what you sent to get a usable
> hdc from a bitmap and I couldn't.
>
> Based on my previous question (and the first thing you
> responded to in your last post)... Is a
> GRAPHICS.getHdc.ToInt32 an integer representation of a
> bitmap's hdc? One that VB6 can use... Remember my
> original problem:
>
> Dim bm As Bitmap = New Bitmap(728, 312)
> Dim gfx As Graphics = Graphics.FromImage(bm)
> gfx.Clear(Color.White)
> Dim gfxhDC As IntPtr = gfx.GetHdc()
> prt.hdc = gfxhDC.ToInt32
> prt.Draw
> bm.Save(sTempFile,
> System.Drawing.Imaging.ImageFormat.Bmp)
> bm.Dispose()
> gfx.ReleaseHdc(gfxhDC)
>
> Where prt.hdc is the property in my vb6 dll that holds the
> device context to draw to and prt.Draw tells the vb6 dll
> to go ahead and draw its data to the given hdc.
>[color=green]
> >-----Original Message-----[color=darkred]
> >> where Handle.ToInt32 is the integer representation of[/color][/color]
> the[color=green][color=darkred]
> >> handle...which is the object's hDc, is this not true?[/color]
> >
> >Handle.ToInt32 _IS_ the integer representation of a[/color]
> handle, but Form.Handle[color=green]
> >is a window handle (HWND),
> >not a GDI device context handle (HDC). To obtain an HDC[/color]
> for a form or a[color=green]
> >control, you should employ
> >the Graphics class and contruct it by using the static[/color]
> FromHwnd method:[color=green]
> >
> >Dim g AsGraphics = Graphics.FromHwnd(Me.Handle)
> >
> >Dim hdc As IntPtr = g.GetHdc()
> >TextOut(hdc, 100, 100, "TESTING", 7)
> >g.ReleaseHdc(hdc)
> >
> >--
> >Dmitriy Lapshin [C# / .NET MVP]
> >X-Unity Test Studio
> >http://x-unity.miik.com.ua/teststudio.aspx
> >Bring the power of unit testing to VS .NET IDE
> >
> >"Metallicraft" <anonymous@discussions.microsoft.com>[/color]
> wrote in message[color=green]
> >news:0c4d01c3a47a$26d38e70$a501280a@phx.gbl...[color=darkred]
> >> I understand what you're saying about the HDC and HWND,
> >> but I thought Handle.ToInt32 was the same as Integer...
> >> where Handle.ToInt32 is the integer representation of[/color][/color]
> the[color=green][color=darkred]
> >> handle...which is the object's hDc, is this not true?
> >>
> >> When I'd pass a Handle to the TextOut API, I have the[/color][/color]
> hDc[color=green][color=darkred]
> >> in the TextOut declaration defined as an IntPtr. Are
> >> Handle and IntPtr different?
> >>
> >> If not, how would one declare the TextOut, for example,
> >> and what would be passed to the hDc parameter?
> >>
> >> Maybe that's not important because the REAL dll I'm[/color][/color]
> trying[color=green][color=darkred]
> >> to get to work cannot be changed. So I need to know if[/color][/color]
> I[color=green][color=darkred]
> >> can pass a .Net-something into a VB6 Long variable and
> >> have them both be refering to the same hDc.
> >>
> >> I understand what you mean about the single-threading,[/color][/color]
> but[color=green][color=darkred]
> >> I'm still not sure where the "<STAThread()>" would go or
> >> how it's used. I have very little experience dealing[/color][/color]
> with[color=green][color=darkred]
> >> threads.
> >>
> >> >-----Original Message-----
> >> >Just to be safe: HDC and HWND are NOT the same and are
> >> NOT interchangeable.
> >> >And therefore neither of the below will work as it[/color][/color]
> seems[color=green][color=darkred]
> >> you are passing
> >> >HWND
> >> >where HDC is expected.
> >> >
> >> >> hDc As IntPtr and TextOut(Me.Handle, etc....
> >> >>
> >> >> -AND-
> >> >>
> >> >> hDc As Integer and TextOut(Me.Handle.ToInt32, etc...
> >> >
> >> >From my experience there's no big difference whether[/color][/color]
> you[color=green][color=darkred]
> >> declare an API
> >> >function parameter as Int32 or IntPtr (the latter is
> >> preferred as you'll
> >> >avoid explicit type casts in your code) - both ways[/color][/color]
> work.[color=green][color=darkred]
> >> >
> >> >> I'm afraid I don't understand your last question
> >> >> about "[STAThread]".
> >> >
> >> >Oops, it's C# syntax. In VB .NET it should look like
> >> <STAThread()> or
> >> >something like that. It's an attribute that indicated[/color][/color]
> the[color=green][color=darkred]
> >> application is
> >> >single-thread and no call to a COM object will be
> >> originated by a thread
> >> >other that the main one. This is important to the COM
> >> subsystem to ensure
> >> >instantiated COM objects (and your VB6 DLL is an[/color][/color]
> ActiveX[color=green][color=darkred]
> >> DLL, isn't it?) run
> >> >in the expected apartment. This is STA in case of VB6
> >> ActiveX DLLs.
> >> >
> >> >--
> >> >Dmitriy Lapshin [C# / .NET MVP]
> >> >X-Unity Test Studio
> >> >http://x-unity.miik.com.ua/teststudio.aspx
> >> >Bring the power of unit testing to VS .NET IDE
> >> >
> >> >"Metallicraft" <anonymous@discussions.microsoft.com>
> >> wrote in message
> >> >news:0a9201c3a470$087fc6f0$a601280a@phx.gbl...
> >> >> Me.Handle refers to the form's handle when I tried to
> >> just
> >> >> TextOut to the form instead of a PictureBox. I do
> >> believe
> >> >> it's an hWnd. You'll note in the declaration:
> >> >>
> >> >> <System.Runtime.InteropServices.DllImportAttribu te
> >> >> ("gdi32.dll")> _
> >> >> Private Shared Function TextOut(ByVal hdc As IntPtr,
> >> >> ByVal X As Integer, ByVal Y As Integer, ByVal
> >> lpString
> >> >> As String, ByVal nCount As Integer) As Integer
> >> >> End Function
> >> >>
> >> >> ...hdc is defined as an "IntPtr". I've seen this[/color][/color]
> done[color=green][color=darkred]
> >> in
> >> >> many examples with APIs that require an hDc that's
> >> >> normally a Long type, though I don't understand how
> >> people
> >> >> can just change the API declaration like that and[/color][/color]
> have[color=green][color=darkred]
> >> it
> >> >> still work (I always thought API declarations were[/color][/color]
> very[color=green][color=darkred]
> >> >> strict). Nevertheless, I've tried it both ways:
> >> >>
> >> >> hDc As IntPtr and TextOut(Me.Handle, etc....
> >> >>
> >> >> -AND-
> >> >>
> >> >> hDc As Integer and TextOut(Me.Handle.ToInt32, etc...
> >> >>
> >> >> Neither work.
> >> >>
> >> >> I'm afraid I don't understand your last question
> >> >> about "[STAThread]".
> >> >>
> >> >> >-----Original Message-----
> >> >> >> I understand that Object.GetHdc is a pointer, but[/color][/color]
> is[color=green][color=darkred]
> >> >> >> Object.GetHdc.ToInt32 the same as a gdi32 device
> >> context
> >> >> >> or vb6 picturebox.hdc?
> >> >> >
> >> >> >Yes, they SHOULD be the same according to MSDN. But:
> >> >> >
> >> >> >> ...to the top and in a button_click adding this:
> >> >> >>
> >> >> >> TextOut(Me.Handle, 100, 100, "TESTING", 7)
> >> >> >
> >> >> >What is Me.Handle here? I suppose it is actually[/color][/color]
> HWND[color=green][color=darkred]
> >> and
> >> >> not HDC?
> >> >> >Does your static Main function is marked as[/color][/color]
> [STAThread][color=green][color=darkred]
> >> >> by the way?
> >> >> >
> >> >> >--
> >> >> >Dmitriy Lapshin [C# / .NET MVP]
> >> >> >X-Unity Test Studio
> >> >> >http://x-unity.miik.com.ua/teststudio.aspx
> >> >> >Bring the power of unit testing to VS .NET IDE
> >> >> >
> >> >> >"Metallicraft" <anonymous@discussions.microsoft.com>
> >> >> wrote in message
> >> >> >news:0f8501c3a3bd$44102100$a501280a@phx.gbl...
> >> >> >> Well, I've tried a couple different things.
> >> >> >>
> >> >> >> I created a vb6 dll with the following code:
> >> >> >>
> >> >> >> Option Explicit
> >> >> >>
> >> >> >> Private Declare Function TextOut Lib "gdi32"
> >> >> >> Alias "TextOutA" (ByVal hdc As Long, ByVal X As[/color][/color]
> Long,[color=green][color=darkred]
> >> >> >> ByVal Y As Long, ByVal lpString As String, ByVal
> >> nCount
> >> >> As
> >> >> >> Long) As Long
> >> >> >>
> >> >> >> Public Sub DrawText(ByRef hdc As Long)
> >> >> >> Dim dl As Long
> >> >> >> dl = TextOut(hdc, 0, 0, "TEST", Len("TEST"))
> >> >> >> End Sub
> >> >> >>
> >> >> >> ...and I compiled it.
> >> >> >>
> >> >> >> I then created a vb application (referencing that
> >> dll)
> >> >> >> with the following code:
> >> >> >>
> >> >> >> Option Explicit
> >> >> >>
> >> >> >> Private Sub Form_Load()
> >> >> >> Picture1.AutoRedraw = True
> >> >> >>
> >> >> >> Dim dt As DrawText.clsDrawText
> >> >> >> Set dt = New DrawText.clsDrawText
> >> >> >> dt.DrawText (Picture1.hDC)
> >> >> >>
> >> >> >> Picture1.Refresh
> >> >> >> End Sub
> >> >> >>
> >> >> >> ...the form contains one picture box.
> >> >> >>
> >> >> >> When I run the app, I get the word "TEST" in the
> >> picture
> >> >> >> box as I would expect.
> >> >> >>
> >> >> >> Next, I created a vb.net Windows app, with only[/color][/color]
> one[color=green][color=darkred]
> >> >> form,
> >> >> >> one button, and a picture box. I referenced my
> >> simple
> >> >> dll
> >> >> >> above and the only code exists in the[/color][/color]
> button_click:[color=green][color=darkred]
> >> >> >>
> >> >> >> Dim dt As New DrawText.clsDrawTextClass
> >> >> >> dt.DrawText(PictureBox1.Handle.ToInt32)
> >> >> >> dt = Nothing
> >> >> >>
> >> >> >> PictureBox1.Refresh()
> >> >> >>
> >> >> >> ...I run the app, press the button, and get no[/color][/color]
> text.[color=green][color=darkred]
> >> >> I've
> >> >> >> tried this with and without the Refresh and with[/color][/color]
> and[color=green][color=darkred]
> >> >> >> without the PictureBox (using the form's handle
> >> instead)
> >> >> >> with the same results.
> >> >> >>
> >> >> >> I have also tried, in a vb.net app, adding this:
> >> >> >>
> >> >> >>
> >> <System.Runtime.InteropServices.DllImportAttribu te
> >> >> >> ("gdi32.dll")> _
> >> >> >> Private Shared Function TextOut(ByVal hdc As
> >> IntPtr,
> >> >> >> ByVal X As Integer, ByVal Y As Integer, ByVal
> >> lpString
> >> >> As
> >> >> >> String, ByVal nCount As Integer) As Integer
> >> >> >> End Function
> >> >> >>
> >> >> >> ...to the top and in a button_click adding this:
> >> >> >>
> >> >> >> TextOut(Me.Handle, 100, 100, "TESTING", 7)
> >> >> >>
> >> >> >> ...running it, pressing button, and getting no[/color][/color]
> text.[color=green][color=darkred]
> >> >> >>
> >> >> >> So, even taking my dll and the graphics object[/color][/color]
> out of[color=green][color=darkred]
> >> >> the
> >> >> >> equation, I can't get a gdi32 function, like
> >> TextOut, to
> >> >> >> write on a .Net device context.
> >> >> >>
> >> >> >> I understand that Object.GetHdc is a pointer, but[/color][/color]
> is[color=green][color=darkred]
> >> >> >> Object.GetHdc.ToInt32 the same as a gdi32 device
> >> context
> >> >> >> or vb6 picturebox.hdc?
> >> >> >>
> >> >> >> >-----Original Message-----
> >> >> >> >You can try calling a raw GDI function through
> >> P/Invoke
> >> >> >> on the HDC obtained
> >> >> >> >and see whether it works that way. If yes, you at
> >> least
> >> >> >> know the HDC being
> >> >> >> >passed is valid.
> >> >> >> >
> >> >> >> >There also could be problems with VB6 COM DLL
> >> running
> >> >> on
> >> >> >> a separate thread
> >> >> >> >(as it runs in the Single-Threaded Apartment and
> >> >> ASP .NET
> >> >> >> is
> >> >> >> >multi-threaded), and I am not sure HDCs can be
> >> >> passed "as
> >> >> >> is" between
> >> >> >> >threads.
> >> >> >> >
> >> >> >> >--
> >> >> >> >Dmitriy Lapshin [C# / .NET MVP]
> >> >> >> >X-Unity Test Studio
> >> >> >> >http://x-unity.miik.com.ua/teststudio.aspx
> >> >> >> >Bring the power of unit testing to VS .NET IDE
> >> >> >> >
> >> >> >> >"Metallicraft"[/color][/color]
> <anonymous@discussions.microsoft.com>[color=green][color=darkred]
> >> >> >> wrote in message
> >> >> >> >news:083501c3a3af$6ff09d30$a001280a@phx.gbl...
> >> >> >> >> Thanks for responding.
> >> >> >> >>
> >> >> >> >> I dispose of my bitmap and release the dc[/color][/color]
> after I[color=green][color=darkred]
> >> >> write
> >> >> >> >> the bitmap to a file further down in the[/color][/color]
> code. I[color=green][color=darkred]
> >> >> know
> >> >> >> the
> >> >> >> >> vb6 dll works in vb6. The vb6 dll is[/color][/color]
> production[color=green][color=darkred]
> >> >> >> software
> >> >> >> >> already working in the hands of hundreds of
> >> clients.
> >> >> >> >>
> >> >> >> >> I can do a:
> >> >> >> >>
> >> >> >> >> gfx.DrawString("test", New Font[/color][/color]
> ("Arial",[color=green][color=darkred]
> >> >> 24.0F),
> >> >> >> >> Brushes.Black, 0, 0)
> >> >> >> >> gfx.DrawRectangle(New Pen(Color.Black),
> >> New
> >> >> >> >> Rectangle(2, 1, 725, 309))
> >> >> >> >>
> >> >> >> >> ...inside vb.net and get a bitmap with text[/color][/color]
> and a[color=green][color=darkred]
> >> >> >> >> rectangle, but when passing the graphic's hdc
> >> >> >> >> (Graphic.GetHdc.ToInt32) I get no drawing
> >> whatsoever
> >> >> >> from
> >> >> >> >> the vb6 dll.
> >> >> >> >>
> >> >> >> >> >-----Original Message-----
> >> >> >> >> >Hi,
> >> >> >> >> >
> >> >> >> >> >You can try calling ReleaseDC after the VB6[/color][/color]
> dll[color=green][color=darkred]
> >> has
> >> >> >> >> finished drawing. The
> >> >> >> >> >rest of .NET code looks correct. You might[/color][/color]
> also[color=green][color=darkred]
> >> >> want to
> >> >> >> >> debug your VB6 dll
> >> >> >> >> >to see where it possibly fails.
> >> >> >> >> >
> >> >> >> >> >--
> >> >> >> >> >Dmitriy Lapshin [C# / .NET MVP]
> >> >> >> >> >X-Unity Test Studio
> >> >> >> >> >http://x-unity.miik.com.ua/teststudio.aspx
> >> >> >> >> >Bring the power of unit testing to VS .NET IDE
> >> >> >> >> >
> >> >> >> >> >"Metallicraft"
> >> <anonymous@discussions.microsoft.com>
> >> >> >> >> wrote in message
> >> >> >> >> >news:066e01c3a3a4$58879370$a001280a@phx.gbl...
> >> >> >> >> >> I have a vb6 application. On the main form[/color][/color]
> is a[color=green][color=darkred]
> >> >> >> picture
> >> >> >> >> >> box with one or two images and several[/color][/color]
> pieces[color=green][color=darkred]
> >> of
> >> >> text
> >> >> >> >> >> displayed in it. These are created on the[/color][/color]
> fly[color=green][color=darkred]
> >> >> using
> >> >> >> >> gdi32
> >> >> >> >> >> routines that are all in a referenced,[/color][/color]
> custom[color=green][color=darkred]
> >> >> dll. I
> >> >> >> >> call
> >> >> >> >> >> a PrintImage routine in the dll and pass it
> >> only
> >> >> the
> >> >> >> the
> >> >> >> >> >> Picturebox.hdc from the main form. The dll's
> >> print
> >> >> >> >> routine
> >> >> >> >> >> draws to the hdc and it shows up in the
> >> picturebox
> >> >> >> >> >> perfectly.
> >> >> >> >> >>
> >> >> >> >> >> I would like to do a similar thing with an
> >> asp.net
> >> >> >> page
> >> >> >> >> >> using my same vb6 custom printing dll. Where
> >> >> >> >> Display.aspx
> >> >> >> >> >> has and IMG tag with src="Image.aspx". Now,[/color][/color]
> in[color=green][color=darkred]
> >> the
> >> >> >> >> >> Image.aspx.vb code, I make the necessary[/color][/color]
> calls[color=green][color=darkred]
> >> to
> >> >> my
> >> >> >> dll
> >> >> >> >> >> to preload some data, then I call the
> >> PrintImage
> >> >> >> >> routine.
> >> >> >> >> >> What I get back is a black box. Since it's[/color][/color]
> an[color=green][color=darkred]
> >> >> asp.net
> >> >> >> >> page
> >> >> >> >> >> I don't have a picturebox to draw to (even[/color][/color]
> if I[color=green][color=darkred]
> >> >> did,
> >> >> >> I'm
> >> >> >> >> >> not sure the picturebox's Handle would be[/color][/color]
> the[color=green][color=darkred]
> >> >> same as
> >> >> >> >> >> vb6's hdc). So I'm trying to create a bitmap
> >> >> in .net
> >> >> >> >> where
> >> >> >> >> >> i can eventually get an hdc that I can send[/color][/color]
> to[color=green][color=darkred]
> >> my
> >> >> >> >> printing
> >> >> >> >> >> routine in the vb6 dll. Below is the code I[/color][/color]
> use[color=green][color=darkred]
> >> >> to do
> >> >> >> >> this:
> >> >> >> >> >>
> >> >> >> >> >> Dim bm As Bitmap = New Bitmap(728, 312)
> >> >> >> >> >> Dim gfx As Graphics = Graphics.FromImage(bm)
> >> >> >> >> >> gfx.Clear(Color.White)
> >> >> >> >> >> Dim hDC As IntPtr = gfx.GetHdc()
> >> >> >> >> >> prt.hdc = hDC.ToInt32 'prt.hdc is the[/color][/color]
> property[color=green][color=darkred]
> >> in
> >> >> my
> >> >> >> vb6
> >> >> >> >> >> dll that receives the hdc to print to
> >> >> >> >> >>
> >> >> >> >> >> The code runs without error, I save the[/color][/color]
> bitmap[color=green][color=darkred]
> >> to
> >> >> a
> >> >> >> >> file,
> >> >> >> >> >> read it into a bytearray, and do a
> >> >> >> >> >> Response.Binarywrite...I get a black box[/color][/color]
> (well,[color=green][color=darkred]
> >> >> now I
> >> >> >> >> get
> >> >> >> >> >> a white box since I added the gfx.Clear line
> >> >> above).
> >> >> >> >> >>
> >> >> >> >> >> Why can't my vb6 printing dll draw to a .net
> >> hdc?
> >> >> >> >> >>
> >> >> >> >> >> PS. I eventually don't want to have to save[/color][/color]
> the[color=green][color=darkred]
> >> >> >> bitmap
> >> >> >> >> to
> >> >> >> >> >> a file. If I can get the correct drawing on[/color][/color]
> a[color=green][color=darkred]
> >> >> device
> >> >> >> >> >> context, I'd like to be able to stream that
> >> >> directly
> >> >> >> to
> >> >> >> >> a
> >> >> >> >> >> byte array and do a Response.Binarywrite.
> >> >> >> >> >>
> >> >> >> >> >> If an expert can help with my main issue[/color][/color]
> and my[color=green][color=darkred]
> >> >> PS. I
> >> >> >> >> >> would greatly appreciate it.
> >> >> >> >> >
> >> >> >> >> >.
> >> >> >> >> >
> >> >> >> >
> >> >> >> >.
> >> >> >> >
> >> >> >
> >> >> >.
> >> >> >
> >> >
> >> >.
> >> >[/color]
> >
> >.
> >[/color][/color]

Metallicraft
Guest
 
Posts: n/a
#14: Nov 20 '05

re: Drawing on a .Net device context from a vb6 dll


Ok. I copied all of my code from my aspx page and put it
into my simple .Net Windows app form. I have 1 picturebox
and one button the form. I cleaned the code up (getting
rid of Response.Writes and commenting out writing the
bitmap to a file, etc...) and directed everything to the
picturebox using your "Graphics.FromHwnd" suggestion. I
referenced my vb6 dll (the real one, not the simple one)
and ran the app. It worked! I got what I expected in the
picturebox.

Excellent! And more frustrating than ever...

I need this to happen on an ASPX page. Grrrr..
[color=blue]
>-----Original Message-----[color=green]
>> Is a GRAPHICS.getHdc.ToInt32 an integer representation[/color][/color]
of a[color=blue][color=green]
>> bitmap's hdc? One that VB6 can use...[/color]
>
>Yes, at least theoretically it is. And there are[/color]
some 'BUT's:[color=blue]
>
>1. A bitmap by itself cannot have HDC. In raw GDI terms,[/color]
it can be[color=blue]
>*selected* into some HDC, and then one can perform[/color]
drawing on it or blit it[color=blue]
>to another HDC. The .NET's representation of HDC is the[/color]
Graphics class.[color=blue]
>
>2. I suppose your problem is not related to HDC[/color]
correctness. The code[color=blue]
>snippet you have given in the latest post looks[/color]
absolutely fine - except[color=blue]
>that I'd recommend releasing the HDC *before* you attempt[/color]
to save the[color=blue]
>bitmap. I wonder if you could paste this snippet into a[/color]
simple Windows Forms[color=blue]
>application and test it there first. If it works that[/color]
way, the problem is[color=blue]
>obviously not with the HDC, but with threading I assume.
>
>3. Mind the color depth. The Bitmap instance you've[/color]
created has 32-bit color[color=blue]
>depth by default (unless requested otherwise in the[/color]
constructor) and make[color=blue]
>sure your VB6 DLL can handle such bitmaps right.
>
>--
>Dmitriy Lapshin [C# / .NET MVP]
>X-Unity Test Studio
>http://x-unity.miik.com.ua/teststudio.aspx
>Bring the power of unit testing to VS .NET IDE
>
>"Metallicraft" <anonymous@discussions.microsoft.com>[/color]
wrote in message[color=blue]
>news:0a5601c3a53d$5f9b57b0$a601280a@phx.gbl...[color=green]
>> Let me start off by saying thank you for sticking with[/color][/color]
me[color=blue][color=green]
>> for the last few days, I really appreciate your time.
>>
>> On to your last post....that's great. Now I know how to
>> draw to form and control objects in .net using a gdi32[/color][/color]
api.[color=blue][color=green]
>>
>> However, I tried tweaking what you sent to get a usable
>> hdc from a bitmap and I couldn't.
>>
>> Based on my previous question (and the first thing you
>> responded to in your last post)... Is a
>> GRAPHICS.getHdc.ToInt32 an integer representation of a
>> bitmap's hdc? One that VB6 can use... Remember my
>> original problem:
>>
>> Dim bm As Bitmap = New Bitmap(728, 312)
>> Dim gfx As Graphics = Graphics.FromImage(bm)
>> gfx.Clear(Color.White)
>> Dim gfxhDC As IntPtr = gfx.GetHdc()
>> prt.hdc = gfxhDC.ToInt32
>> prt.Draw
>> bm.Save(sTempFile,
>> System.Drawing.Imaging.ImageFormat.Bmp)
>> bm.Dispose()
>> gfx.ReleaseHdc(gfxhDC)
>>
>> Where prt.hdc is the property in my vb6 dll that holds[/color][/color]
the[color=blue][color=green]
>> device context to draw to and prt.Draw tells the vb6 dll
>> to go ahead and draw its data to the given hdc.
>>[color=darkred]
>> >-----Original Message-----
>> >> where Handle.ToInt32 is the integer representation of[/color]
>> the[color=darkred]
>> >> handle...which is the object's hDc, is this not true?
>> >
>> >Handle.ToInt32 _IS_ the integer representation of a[/color]
>> handle, but Form.Handle[color=darkred]
>> >is a window handle (HWND),
>> >not a GDI device context handle (HDC). To obtain an HDC[/color]
>> for a form or a[color=darkred]
>> >control, you should employ
>> >the Graphics class and contruct it by using the static[/color]
>> FromHwnd method:[color=darkred]
>> >
>> >Dim g AsGraphics = Graphics.FromHwnd(Me.Handle)
>> >
>> >Dim hdc As IntPtr = g.GetHdc()
>> >TextOut(hdc, 100, 100, "TESTING", 7)
>> >g.ReleaseHdc(hdc)
>> >
>> >--
>> >Dmitriy Lapshin [C# / .NET MVP]
>> >X-Unity Test Studio
>> >http://x-unity.miik.com.ua/teststudio.aspx
>> >Bring the power of unit testing to VS .NET IDE
>> >
>> >"Metallicraft" <anonymous@discussions.microsoft.com>[/color]
>> wrote in message[color=darkred]
>> >news:0c4d01c3a47a$26d38e70$a501280a@phx.gbl...
>> >> I understand what you're saying about the HDC and[/color][/color][/color]
HWND,[color=blue][color=green][color=darkred]
>> >> but I thought Handle.ToInt32 was the same as[/color][/color][/color]
Integer...[color=blue][color=green][color=darkred]
>> >> where Handle.ToInt32 is the integer representation of[/color]
>> the[color=darkred]
>> >> handle...which is the object's hDc, is this not true?
>> >>
>> >> When I'd pass a Handle to the TextOut API, I have the[/color]
>> hDc[color=darkred]
>> >> in the TextOut declaration defined as an IntPtr. Are
>> >> Handle and IntPtr different?
>> >>
>> >> If not, how would one declare the TextOut, for[/color][/color][/color]
example,[color=blue][color=green][color=darkred]
>> >> and what would be passed to the hDc parameter?
>> >>
>> >> Maybe that's not important because the REAL dll I'm[/color]
>> trying[color=darkred]
>> >> to get to work cannot be changed. So I need to know[/color][/color][/color]
if[color=blue][color=green]
>> I[color=darkred]
>> >> can pass a .Net-something into a VB6 Long variable[/color][/color][/color]
and[color=blue][color=green][color=darkred]
>> >> have them both be refering to the same hDc.
>> >>
>> >> I understand what you mean about the single-[/color][/color][/color]
threading,[color=blue][color=green]
>> but[color=darkred]
>> >> I'm still not sure where the "<STAThread()>" would[/color][/color][/color]
go or[color=blue][color=green][color=darkred]
>> >> how it's used. I have very little experience dealing[/color]
>> with[color=darkred]
>> >> threads.
>> >>
>> >> >-----Original Message-----
>> >> >Just to be safe: HDC and HWND are NOT the same and[/color][/color][/color]
are[color=blue][color=green][color=darkred]
>> >> NOT interchangeable.
>> >> >And therefore neither of the below will work as it[/color]
>> seems[color=darkred]
>> >> you are passing
>> >> >HWND
>> >> >where HDC is expected.
>> >> >
>> >> >> hDc As IntPtr and TextOut(Me.Handle, etc....
>> >> >>
>> >> >> -AND-
>> >> >>
>> >> >> hDc As Integer and TextOut(Me.Handle.ToInt32,[/color][/color][/color]
etc...[color=blue][color=green][color=darkred]
>> >> >
>> >> >From my experience there's no big difference whether[/color]
>> you[color=darkred]
>> >> declare an API
>> >> >function parameter as Int32 or IntPtr (the latter is
>> >> preferred as you'll
>> >> >avoid explicit type casts in your code) - both ways[/color]
>> work.[color=darkred]
>> >> >
>> >> >> I'm afraid I don't understand your last question
>> >> >> about "[STAThread]".
>> >> >
>> >> >Oops, it's C# syntax. In VB .NET it should look like
>> >> <STAThread()> or
>> >> >something like that. It's an attribute that[/color][/color][/color]
indicated[color=blue][color=green]
>> the[color=darkred]
>> >> application is
>> >> >single-thread and no call to a COM object will be
>> >> originated by a thread
>> >> >other that the main one. This is important to the[/color][/color][/color]
COM[color=blue][color=green][color=darkred]
>> >> subsystem to ensure
>> >> >instantiated COM objects (and your VB6 DLL is an[/color]
>> ActiveX[color=darkred]
>> >> DLL, isn't it?) run
>> >> >in the expected apartment. This is STA in case of[/color][/color][/color]
VB6[color=blue][color=green][color=darkred]
>> >> ActiveX DLLs.
>> >> >
>> >> >--
>> >> >Dmitriy Lapshin [C# / .NET MVP]
>> >> >X-Unity Test Studio
>> >> >http://x-unity.miik.com.ua/teststudio.aspx
>> >> >Bring the power of unit testing to VS .NET IDE
>> >> >
>> >> >"Metallicraft" <anonymous@discussions.microsoft.com>
>> >> wrote in message
>> >> >news:0a9201c3a470$087fc6f0$a601280a@phx.gbl...
>> >> >> Me.Handle refers to the form's handle when I[/color][/color][/color]
tried to[color=blue][color=green][color=darkred]
>> >> just
>> >> >> TextOut to the form instead of a PictureBox. I do
>> >> believe
>> >> >> it's an hWnd. You'll note in the declaration:
>> >> >>
>> >> >>[/color][/color][/color]
<System.Runtime.InteropServices.DllImportAttribu te[color=blue][color=green][color=darkred]
>> >> >> ("gdi32.dll")> _
>> >> >> Private Shared Function TextOut(ByVal hdc As[/color][/color][/color]
IntPtr,[color=blue][color=green][color=darkred]
>> >> >> ByVal X As Integer, ByVal Y As Integer, ByVal
>> >> lpString
>> >> >> As String, ByVal nCount As Integer) As Integer
>> >> >> End Function
>> >> >>
>> >> >> ...hdc is defined as an "IntPtr". I've seen this[/color]
>> done[color=darkred]
>> >> in
>> >> >> many examples with APIs that require an hDc that's
>> >> >> normally a Long type, though I don't understand[/color][/color][/color]
how[color=blue][color=green][color=darkred]
>> >> people
>> >> >> can just change the API declaration like that and[/color]
>> have[color=darkred]
>> >> it
>> >> >> still work (I always thought API declarations were[/color]
>> very[color=darkred]
>> >> >> strict). Nevertheless, I've tried it both ways:
>> >> >>
>> >> >> hDc As IntPtr and TextOut(Me.Handle, etc....
>> >> >>
>> >> >> -AND-
>> >> >>
>> >> >> hDc As Integer and TextOut(Me.Handle.ToInt32,[/color][/color][/color]
etc...[color=blue][color=green][color=darkred]
>> >> >>
>> >> >> Neither work.
>> >> >>
>> >> >> I'm afraid I don't understand your last question
>> >> >> about "[STAThread]".
>> >> >>
>> >> >> >-----Original Message-----
>> >> >> >> I understand that Object.GetHdc is a pointer,[/color][/color][/color]
but[color=blue][color=green]
>> is[color=darkred]
>> >> >> >> Object.GetHdc.ToInt32 the same as a gdi32[/color][/color][/color]
device[color=blue][color=green][color=darkred]
>> >> context
>> >> >> >> or vb6 picturebox.hdc?
>> >> >> >
>> >> >> >Yes, they SHOULD be the same according to MSDN.[/color][/color][/color]
But:[color=blue][color=green][color=darkred]
>> >> >> >
>> >> >> >> ...to the top and in a button_click adding[/color][/color][/color]
this:[color=blue][color=green][color=darkred]
>> >> >> >>
>> >> >> >> TextOut(Me.Handle, 100, 100, "TESTING", 7)
>> >> >> >
>> >> >> >What is Me.Handle here? I suppose it is actually[/color]
>> HWND[color=darkred]
>> >> and
>> >> >> not HDC?
>> >> >> >Does your static Main function is marked as[/color]
>> [STAThread][color=darkred]
>> >> >> by the way?
>> >> >> >
>> >> >> >--
>> >> >> >Dmitriy Lapshin [C# / .NET MVP]
>> >> >> >X-Unity Test Studio
>> >> >> >http://x-unity.miik.com.ua/teststudio.aspx
>> >> >> >Bring the power of unit testing to VS .NET IDE
>> >> >> >
>> >> >> >"Metallicraft"[/color][/color][/color]
<anonymous@discussions.microsoft.com>[color=blue][color=green][color=darkred]
>> >> >> wrote in message
>> >> >> >news:0f8501c3a3bd$44102100$a501280a@phx.gbl...
>> >> >> >> Well, I've tried a couple different things.
>> >> >> >>
>> >> >> >> I created a vb6 dll with the following code:
>> >> >> >>
>> >> >> >> Option Explicit
>> >> >> >>
>> >> >> >> Private Declare Function TextOut Lib "gdi32"
>> >> >> >> Alias "TextOutA" (ByVal hdc As Long, ByVal X As[/color]
>> Long,[color=darkred]
>> >> >> >> ByVal Y As Long, ByVal lpString As String,[/color][/color][/color]
ByVal[color=blue][color=green][color=darkred]
>> >> nCount
>> >> >> As
>> >> >> >> Long) As Long
>> >> >> >>
>> >> >> >> Public Sub DrawText(ByRef hdc As Long)
>> >> >> >> Dim dl As Long
>> >> >> >> dl = TextOut(hdc, 0, 0, "TEST", Len[/color][/color][/color]
("TEST"))[color=blue][color=green][color=darkred]
>> >> >> >> End Sub
>> >> >> >>
>> >> >> >> ...and I compiled it.
>> >> >> >>
>> >> >> >> I then created a vb application (referencing[/color][/color][/color]
that[color=blue][color=green][color=darkred]
>> >> dll)
>> >> >> >> with the following code:
>> >> >> >>
>> >> >> >> Option Explicit
>> >> >> >>
>> >> >> >> Private Sub Form_Load()
>> >> >> >> Picture1.AutoRedraw = True
>> >> >> >>
>> >> >> >> Dim dt As DrawText.clsDrawText
>> >> >> >> Set dt = New DrawText.clsDrawText
>> >> >> >> dt.DrawText (Picture1.hDC)
>> >> >> >>
>> >> >> >> Picture1.Refresh
>> >> >> >> End Sub
>> >> >> >>
>> >> >> >> ...the form contains one picture box.
>> >> >> >>
>> >> >> >> When I run the app, I get the word "TEST" in[/color][/color][/color]
the[color=blue][color=green][color=darkred]
>> >> picture
>> >> >> >> box as I would expect.
>> >> >> >>
>> >> >> >> Next, I created a vb.net Windows app, with only[/color]
>> one[color=darkred]
>> >> >> form,
>> >> >> >> one button, and a picture box. I referenced my
>> >> simple
>> >> >> dll
>> >> >> >> above and the only code exists in the[/color]
>> button_click:[color=darkred]
>> >> >> >>
>> >> >> >> Dim dt As New DrawText.clsDrawTextClass
>> >> >> >> dt.DrawText(PictureBox1.Handle.ToInt32)
>> >> >> >> dt = Nothing
>> >> >> >>
>> >> >> >> PictureBox1.Refresh()
>> >> >> >>
>> >> >> >> ...I run the app, press the button, and get no[/color]
>> text.[color=darkred]
>> >> >> I've
>> >> >> >> tried this with and without the Refresh and[/color][/color][/color]
with[color=blue][color=green]
>> and[color=darkred]
>> >> >> >> without the PictureBox (using the form's handle
>> >> instead)
>> >> >> >> with the same results.
>> >> >> >>
>> >> >> >> I have also tried, in a vb.net app, adding[/color][/color][/color]
this:[color=blue][color=green][color=darkred]
>> >> >> >>
>> >> >> >>
>> >> <System.Runtime.InteropServices.DllImportAttribu te
>> >> >> >> ("gdi32.dll")> _
>> >> >> >> Private Shared Function TextOut(ByVal hdc[/color][/color][/color]
As[color=blue][color=green][color=darkred]
>> >> IntPtr,
>> >> >> >> ByVal X As Integer, ByVal Y As Integer, ByVal
>> >> lpString
>> >> >> As
>> >> >> >> String, ByVal nCount As Integer) As Integer
>> >> >> >> End Function
>> >> >> >>
>> >> >> >> ...to the top and in a button_click adding[/color][/color][/color]
this:[color=blue][color=green][color=darkred]
>> >> >> >>
>> >> >> >> TextOut(Me.Handle, 100, 100, "TESTING", 7)
>> >> >> >>
>> >> >> >> ...running it, pressing button, and getting no[/color]
>> text.[color=darkred]
>> >> >> >>
>> >> >> >> So, even taking my dll and the graphics object[/color]
>> out of[color=darkred]
>> >> >> the
>> >> >> >> equation, I can't get a gdi32 function, like
>> >> TextOut, to
>> >> >> >> write on a .Net device context.
>> >> >> >>
>> >> >> >> I understand that Object.GetHdc is a pointer,[/color][/color][/color]
but[color=blue][color=green]
>> is[color=darkred]
>> >> >> >> Object.GetHdc.ToInt32 the same as a gdi32[/color][/color][/color]
device[color=blue][color=green][color=darkred]
>> >> context
>> >> >> >> or vb6 picturebox.hdc?
>> >> >> >>
>> >> >> >> >-----Original Message-----
>> >> >> >> >You can try calling a raw GDI function through
>> >> P/Invoke
>> >> >> >> on the HDC obtained
>> >> >> >> >and see whether it works that way. If yes,[/color][/color][/color]
you at[color=blue][color=green][color=darkred]
>> >> least
>> >> >> >> know the HDC being
>> >> >> >> >passed is valid.
>> >> >> >> >
>> >> >> >> >There also could be problems with VB6 COM DLL
>> >> running
>> >> >> on
>> >> >> >> a separate thread
>> >> >> >> >(as it runs in the Single-Threaded Apartment[/color][/color][/color]
and[color=blue][color=green][color=darkred]
>> >> >> ASP .NET
>> >> >> >> is
>> >> >> >> >multi-threaded), and I am not sure HDCs can be
>> >> >> passed "as
>> >> >> >> is" between
>> >> >> >> >threads.
>> >> >> >> >
>> >> >> >> >--
>> >> >> >> >Dmitriy Lapshin [C# / .NET MVP]
>> >> >> >> >X-Unity Test Studio
>> >> >> >> >http://x-unity.miik.com.ua/teststudio.aspx
>> >> >> >> >Bring the power of unit testing to VS .NET IDE
>> >> >> >> >
>> >> >> >> >"Metallicraft"[/color]
>> <anonymous@discussions.microsoft.com>[color=darkred]
>> >> >> >> wrote in message
>> >> >> >> >news:083501c3a3af$6ff09d30$a001280a@phx.gbl...
>> >> >> >> >> Thanks for responding.
>> >> >> >> >>
>> >> >> >> >> I dispose of my bitmap and release the dc[/color]
>> after I[color=darkred]
>> >> >> write
>> >> >> >> >> the bitmap to a file further down in the[/color]
>> code. I[color=darkred]
>> >> >> know
>> >> >> >> the
>> >> >> >> >> vb6 dll works in vb6. The vb6 dll is[/color]
>> production[color=darkred]
>> >> >> >> software
>> >> >> >> >> already working in the hands of hundreds of
>> >> clients.
>> >> >> >> >>
>> >> >> >> >> I can do a:
>> >> >> >> >>
>> >> >> >> >> gfx.DrawString("test", New Font[/color]
>> ("Arial",[color=darkred]
>> >> >> 24.0F),
>> >> >> >> >> Brushes.Black, 0, 0)
>> >> >> >> >> gfx.DrawRectangle(New Pen[/color][/color][/color]
(Color.Black),[color=blue][color=green][color=darkred]
>> >> New
>> >> >> >> >> Rectangle(2, 1, 725, 309))
>> >> >> >> >>
>> >> >> >> >> ...inside vb.net and get a bitmap with text[/color]
>> and a[color=darkred]
>> >> >> >> >> rectangle, but when passing the graphic's[/color][/color][/color]
hdc[color=blue][color=green][color=darkred]
>> >> >> >> >> (Graphic.GetHdc.ToInt32) I get no drawing
>> >> whatsoever
>> >> >> >> from
>> >> >> >> >> the vb6 dll.
>> >> >> >> >>
>> >> >> >> >> >-----Original Message-----
>> >> >> >> >> >Hi,
>> >> >> >> >> >
>> >> >> >> >> >You can try calling ReleaseDC after the VB6[/color]
>> dll[color=darkred]
>> >> has
>> >> >> >> >> finished drawing. The
>> >> >> >> >> >rest of .NET code looks correct. You might[/color]
>> also[color=darkred]
>> >> >> want to
>> >> >> >> >> debug your VB6 dll
>> >> >> >> >> >to see where it possibly fails.
>> >> >> >> >> >
>> >> >> >> >> >--
>> >> >> >> >> >Dmitriy Lapshin [C# / .NET MVP]
>> >> >> >> >> >X-Unity Test Studio
>> >> >> >> >> >http://x-unity.miik.com.ua/teststudio.aspx
>> >> >> >> >> >Bring the power of unit testing to VS .NET[/color][/color][/color]
IDE[color=blue][color=green][color=darkred]
>> >> >> >> >> >
>> >> >> >> >> >"Metallicraft"
>> >> <anonymous@discussions.microsoft.com>
>> >> >> >> >> wrote in message
>> >> >> >> >> >news:066e01c3a3a4$58879370[/color][/color][/color]
$a001280a@phx.gbl...[color=blue][color=green][color=darkred]
>> >> >> >> >> >> I have a vb6 application. On the main[/color][/color][/color]
form[color=blue][color=green]
>> is a[color=darkred]
>> >> >> >> picture
>> >> >> >> >> >> box with one or two images and several[/color]
>> pieces[color=darkred]
>> >> of
>> >> >> text
>> >> >> >> >> >> displayed in it. These are created on the[/color]
>> fly[color=darkred]
>> >> >> using
>> >> >> >> >> gdi32
>> >> >> >> >> >> routines that are all in a referenced,[/color]
>> custom[color=darkred]
>> >> >> dll. I
>> >> >> >> >> call
>> >> >> >> >> >> a PrintImage routine in the dll and pass[/color][/color][/color]
it[color=blue][color=green][color=darkred]
>> >> only
>> >> >> the
>> >> >> >> the
>> >> >> >> >> >> Picturebox.hdc from the main form. The[/color][/color][/color]
dll's[color=blue][color=green][color=darkred]
>> >> print
>> >> >> >> >> routine
>> >> >> >> >> >> draws to the hdc and it shows up in the
>> >> picturebox
>> >> >> >> >> >> perfectly.
>> >> >> >> >> >>
>> >> >> >> >> >> I would like to do a similar thing with[/color][/color][/color]
an[color=blue][color=green][color=darkred]
>> >> asp.net
>> >> >> >> page
>> >> >> >> >> >> using my same vb6 custom printing dll.[/color][/color][/color]
Where[color=blue][color=green][color=darkred]
>> >> >> >> >> Display.aspx
>> >> >> >> >> >> has and IMG tag with src="Image.aspx".[/color][/color][/color]
Now,[color=blue][color=green]
>> in[color=darkred]
>> >> the
>> >> >> >> >> >> Image.aspx.vb code, I make the necessary[/color]
>> calls[color=darkred]
>> >> to
>> >> >> my
>> >> >> >> dll
>> >> >> >> >> >> to preload some data, then I call the
>> >> PrintImage
>> >> >> >> >> routine.
>> >> >> >> >> >> What I get back is a black box. Since[/color][/color][/color]
it's[color=blue][color=green]
>> an[color=darkred]
>> >> >> asp.net
>> >> >> >> >> page
>> >> >> >> >> >> I don't have a picturebox to draw to[/color][/color][/color]
(even[color=blue][color=green]
>> if I[color=darkred]
>> >> >> did,
>> >> >> >> I'm
>> >> >> >> >> >> not sure the picturebox's Handle would be[/color]
>> the[color=darkred]
>> >> >> same as
>> >> >> >> >> >> vb6's hdc). So I'm trying to create a[/color][/color][/color]
bitmap[color=blue][color=green][color=darkred]
>> >> >> in .net
>> >> >> >> >> where
>> >> >> >> >> >> i can eventually get an hdc that I can[/color][/color][/color]
send[color=blue][color=green]
>> to[color=darkred]
>> >> my
>> >> >> >> >> printing
>> >> >> >> >> >> routine in the vb6 dll. Below is the[/color][/color][/color]
code I[color=blue][color=green]
>> use[color=darkred]
>> >> >> to do
>> >> >> >> >> this:
>> >> >> >> >> >>
>> >> >> >> >> >> Dim bm As Bitmap = New Bitmap(728, 312)
>> >> >> >> >> >> Dim gfx As Graphics = Graphics.FromImage[/color][/color][/color]
(bm)[color=blue][color=green][color=darkred]
>> >> >> >> >> >> gfx.Clear(Color.White)
>> >> >> >> >> >> Dim hDC As IntPtr = gfx.GetHdc()
>> >> >> >> >> >> prt.hdc = hDC.ToInt32 'prt.hdc is the[/color]
>> property[color=darkred]
>> >> in
>> >> >> my
>> >> >> >> vb6
>> >> >> >> >> >> dll that receives the hdc to print to
>> >> >> >> >> >>
>> >> >> >> >> >> The code runs without error, I save the[/color]
>> bitmap[color=darkred]
>> >> to
>> >> >> a
>> >> >> >> >> file,
>> >> >> >> >> >> read it into a bytearray, and do a
>> >> >> >> >> >> Response.Binarywrite...I get a black box[/color]
>> (well,[color=darkred]
>> >> >> now I
>> >> >> >> >> get
>> >> >> >> >> >> a white box since I added the gfx.Clear[/color][/color][/color]
line[color=blue][color=green][color=darkred]
>> >> >> above).
>> >> >> >> >> >>
>> >> >> >> >> >> Why can't my vb6 printing dll draw to[/color][/color][/color]
a .net[color=blue][color=green][color=darkred]
>> >> hdc?
>> >> >> >> >> >>
>> >> >> >> >> >> PS. I eventually don't want to have to[/color][/color][/color]
save[color=blue][color=green]
>> the[color=darkred]
>> >> >> >> bitmap
>> >> >> >> >> to
>> >> >> >> >> >> a file. If I can get the correct drawing[/color][/color][/color]
on[color=blue][color=green]
>> a[color=darkred]
>> >> >> device
>> >> >> >> >> >> context, I'd like to be able to stream[/color][/color][/color]
that[color=blue][color=green][color=darkred]
>> >> >> directly
>> >> >> >> to
>> >> >> >> >> a
>> >> >> >> >> >> byte array and do a Response.Binarywrite.
>> >> >> >> >> >>
>> >> >> >> >> >> If an expert can help with my main issue[/color]
>> and my[color=darkred]
>> >> >> PS. I
>> >> >> >> >> >> would greatly appreciate it.
>> >> >> >> >> >
>> >> >> >> >> >.
>> >> >> >> >> >
>> >> >> >> >
>> >> >> >> >.
>> >> >> >> >
>> >> >> >
>> >> >> >.
>> >> >> >
>> >> >
>> >> >.
>> >> >
>> >
>> >.
>> >[/color][/color]
>
>.
>[/color]
Closed Thread