Print to a Dymo LabelWriter 450

There have been several conversations here about printing to Dymo but none seem to give me the answer.

The following code prints appropriately to a regular printer but when the Dymo is deleted in the printersetup, only a blank table prints. It advance the blank label so it is communicating so I suspect there is just some unique set of settings that have to be used. Anyone have any idea>

thanks so much in advance.

[code]var ps As New PrinterSetup
var Label As Graphics
var iLeft As Integer = 12
var iTop As Integer = 25
var iLineH As Integer = 18
var sLine(4) As String
var iLineCnt As Integer = 0
var settings As String

sLine(iLineCnt) = Trim(tfFirstName.Text) + " " + Trim(tfMiddleName.Text) + " " + Trim(tfLastName.Text)
iLineCnt = iLineCnt + 1
sLine(iLineCnt) = Trim(tfAddr1.Text)
iLineCnt = iLineCnt + 1
if tfaddr2.Text <> “” then
sLine(iLineCnt) = Trim(tfAddr2.Text)
iLineCnt = iLineCnt + 1
end if
sLine(iLineCnt) = Trim(tfCity.Text) + ", " + Trim(spmState.Text) + " " + Trim(tfZip.Text)

Label = OpenPrinterDialog(ps)
Label.DrawText(sLine(0), iLeft, iTop)
iTop = iTop + 18
Label.DrawText(sLine(1), iLeft, iTop)
iTop = iTop + 18
Label.DrawText(sLine(2), iLeft, iTop)
iTop = iTop + 18
Label.DrawText(sLine(3), iLeft, iTop)

Return[/code]

In my experience with the Dymo 450 printers you really need to go into Page Setup at least once, set all of the margins as close to zero as you possibly can and save the printer setup string to disk so it can be used the next time.

I’ll second that. Once the page setup is done, printing is straightforward.

Greg’s response SORTA fixed it. I have the label correctly printing to the Dymo printer but the open printer dialog won’t save the Dymo printer, it always goes back to the default.

After doing a lot of searching here that seems to be a pretty well know XOJO problem. Why can’t they fix it?

[quote=475453:@William Plunkett]
After doing a lot of searching here that seems to be a pretty well know XOJO problem. Why can’t they fix it?[/quote]
Like many things this has changed dramatically from the Carbon days and so I suspect a big chunk of it needs a rewrite or significant overhaul to be modernized.

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.