How can I get the printer HDC - vb.net

I have a COM component written in C++ that has a Print function. This print function takes the Printer hDC as a parameter that includes all settings to use for the print. Previously, this was called from VB6 code, and Printer.hdc would work here after setting everything on the Printer object.
The code was converted from VB6 to VB.NET, and I have figured out most of things that I need to do. The old Printer object is available through the Microsoft.VisualBasic.PowerPacks.Printing.Compability.VB6.Printer class, but the old hdc property is not supported here.
Can anyone tell me how to get this hdc?
Is this hdc the same as GetHdevmode() on a System.Drawing.Printing.PrinterSettings object?

You can get one out of the Graphics object returned by PrinterSettings.CreateMeasurementGraphics(). Use the Graphics.GetHdc() method. Don't forget ReleaseHdc() after printing.

Hdc is not the same as getdevmode, but you can do everything in .net without using hdc. If it saves time using the old code, you can get the hdc from the graphics object and use it as in nobugz's answer. But if you have a graphics object for the printer, it might be simpler to draw directly to the graphics object and skip the hdc altogether.

Here's a similar approach to the one suggested by Hans but it uses a form control. If you are using a form control anyway, this might be a cleaner approach.
Place a PrintDocument from the Windows Forms toolbox to your form.
Then add the following code to handle the print page (as an example):
Private Sub PrintDocument1_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
Dim printerhdc As IntPtr = e.Graphics.GetHdc()
' Do whatever you need to do to get the right image
XYZ.Load file(currentpagenumber)
XYZ.Render(printerhdc.ToInt64, 25, 25, Width, Height)
CurrentPageNumber += 1
If CurrentPageNumber < TotalPageCount Then
e.HasMorePages = True
Else
e.HasMorePages = False
End If
e.Graphics.ReleaseHdc(printerhdc)
End Sub
...
'Gather all the files you need and put their names in an arraylist.
'Then issue the print command
PrintDocument1.Print
' You've just printed your files
source: http://www.vbforums.com/showthread.php?247493-Good-ol-Printer-hDC
(source: http://www.vbforums.com/showthread.php?247493-Good-ol-Printer-hDC)

Related

Do I need to send ESC commands through a windows driver?

Can anyone help me.
Do I need to send printer commands when printing through a windows driver?
I am writing a windows forms application which prints out information on a label printer. This information contains an image which has a title and a barcode on it. I can create the image ok, but when I try to send it to the printer it prints completely wrong!
The Esc commands are normally handled through the Windows Driver. Here's rough example on how to print an image. You initialize PrintDocument, then use the Print method to start printing. Windows then calls the PrintPage handler, which draws on e.Graphics. e.Graphics is effectively the printer page.
Dim pd As PrintDocument
AddHandler pd.PrintPage, AddressOf printPage
' assign pd properties
pd.Print
Sub printPage(ByVal sender As Object, ByVal e As PrintPageEventArgs)
' assign img, set rectangle, determine number of pages, etc.
e.Graphics.DrawImage(img, rectangle) ' essentially draws on the printer page
e.HasMorePages = ...
end sub

AllPaintingInWnPaint for TOOL_WINDOW

I'm trying to use GDI+ animation in a ToolWindow, whilst keeping the animation flicker-free. When I set the ControlStyles.AllPaintingInWmPaint to true the application crashes when the toolwindow is opened.
I create my toolwindow with the following code:
SetWindowLong(Handle, win32.GWL.__EXSTYLE, win32.WS._EX_TOOLWINDOW)
Where win32 is a class containing all the WM constants from PInvoke. GWL and WS are enums containing the integer values for the respective constants. The SetWindowLong is sourced from a dll import:
<DllImport("user32.dll",
EntryPoint:="SetWindowLong")>
Private Shared Function SetWindowLong(ByVal hWnd As IntPtr,
ByVal nIndex As Integer,
ByVal dwNewLong As Integer) As Integer
End Function
The ToolWindow code has worked wonderfully for me so far, but I haven't tried to use any GDI animation so far.
Basically, I would appreciate a method to reduce flicker/lag during GDI animation in my toolwindow type form, or a way to use the aforementioned controlstyle. I'm already using these styles:
SetStyle(ControlStyles.DoubleBuffer, True)
SetStyle(ControlStyles.UserPaint, True)
which reduce the flickering by a bit, but not enough.
I think I found the problem. In my Form.Paint event I tried to save on typing:
Dim g as Graphics = e.Graphics
g.DrawImage(bmp)
After changing this back to the original code;
e.graphics.DrawImage(bmp)
the program worked flawlessly! A lack of understanding on my part regarding variables resulted in many hours wasted.

VB.NET Custom Listview - How do you get the imagelist?

I have some code im working with to add icons to subitems. It's working great but now I have the need to center the icon in the subitem column. To do this I need to redraw the icon under the DrawSubItem event. How can I tie into the listviews assigned imagelist? (I am using Inherits Windows.Forms.ListView)
Thanks!
Private Sub lvResult_DrawSubItem(ByVal sender As Object, ByVal e As DrawListViewSubItemEventArgs)
If e.SubItem.Text = "" Then
Dim xpos = e.SubItem.Bounds.Location.X + (e.SubItem.Bounds.Width / 2) - 8
Dim p As New PointF(xpos, e.SubItem.Bounds.Location.Y)
e.DrawBackground()
e.Graphics.DrawImage(***NEED IMAGE HERE FROM THE IMAGELIST***, p)
Else
e.DrawDefault = True
End If
End Sub
Just use the property for it:
e.Graphics.DrawImage(Me.SmallImageList.Images("myImage")...
Obviously, you should do some error checking to make sure the image exists, etc.
But this illustrates why you are probably going down the wrong path with this since your custom control now needs to know about some images that exist on your form. Not a good object oriented design. It doesn't sound like you need a custom control.

Dynamically resize font to fill up RichTextbox

How do i dynamically resize the text in a RichTextbox so that it fills up the entire rich textbox?
any help is much appreciated. thank you.
This MSDN article almost answers your question. http://msdn.microsoft.com/en-us/library/bb986765.aspx.
You may download the attached sample there.
I think you might have to get creative with the 'Font' constructor. For example, on a click event then construct a new Font using some relationship with your application (or textbox size) with the desired font size.
Protected Sub btn_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btn.Click
Dim yourfontsize As Integer
'machinery to create desired font size
If blah then
yourfontsize = X()
Else
yourfontsize = Y()
End If
yourtextbox.SelectionFont = New Font("Tahoma", yourfontsize, FontStyle.Bold)
End Sub
Where X() and Y() are functions to return your target font sizes based on whatever else may
be going on within your application.
Reference: http://msdn.microsoft.com/en-us/library/yh8963yx.aspx
Hope that helps!
-sf

Printing Photos using VB6 and/or .NET

Does anyone have any code suggestions or samples for printing photos (BMP or TIFF or JPEG), using Visual Basic or .NET framework?
VB6 and .NET handle printing quite differently. These examples are the bare minumum, just to give you an idea of the process.
In VB6 you control the printer step by step:
Private Sub PrintMyPicture()
'Place to store my picture
Dim myPicture As IPictureDisp
'Load the picture into the variable
Set myPicture = LoadPicture("C:\temp\myPictureFile.bmp")
'Draw the picture on the printer, just off the edge of the page
Printer.PaintPicture myPicture, 10, 10
'Done printing!
Printer.EndDoc
End Sub
Lo and behold, your picture will come out of the default printer. the PaintPicture method accepts width, height and a few other parameters to help get the image to fit, and the Printer object gives you all sorts of info about the printer.
In .Net it's kind of the other way around. You start printing, and the printer will raise an event for each page until you tell it to stop. Every page event gives you as graphics object upon which you can draw using all of the standard System.Drawing classes and methods:
'Class variable
Private WithEvents printer As System.Drawing.Printing.PrintDocument
' Kick off the printing process. This will cause the printer_PrintPage event chain to start firing.
Public Sub PrintMyPicture()
'Set up the printer
printer.PrinterSettings.PrinterName = "MyPrinterNameInPrintersAndFaxes"
printer.Print()
End Sub
'This event will keep firing while e.HasMorePages = True.
Private Sub printer_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles printer.PrintPage
'Load the picture
Dim myPicture As System.Drawing.Image = System.Drawing.Image.FromFile("C:\temp\myPictureFile.bmp")
'Print the Image. 'e' is the Print events that the printer provides. In e is a graphics object on hwich you can draw.
'10, 10 is the position to print the picture.
e.Graphics.DrawImage(myPicture, 10, 10)
'Clean up
myPicture.Dispose()
myPicture = Nothing
'Tell the printer that there are no more pages to print. This will cause the document to be finalised and come out of the printer.
e.HasMorePages = False
End Sub
Again, there are a lot more parameters in DrawImage and the PrintDocument objects.