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. 13 3123
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" <an*******@discussions.microsoft.com> wrote in message
news:06****************************@phx.gbl... 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.
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. -----Original Message----- Hi,
You can try calling ReleaseDC after the VB6 dll has
finished drawing. Therest of .NET code looks correct. You might also want to
debug your VB6 dllto 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" <an*******@discussions.microsoft.com>
wrote in messagenews:06****************************@phx.gbl... 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.
.
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" <an*******@discussions.microsoft.com> wrote in message
news:08****************************@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 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.
-----Original Message----- Hi,
You can try calling ReleaseDC after the VB6 dll has finished drawing. Therest of .NET code looks correct. You might also want to debug your VB6 dllto 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" <an*******@discussions.microsoft.com> wrote in messagenews:06****************************@phx.gbl... 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.
.
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? -----Original Message----- You can try calling a raw GDI function through P/Invoke
on the HDC obtainedand see whether it works that way. If yes, you at least
know the HDC beingpassed 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
ismulti-threaded), and I am not sure HDCs can be passed "as
is" betweenthreads.
-- 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" <an*******@discussions.microsoft.com>
wrote in messagenews:08****************************@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 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.
>-----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" <an*******@discussions.microsoft.com> wrote in message >news:06****************************@phx.gbl... >> 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. > >. >
.
> I understand that Object.GetHdc is a pointer, but is 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 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" <an*******@discussions.microsoft.com> wrote in message
news:0f****************************@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 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?
-----Original Message----- You can try calling a raw GDI function through P/Invoke on the HDC obtainedand see whether it works that way. If yes, you at least know the HDC beingpassed 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 ismulti-threaded), and I am not sure HDCs can be passed "as is" betweenthreads.
-- 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" <an*******@discussions.microsoft.com> wrote in messagenews:08****************************@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 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.
>-----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" <an*******@discussions.microsoft.com> wrote in message >news:06****************************@phx.gbl... >> 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. > >. >
.
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]". -----Original Message----- I understand that Object.GetHdc is a pointer, but is 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 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" <an*******@discussions.microsoft.com>
wrote in messagenews:0f****************************@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 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?
>-----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" <an*******@discussions.microsoft.com> wrote in message >news:08****************************@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 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. >> >> >-----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" <an*******@discussions.microsoft.com> >> wrote in message >> >news:06****************************@phx.gbl... >> >> 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. >> > >> >. >> > > >. >
.
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. 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 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.
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 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" <an*******@discussions.microsoft.com> wrote in message
news:0a****************************@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 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]".
-----Original Message----- I understand that Object.GetHdc is a pointer, but is 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 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" <an*******@discussions.microsoft.com>
wrote in messagenews:0f****************************@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 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?
>-----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" <an*******@discussions.microsoft.com> wrote in message >news:08****************************@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 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. >> >> >-----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" <an*******@discussions.microsoft.com> >> wrote in message >> >news:06****************************@phx.gbl... >> >> 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. >> > >> >. >> > > >. >
.
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. -----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 seems
you are passingHWND 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 you
declare an APIfunction parameter as Int32 or IntPtr (the latter is
preferred as you'llavoid explicit type casts in your code) - both ways work.
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()> orsomething like that. It's an attribute that indicated the
application issingle-thread and no call to a COM object will be
originated by a threadother that the main one. This is important to the COM
subsystem to ensureinstantiated COM objects (and your VB6 DLL is an ActiveX
DLL, isn't it?) runin 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" <an*******@discussions.microsoft.com>
wrote in messagenews:0a****************************@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 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]".
>-----Original Message----- >> I understand that Object.GetHdc is a pointer, but is >> 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 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" <an*******@discussions.microsoft.com> wrote in message >news:0f****************************@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
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? >> >> >-----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" <an*******@discussions.microsoft.com> >> wrote in message >> >news:08****************************@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
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. >> >> >> >> >-----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"
<an*******@discussions.microsoft.com> >> >> wrote in message >> >> >news:06****************************@phx.gbl... >> >> >> 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. >> >> > >> >> >. >> >> > >> > >> >. >> > > >. >
.
> where Handle.ToInt32 is the integer representation of the handle...which is the object's hDc, is this not true?
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" <an*******@discussions.microsoft.com> wrote in message
news:0c****************************@phx.gbl... 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.
-----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 seems you are passingHWND 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 you declare an APIfunction parameter as Int32 or IntPtr (the latter is preferred as you'llavoid explicit type casts in your code) - both ways work.
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()> orsomething like that. It's an attribute that indicated the application issingle-thread and no call to a COM object will be originated by a threadother that the main one. This is important to the COM subsystem to ensureinstantiated COM objects (and your VB6 DLL is an ActiveX DLL, isn't it?) runin 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" <an*******@discussions.microsoft.com>
wrote in messagenews:0a****************************@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 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]".
>-----Original Message----- >> I understand that Object.GetHdc is a pointer, but is >> 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 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" <an*******@discussions.microsoft.com> wrote in message >news:0f****************************@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 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? >> >> >-----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" <an*******@discussions.microsoft.com> >> wrote in message >> >news:08****************************@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 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. >> >> >> >> >-----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" <an*******@discussions.microsoft.com> >> >> wrote in message >> >> >news:06****************************@phx.gbl... >> >> >> 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. >> >> > >> >> >. >> >> > >> > >> >. >> > > >. >
.
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. -----Original Message----- where Handle.ToInt32 is the integer representation of
the handle...which is the object's hDc, is this not true? Handle.ToInt32 _IS_ the integer representation of a
handle, but Form.Handleis a window handle (HWND), not a GDI device context handle (HDC). To obtain an HDC
for a form or acontrol, 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" <an*******@discussions.microsoft.com>
wrote in messagenews:0c****************************@phx.gbl... 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.
>-----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
seems 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
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. > >> 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
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" <an*******@discussions.microsoft.com> wrote in message >news:0a****************************@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
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]". >> >> >-----Original Message----- >> >> I understand that Object.GetHdc is a pointer, but
is >> >> 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
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" <an*******@discussions.microsoft.com> >> wrote in message >> >news:0f****************************@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 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? >> >> >> >> >-----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"
<an*******@discussions.microsoft.com> >> >> wrote in message >> >> >news:08****************************@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 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. >> >> >> >> >> >> >-----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" <an*******@discussions.microsoft.com> >> >> >> wrote in message >> >> >> >news:06****************************@phx.gbl... >> >> >> >> 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. >> >> >> > >> >> >> >. >> >> >> > >> >> > >> >> >. >> >> > >> > >> >. >> > > >. >
.
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). -----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
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
thedevice context to draw to and prt.Draw tells the vb6 dll to go ahead and draw its data to the given hdc.
-----Original Message----- where Handle.ToInt32 is the integer representation ofthe handle...which is the object's hDc, is this not true? Handle.ToInt32 _IS_ the integer representation of a handle, but Form.Handleis a window handle (HWND), not a GDI device context handle (HDC). To obtain an HDC for a form or acontrol, 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" <an*******@discussions.microsoft.com>
wrote in messagenews:0c****************************@phx.gbl... 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 ofthe handle...which is the object's hDc, is this not true?
When I'd pass a Handle to the TextOut API, I have thehDc 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'mtrying to get to work cannot be changed. So I need to know
ifI 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.
>-----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 itseems 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 whetheryou declare an API >function parameter as Int32 or IntPtr (the latter is preferred as you'll >avoid explicit type casts in your code) - both wayswork. > >> 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 indicatedthe 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 anActiveX 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" <an*******@discussions.microsoft.com> wrote in message >news:0a****************************@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 thisdone 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 andhave it >> still work (I always thought API declarations werevery >> 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,
butis >> >> 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 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"
<an*******@discussions.microsoft.com> >> wrote in message >> >news:0f****************************@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 AsLong, >> >> 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 onlyone >> form, >> >> one button, and a picture box. I referenced my simple >> dll >> >> above and the only code exists in thebutton_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 notext. >> I've >> >> tried this with and without the Refresh and withand >> >> 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 notext. >> >> >> >> So, even taking my dll and the graphics objectout 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,
butis >> >> 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" <an*******@discussions.microsoft.com> >> >> wrote in message >> >> >news:08****************************@phx.gbl... >> >> >> Thanks for responding. >> >> >> >> >> >> I dispose of my bitmap and release the dcafter I >> write >> >> >> the bitmap to a file further down in thecode. I >> know >> >> the >> >> >> vb6 dll works in vb6. The vb6 dll isproduction >> >> 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 textand 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 VB6dll has >> >> >> finished drawing. The >> >> >> >rest of .NET code looks correct. You mightalso >> 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" <an*******@discussions.microsoft.com> >> >> >> wrote in message >> >> >> >news:066e01c3a3a4$58879370
$a*******@phx.gbl... >> >> >> >> I have a vb6 application. On the main formis a >> >> picture >> >> >> >> box with one or two images and severalpieces of >> text >> >> >> >> displayed in it. These are created on thefly >> 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 necessarycalls to >> my >> >> dll >> >> >> >> to preload some data, then I call the PrintImage >> >> >> routine. >> >> >> >> What I get back is a black box. Since it'san >> asp.net >> >> >> page >> >> >> >> I don't have a picturebox to draw to (evenif I >> did, >> >> I'm >> >> >> >> not sure the picturebox's Handle would bethe >> 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
sendto my >> >> >> printing >> >> >> >> routine in the vb6 dll. Below is the code
Iuse >> 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 thebitmap 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
savethe >> >> bitmap >> >> >> to >> >> >> >> a file. If I can get the correct drawing
ona >> 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 issueand my >> PS. I >> >> >> >> would greatly appreciate it. >> >> >> > >> >> >> >. >> >> >> > >> >> > >> >> >. >> >> > >> > >> >. >> > > >. >
. .
> Is a GRAPHICS.getHdc.ToInt32 an integer representation of a bitmap's hdc? One that VB6 can use...
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" <an*******@discussions.microsoft.com> wrote in message
news:0a****************************@phx.gbl... 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.
-----Original Message----- where Handle.ToInt32 is the integer representation of the handle...which is the object's hDc, is this not true?
Handle.ToInt32 _IS_ the integer representation of a handle, but Form.Handleis a window handle (HWND), not a GDI device context handle (HDC). To obtain an HDC for a form or acontrol, 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" <an*******@discussions.microsoft.com>
wrote in messagenews:0c****************************@phx.gbl... 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.
>-----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 seems 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 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. > >> 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 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" <an*******@discussions.microsoft.com> wrote in message >news:0a****************************@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 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]". >> >> >-----Original Message----- >> >> I understand that Object.GetHdc is a pointer, but is >> >> 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 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" <an*******@discussions.microsoft.com> >> wrote in message >> >news:0f****************************@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 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? >> >> >> >> >-----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" <an*******@discussions.microsoft.com> >> >> wrote in message >> >> >news:08****************************@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 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. >> >> >> >> >> >> >-----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" <an*******@discussions.microsoft.com> >> >> >> wrote in message >> >> >> >news:06****************************@phx.gbl... >> >> >> >> 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. >> >> >> > >> >> >> >. >> >> >> > >> >> > >> >> >. >> >> > >> > >> >. >> > > >. >
.
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.. -----Original Message----- Is a GRAPHICS.getHdc.ToInt32 an integer representation
of a bitmap's hdc? One that VB6 can use... 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 itto another HDC. The .NET's representation of HDC is the
Graphics class. 2. I suppose your problem is not related to HDC
correctness. The codesnippet you have given in the latest post looks
absolutely fine - exceptthat I'd recommend releasing the HDC *before* you attempt
to save thebitmap. I wonder if you could paste this snippet into a
simple Windows Formsapplication and test it there first. If it works that
way, the problem isobviously not with the HDC, but with threading I assume.
3. Mind the color depth. The Bitmap instance you've
created has 32-bit colordepth by default (unless requested otherwise in the
constructor) and makesure 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" <an*******@discussions.microsoft.com>
wrote in messagenews:0a****************************@phx.gbl... 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.
>-----Original Message----- >> where Handle.ToInt32 is the integer representation of the >> handle...which is the object's hDc, is this not true? > >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" <an*******@discussions.microsoft.com> wrote in message >news:0c****************************@phx.gbl... >> 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. >> >> >-----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 seems >> 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 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. >> > >> >> 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 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" <an*******@discussions.microsoft.com> >> wrote in message >> >news:0a****************************@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 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]". >> >> >> >> >-----Original Message----- >> >> >> I understand that Object.GetHdc is a pointer,
but is >> >> >> 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 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"
<an*******@discussions.microsoft.com> >> >> wrote in message >> >> >news:0f****************************@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 >> 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? >> >> >> >> >> >> >-----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" <an*******@discussions.microsoft.com> >> >> >> wrote in message >> >> >> >news:08****************************@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 >> 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. >> >> >> >> >> >> >> >> >-----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" >> <an*******@discussions.microsoft.com> >> >> >> >> wrote in message >> >> >> >> >news:066e01c3a3a4$58879370
$a*******@phx.gbl... >> >> >> >> >> 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. >> >> >> >> > >> >> >> >> >. >> >> >> >> > >> >> >> > >> >> >> >. >> >> >> > >> >> > >> >> >. >> >> > >> > >> >. >> > > >. >
. This discussion thread is closed Replies have been disabled for this discussion. Similar topics
2 posts
views
Thread by matt |
last post: by
|
1 post
views
Thread by Abd |
last post: by
|
reply
views
Thread by sachin |
last post: by
|
4 posts
views
Thread by Peter Oliphant |
last post: by
|
9 posts
views
Thread by davetelling |
last post: by
|
8 posts
views
Thread by Joergen Bech |
last post: by
| |
6 posts
views
Thread by =?Utf-8?B?bmNvbG9zaQ==?= |
last post: by
| | | | | | | | | | | |