Hi, The graphics class has a gethdc method. You could create a new bitmap and create a graphics object to the bitmap and get its hdc that way. Wouldn't it just be easier to use the drawstring method of the graphics class. http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemdrawinggraphicsclassgethdctopic.asp http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemdrawinggraphicsclassdrawstringtopic4.asp Dim bm As New Bitmap(200, 200) Dim g As Graphics = Graphics.FromImage(bm) g.FillRectangle(SystemBrushes.Control, 0, 0, 200, 200) g.DrawString("Hello, world", Me.Font, Brushes.Black, 10, 10) picGraphics.Image = bm g.Dispose() Ken ---------------------------- "Benjamin Lukner" <Benjamin.Lukner_at_trinomix.de@mp3mounter.de> wrote in message news:uzyBBPk6DHA.3860@tk2msftngp13.phx.gbl... [quoted text, click to view] > Hi again! > > I've spent a whole day on tryining to get ExtTextOutW to work. > > I've found out a lot of things, and it works in VB6 with ExtTextOutA, > but I still have problems on VB.Net. > > It's not possible to pass the font to the function. > In VB6, the function uses the font and colors of the PictureBox control. > In VB.Net, it always writes Sans Serif with white background. > I can change the text color with SetTextColor. > > VB.Net does not provide the hDC like VB6, so I used GetDC with the handle > of my control. > Nevertheless I'd like to use a double buffered control and print on a > bitmap, not on the control. > > Does anyone have an idea how to do this? > > My code trials so far: > > Inherits Control > > Private Structure RECT > Public Left As Int32 > Public Top As Int32 > Public Right As Int32 > Public Bottom As Int32 > End Structure > > Const ETO_GRAYED = 1 > Const ETO_OPAQUE = 2 > Const ETO_CLIPPED = 4 > > Private Declare Function ExtTextOut Lib "gdi32" Alias "ExtTextOutW" ( _ > ByVal hdc As IntPtr, _ > ByVal x As Int32, _ > ByVal y As Int32, _ > ByVal wOptions As Int32, _ > ByRef lpRect As RECT, _ > ByVal lpString() As Byte, _ > ByVal nCount As Int32, _ > ByRef lpDx As Int32 _ > ) As Int32 > > Private Declare Function SetTextColor Lib "gdi32" Alias "SetTextColor" ( _ > ByVal hdc As IntPtr, _ > ByVal crColor As Int32 _ > ) As Int32 > > Private Declare Function GetDC Lib "user32" Alias "GetDC" ( _ > ByVal hwnd As IntPtr _ > ) As IntPtr > > Private Declare Function ReleaseDC Lib "user32" Alias "ReleaseDC" ( _ > ByVal hwnd As IntPtr, _ > ByVal hdc As IntPtr _ > ) As Int32 > > > > Public Sub WriteText(ByVal sText As String, _ > ByVal iRow As Integer, _ > ByVal iCol As Integer) > > Dim uRect As RECT > Dim iWidth As Int32 > Dim iHeight As Int32 > Dim iStruct() As Int32 > Dim iIndex As Int32 > Dim iLength As Int32 > Dim hDC As IntPtr > > Dim oFont As System.Drawing.Font = _ > New System.Drawing.Font( _ > "Courier New", _ > nFontSize, _ > FontStyle.Regular) > > Dim oSize As System.Drawing.SizeF > > oSize = _graphics.MeasureString("W", oFont, oOrigin, oFormat) > > iLength = Len(sText) > iWidth = oSize.Width > iHeight = oSize.Height > > uRect.Left = (iCol - 1) * iWidth > uRect.Top = (iRow - 1) * iHeight > uRect.Right = uRect.Left + iLength * iWidth > uRect.Bottom = uRect.Top + iHeight > > ReDim iStruct(iLength) > > For iIndex = 0 To iLength > iStruct(iIndex) = iWidth > Next > > hDC = GetDC(Me.Handle) > SetTextColor(hDC, RGB(222, 0, 0)) > ExtTextOut(hDC, uRect.Left, uRect.Top, ETO_CLIPPED, uRect, _ > System.Text.Encoding.Unicode.GetBytes(sText), iLength, iStruct(0)) > ReleaseDC(Me.Handle, hDC) > > End Sub > > > > Kind regards, > > Benjamin Lukner
Hi again! I've spent a whole day on tryining to get ExtTextOutW to work. I've found out a lot of things, and it works in VB6 with ExtTextOutA, but I still have problems on VB.Net. It's not possible to pass the font to the function. In VB6, the function uses the font and colors of the PictureBox control. In VB.Net, it always writes Sans Serif with white background. I can change the text color with SetTextColor. VB.Net does not provide the hDC like VB6, so I used GetDC with the handle of my control. Nevertheless I'd like to use a double buffered control and print on a bitmap, not on the control. Does anyone have an idea how to do this? My code trials so far: Inherits Control Private Structure RECT Public Left As Int32 Public Top As Int32 Public Right As Int32 Public Bottom As Int32 End Structure Const ETO_GRAYED = 1 Const ETO_OPAQUE = 2 Const ETO_CLIPPED = 4 Private Declare Function ExtTextOut Lib "gdi32" Alias "ExtTextOutW" ( _ ByVal hdc As IntPtr, _ ByVal x As Int32, _ ByVal y As Int32, _ ByVal wOptions As Int32, _ ByRef lpRect As RECT, _ ByVal lpString() As Byte, _ ByVal nCount As Int32, _ ByRef lpDx As Int32 _ ) As Int32 Private Declare Function SetTextColor Lib "gdi32" Alias "SetTextColor" ( _ ByVal hdc As IntPtr, _ ByVal crColor As Int32 _ ) As Int32 Private Declare Function GetDC Lib "user32" Alias "GetDC" ( _ ByVal hwnd As IntPtr _ ) As IntPtr Private Declare Function ReleaseDC Lib "user32" Alias "ReleaseDC" ( _ ByVal hwnd As IntPtr, _ ByVal hdc As IntPtr _ ) As Int32 Public Sub WriteText(ByVal sText As String, _ ByVal iRow As Integer, _ ByVal iCol As Integer) Dim uRect As RECT Dim iWidth As Int32 Dim iHeight As Int32 Dim iStruct() As Int32 Dim iIndex As Int32 Dim iLength As Int32 Dim hDC As IntPtr Dim oFont As System.Drawing.Font = _ New System.Drawing.Font( _ "Courier New", _ nFontSize, _ FontStyle.Regular) Dim oSize As System.Drawing.SizeF oSize = _graphics.MeasureString("W", oFont, oOrigin, oFormat) iLength = Len(sText) iWidth = oSize.Width iHeight = oSize.Height uRect.Left = (iCol - 1) * iWidth uRect.Top = (iRow - 1) * iHeight uRect.Right = uRect.Left + iLength * iWidth uRect.Bottom = uRect.Top + iHeight ReDim iStruct(iLength) For iIndex = 0 To iLength iStruct(iIndex) = iWidth Next hDC = GetDC(Me.Handle) SetTextColor(hDC, RGB(222, 0, 0)) ExtTextOut(hDC, uRect.Left, uRect.Top, ETO_CLIPPED, uRect, _ System.Text.Encoding.Unicode.GetBytes(sText), iLength, iStruct(0)) ReleaseDC(Me.Handle, hDC) End Sub Kind regards,
[quoted text, click to view] Ken Tucker [MVP] wrote: > The graphics class has a gethdc method. You could create a new > bitmap and create a graphics object to the bitmap and get its hdc that way. > Wouldn't it just be easier to use the drawstring method of the graphics > class.
LAST (so I hope) QUESTIONS: - How do I select the font?? I still found no API call [IMPORTANT!]. hDC = _graphics.GetHdc SetTextColor(hDC, ToRgb(System.Drawing.Color.DarkRed)) SetBkColor(hDC, ToRgb(System.Drawing.Color.SteelBlue)) ExtTextOut(hDC, uRect.Left, uRect.Top, ETO_CLIPPED, uRect, _ System.Text.Encoding.Unicode.GetBytes(sText), iLength, iStruct(0)) _graphics.ReleaseHdc(hDC) Less important: - How do I print text with transparent background? (SetBkColor to the current backcolor didn't help. I did not state ETO_OPAQUE.) - Which API call do I use to get the size of a single letter of a specific font, rendition and size? Anyway (questions above because I was afraid that they could be overseen *g*) : Thanks! :-) I relied on the popup menu of .NET, but it doesn't show GetHdc and ReleaseHdc... And of course I'd like to use DrawString (what works fine on Pocket PC), but it renders text with spaces of varying width. http://support.microsoft.com/default.aspx?scid=kb;en-us;307208 mentions in paragraph "How to display adjacent text" to use _GenericTypographic_ and _TextRenderingHintAntiAlias_ for editor-like applications, but I still got spaces of 1 AND 2 pixels width in a printed text. I posted it with subject 'DrawString and "real" fixed width' last week. The default answer for this problem is to use GDI / ExtTextOut instead of GDI+ / DrawString. So I did it. Kind regards,
I just got an eMail explaining how to select the font via CreateFont and SelectObject. Oh happy day! If someone needs it, tell me. At the moment I'm still converting the example code from VB6 to VB.Net. So there are only the less important questions left: - How do I print text with transparent background? (SetBkColor to the current backcolor didn't help. I did not state ETO_OPAQUE.) - Which API call do I use to get the size of a single letter of a specific font, rendition and size? Kind regards,
[quoted text, click to view] >- How do I print text with transparent background? (SetBkColor to the >current backcolor didn't help. I did not state ETO_OPAQUE.)
SetBkMode(hdc, TRANSPARENT) [quoted text, click to view] >- Which API call do I use to get the size of a single letter of a >specific font, rendition and size?
Not sure, but perhaps GetGlyphOutline does what you want. Mattias -- Mattias Sjögren [MVP] mattias @ mvps.org http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Actually your use of ExTextOut will get more interesting if you try to double buffer using a Graphics object created from a Bitmap. This is a problem a I am still working to resolve, but first let me explain. If you do the following: ' Create Memory Bitmap (I think it makes a DIB or DIB Section) as the basis for the Graphics object Dim buffer As Bitmap = New Bitmap(Panel1.Width, Panel1.Height, Drawing.Imaging.PixelFormat.Format32bppPArgb) ' Create the graphics object from the bitmap. Dim g As Graphics = Graphics.FromImage(buffer) ' Get the device context to the graphics object, to use with Win32 Calls Dim hDC As IntPtr = g.GetHdc() ' GetHFont is a function I wrote which returns a handle to a font (win32 style) from a .NET font object ' the font is created to be PROOF_QUALITY Dim hFont As IntPtr = TextDrawControl1.GetHFont(New Font("Times New Roman", 16, FontStyle.Bold), hDC) 'Win32Wrapper just declares the Win32 calls (using the names from gdi32.dll and user32.dll) Win32Wrapper.SelectObject(hDC, hFont) ' This is part of the problem as best as I can tell Win32Wrapper.SetBkMode(hDC, Win32Wrapper.TRANSPARENT) Win32Wrapper.SetBkColor(hDC, New Win32Wrapper.RGB(0, 0, 255)) Win32Wrapper.SetTextColor(hDC, New Win32Wrapper.RGB(255, 0, 0)) ' Text is drawn to the buffer, but you'll notice that it looks jagged. ' closer inspection reveals that the antialiasing was not performed on a background ' consisting of the same color as whatever G had- even if you call g.FillRect.... ' In summary, GDI seems to draw the text using a black background and then performs ' the antialiasing, which looks horrible on any other color of background. Win32Wrapper.ExtTextOut(hDC, 0, 0, 0, Nothing, "Hello World", "Hello World".Length, Nothing) g.ReleaseHdc(hDC) ' As would be necessary for a double buffer, blit the buffer into a visible control Dim destG As Graphics = Panel1.CreateGraphics() destG.DrawImageUnscaled(buffer, 0, 0) destG.Dispose() g.Dispose() buffer.Dispose() If you read through the comments in the above source you should understand the problem, GDI doesn't know what to use to antilias with when the BKMODE is transparent and the Bitmap was not created by GDI directly. My workaround to get nice, sharp text from the buffer is to NOT create the buffer in .NET but to use straight GDI. Instead do this to get the buffer: Dim compHDC As IntPtr = Win32Wrapper.GetDC(Nothing) ' Uses the screen as a basis Dim memDC As IntPtr = Win32Wrapper.CreateCompatibleDC(compHDC) 'Create Memory Device Context Dim hBitmap As IntPtr = Win32Wrapper.CreateCompatibleBitmap(compHDC, Panel1.Width, Panel1.Height) 'Make BMP Win32Wrapper.SelectObject(memDC, hBitmap) ' associate the bitmap with the memDC then simly do the following to get your bitmap backed Graphics object: Dim g As Graphics = Graphics.FromHdc(memDC) Your text drawing will appear smooth, because somehow it is very capable of getting the correct background color information and thus performing antialiasing correctly.
Don't see what you're looking for? Try a search.
|