I am using a brother QL-1110NWB label printer to print labels as well as a laser printer to print normal pages (Delivery notes). For the label printer I have a one time setup and save the setup string. Then when printing the label, I use no printer dialog - print straight using OpenPrinter() with the saved setup string. This works well and uses MBS as well as API 2.0, so you need 19R2 or later. I use 19R3.1. MBS might not be needed but for the way I want my interface to be it works well and it gives the option to optimise/tweak the setup string further in the future in a way that standard Xojo code can not.
The code still needs to be cleaned up (and I still have to buy an MBS license as I am using an evaluation version now…)
In application config window, I have popupmenu to show list of available printers. This is populated as:
[code]Sub Open() Handles Open
// start Open event
IsLoading = true
// fill printer menu
if TargetMacOS then
dim printers() as string = NSPrinterMBS.printerNames
PrinterMenu.DeleteAllRows
dim PrinterInfo as NSPrintInfoMBS = NSPrintInfoMBS.sharedPrintInfo
for each printer as string in printers
PrinterMenu.AddRow printer
next
if app.preferences.mLabelPrintSettings<>"" then
printerinfo = new NSPrintInfoMBS(app.preferences.mLabelPrintSettings)
PrinterMenu.SelectByText(printerinfo.printername)
lblLabel.Value = printerinfo.papername
lblOrientation.Value = PrinterInfo.OrientationName
end if
elseif TargetWindows then
PrinterMenu.DeleteAllRows
dim PrinterInfo as WindowsPrinterInfoMBS
for each w as WindowsPrinterInfoMBS in WindowsPrinterInfoMBS.LocalPrinters
PrinterMenu.AddRow w.PrinterName
next
if app.preferences.mLabelPrintSettings<>"" then
dim d as WindowsDeviceModeMBS = WindowsDeviceModeMBS.FromSetupString(app.preferences.mLabelPrintSettings)
lblLabel.Value = d.FormName
lblOrientation.Value = d.OrientationName
PrinterMenu.SelectByText(d.DeviceName)
end if
end if
IsLoading = false
End Sub[/code]
Extensions to classes used:
Public Function OrientationName(extends p as NSPrintInfoMBS) as string
if p.orientation = 0 then
return "Portrait"
else
return "Landscape"
end if
End Function
Public Function OrientationName(extends p as WindowsDeviceModeMBS) as string
if p.Orientation = 0 then
return "Portrait"
else
return "Landscape"
end if
End Function
[code]Public Sub SelectByText(Extends p As PopupMenu, text As String)
For i As Integer = 0 To p.ListCount-1
If p.List(i) = text Then
p.ListIndex = i
Return
End If
Next
End Sub[/code]
In the popupmenu change event I trigger configuration of the printer setup string:
[code][code]Sub Change() Handles Change
dim name as string
dim p as PrinterSetup = new PrinterSetup
dim g as Graphics
if IsLoading= true then
// it is during Open event, then don’t fire
Return
end if
if TargetMacOS then
dim prntr as NSPrinterMBS
dim printerinfo as NSPrintInfoMBS
name = printermenu.SelectedRowValue
if name <>"" then
prntr = new NSPrinterMBS(name)
printerinfo = new NSPrintInfoMBS(p.SetupString)
printerinfo.printer = prntr
p.SetupString = printerinfo.SetupString
if p.ShowPageSetupDialog then
// update preferences setting
app.preferences.mLabelPrintSettings = p.SetupString
end if
end if
if app.preferences.mLabelPrintSettings<>"" then
printerinfo = new NSPrintInfoMBS(app.preferences.mLabelPrintSettings)
lblLabel.Value = printerinfo.papername
lblOrientation.Value = PrinterInfo.OrientationName
end if
elseif TargetWindows then
dim d as WindowsDeviceModeMBS = WindowsDeviceModeMBS.FromSetupString(app.preferences.mLabelPrintSettings)
if d=nil then
d = new WindowsDeviceModeMBS
end if
name = printermenu.SelectedRowValue
dim printerinfo as WindowsPrinterMBS = WindowsPrinterMBS.OpenPrinter(name)
d.DeviceName = printerinfo.Printername
p.SetupString = d.SetupString
if p.ShowPageSetupDialog then
// update preferences setting
app.preferences.mLabelPrintSettings = p.SetupString
end if
if app.preferences.mLabelPrintSettings<>"" then
d = WindowsDeviceModeMBS.FromSetupString(app.preferences.mLabelPrintSettings)
lblLabel.Value = d.FormName
lblOrientation.Value = d.OrientationName
end if
end if
End Sub[/code][/code]
This way p.ShowPageSetupDialog sets up the printer without triggering the printing of the page. Without API 2.0 I could not find a way to do that and with MBS alone I also could not figure out how to do that either. API 2.0 was needed for me to get it working as under API 1.0 the whole printer setup sequence was more or less reversed from what it should be - it does the page setup first and then the printer selection and that does not work if paper sizes fundamentally change between printers as you have going from a default configured laser printer with A4 to a label printer and a label size of 62mm x 100mm.
One key reason why I use NBS is because I want the app to show which printer has been selected without having to go into the page setup dialog and without NBS it is almost impossible to extract the printer name from the setup string.
This was the only way I could get a list of available printer specific paper sizes and select the correct one and have it correctly in the setupstring.
Then I have a button to print a test page if needed:
[code]dim pLabel As PrintLabel
pLabel = new PrintLabel
if pLabel.CanPrint then
pLabel.PrintLabelTestPage
end if[/code]
Canprint just checks if g<>nil. The constructor is as follows, showing the printer dialog in debug mode:
[code]Public Sub Constructor()
ps = New PrinterSetup
printArea = new Rect
if app.preferences.mLabelPrintSettings<>"" then
ps.SetupString = app.preferences.mLabelPrintSettings
#if DebugBuild then
g = OpenPrinterDialog(ps)
#else
g = OpenPrinter(ps)
#endif
else
Messagebox(“No label printer set up”)
g = nil
end if
Setmargins
printArea.Left = pgMarginLeft + hPixToMM(ps.PageLeft)
printArea.Top = pgMarginTop + vPixToMM(ps.PageTop)
printArea.Width = hPixToMM(ps.Pagewidth) - pgMarginLeft - pgMarginRight
printArea.Height = vPixToMM(ps.PageHeight) - pgMarginTop - pgMarginBottom
End Sub[/code]
PrintArea is the scaled in mm. The pgXXXX parameters are specific to my label format. Setmargins is only for Windows - I don’t trust the windows setup but I think it is a driver issue as I don’t have a problem with A4 and the laser printer driver. Even this code I don’t trust 100% and I am trying to get rid of it.
[code]Public Sub Setmargins()
If TargetWindows Then
Dim Codes() As String = ps.SetupString.Split(EndOfLine.Windows)
For i As Integer = 0 To Codes.Ubound
If Codes(i).InStr("MarginLeft") > 3 Then Codes(i) = "MarginLeft=3"
If Codes(i).InStr("MarginRight") > 3 Then Codes(i) = "MarginRight=3"
If Codes(i).InStr("MarginTop") > 3 Then Codes(i) = "MarginTop=3"
If Codes(i).InStr("MarginBottom") > 3 Then Codes(i) = "MarginBottom=3"
Next
ps.SetupString = Join(Codes, EndOfLine.Windows)
end if
End Sub[/code]
The pLabel.PrintLabelTestPage code is just standard drawing code.