Selecting printer without asking user

Selecting the printer to use (not the default printer/Windows 10), without asking the user.

Sending text to a specific printer (not the default printer/Windows 10), without asking the user, not even once.

Dear Friends.

I am a user since RealStudio (2011). A few years ago I upgraded to xojo, but I didn’t use it because I didn’t understand the new interface well or know the new commands, and that’s how time went by.

Now I’m finally updating my old programs to Xojo 2022.r3.2 and I see sadly that my software requires a lot of changes, I’m working on it.

The biggest problem I have, is trying to send text to a printer different to the windows default printer.

My computer has 2 printers, one is to print invoices (Brother/InkJet/Letter sized) from a billing software I bought (this is the default printer in Windows 10), and the other is a POS printer (Bixolon/thermal printer for tickets) to print just that tickets, and this is the one that my program should use (this is configured in Windows but it’s not the default printer, and in fact no other program uses it, it’s just for my program).

The point is that the two printers are already registered in Windows, I have the “settings” of the Bixolon printer saved in a small database, and when I need to print a ticket, my program searches and loads the “settings”, it builds the ticket, and sends it to this printer. I don’t need to ask the user, nor do I need to select the printer they want to use, that is always fixed.

The specific problem is that although my program opens the file with the settings and assigns them, when it sends to print they come out on the Brother printer, not on the Bixolon! It’s as if a couldn’t identify it, it just sends it to the default printer. Before, it did print to the correct printer with no problems, but it no longer does so.

I would like to know what is wrong, because it has been working well for years, and it no longer does. :frowning:

Here are the settings that I have saved:

DoNotAlterThis=SetupString.2 ActualHorizontalResolution=72 ActualVerticalResolution=72 MaxHorizontalResolution=72 MaxVerticalResolution=72 MarginLeft=0 MarginRight=0 MarginTop=0 MarginBottom=0 MinMarginLeft=0 MinMarginRight=0 MinMarginTop=0 MinMarginBottom=0 PageSetupFlags=10 DevModeStructureSizePS=936 DevModeStructurePS=BIXOLON SRP-F310

And this is the program that assigns these settings to the printer:

Dim Settings as String      // Settings will be used for keeping the printer’s settings

Dim pageSetup As PrinterSetup

pageSetup = New PrinterSetup

// Then I access my database, and store the printer settings (listed before) in the “settings” variable
Msgbox “The settings from the database are:”+chr(13)+settings  // This is just to verify that the settings are complete and correctly accessed.

pageSetup.SetupString = settings    // Here I assign the setting to the printer (including the printer’s name as named by Windows)

Dim g as Graphics

g = OpenPrinter(pagesetup)

g.DrawString ("Hello world”,0,0) … // Just normal printing row by row

…
…
…

Do you see something wrong here? Any suggestion will be very welcome!

Best regards!

I haven’t tried this on the newer versions, but a setupstring on Windows is usually around 2048 bytes. Could you be losing some info? Also, try presenting the SetupDialog and re-saving the setupstring.

i remember i saved it binary for some reason.

Do you use MBS Xojo Plugins?

We have classes to work with the SetupString in PrinterSetup and edit the settings.
See NSPrintInfoMBS class for macOS and WindowsDeviceModeMBS class for Windows.

Use Christian’s plugins for this. Editing the setup string is a great way to crash your app.

2 Likes

After the textual part Xojo appends some binary internal content. Xojo printer handling is not smart enough to give users more freedom for setting values themselves without Xojo interfaces.

That’s one of the parts of Xojo needing enhancements.

2 Likes

Thanks Tim! Well now when you say it, it makes sense, because it doesn’t matter how do I write the printer’s name, it always does the same, so may be the last part of the settings are not loaded (doesn’t fit) into the SetupString… it’s just missing! and without it, It goes directly to the default printer …

Hi Chris! I’m not using any plugin, just the Xojo’s way! :slight_smile: But right now I’m going to read about your plugins. Thank you.

Just as a data point, the last time I worked on a project that did printer swapping (for a very similar reason), we used MBS to do so.

It was a long time ago and for a project I no longer have access to, so I can’t look up the code to offer answers or guidance, but I thought I’d mention that MBS was a usable solution.

I would like to understand, why is it so difficult to print from Xojo? I mean, when I met RealStudio (2011) it was so simple, I had a program that used to open the printer dialog (Windows 7 at that time), and after selecting the printer and its settings (sizes, margins, etc. ) , stored the data in a string variable and saved it in a mini SQLlite database (just one record), or two or three depending on how many printers you need to use. So when the program needed to print a ticket, it just needed to open the database, get the settings and assign it to the printer settings, and VOILA! the ticket is printed! The right setup, the right printer! Why can’t it be the same way? I am seriously considering reinstalling the RealStudio 2011 license and recompiling my program from there, because that used to work perfectly and “default printer independent”…

It works the same way. But if you want to store the current configs that contains binary content in a DB, better convert it to base 64 before doing so, and converting it back to the binary original content when reading it back.

My grievances are more comparing the way Xojo does and other platforms, as VB.Net, that you have access to basically anything for printing jobs, as the list of printers, knowing what’s the default one, read configs of such printers, and could set almost anything, and use those printers precisely (knowing paper sizes, resolution, margins, etc) without even presenting a dialog if you wanted so.

1 Like

Xojo sucks at printing.

You can use declares to print on windows. Try searching the forum for raw printing or printing with declares.

1 Like

If you’re macOS only then macOSLib provides functions to get a list of available printers. Which can help some things.

Thank ou ver much guys. I found a little program that Tim did called twoprinters (thanks Tim) and in fact it stores the printer settings in a text file using textstreams (in and out), so I tried it and it works! The very first time ou run it, it’s empty so opens a dialog for you to select the printer and it’s settings, so it stores them, the next time you run it, it finds the settings so doesn’t asks the user for them, and it sends the text to the right printer!.

dim ps as new PrinterSetup
dim f as FolderItem
dim txtin as TextInputStream
dim txtout as TextOutputStream
dim g as Graphics

f = GetFolderItem("printer1.txt")
if not f.exists then
  if not ps.PageSetupDialog then return
  g = OpenPrinterDialog(ps)
  if g = nil then return
  txtout = TextOutputStream.Create(f)
  txtout.write ps.SetupString
else
  txtin = TextInputStream.Open(f)
  ps.SetupString = txtin.ReadAll
  g = OpenPrinter(ps)
end

g.DrawString("Printer 1", 30, 30)

I will modify my program to work this way and not the DB way and I think it’s going to work. Will tell you what happened when done.
I really appreciate your support guys! :smiley:

As already said, using a DB works too. You just need to preserve all the binary content. One way is encoding the stream as Base64 before writing it in a large enough field and decoding it reading it back, or using a blob.

But storing a binary content directly in a file (I would not use .txt to avoid users trying to edit it) will work too.

We save and retrieve binary setupstrings to a database without problem. We use both MySql and Sqlite. Using Base64 is a good idea, though. But we’ve gotten away with it for the last 20 years, so I’m not going to revisit that code just yet.

Do yourself a favor and either hexencode or base64encode the setup string. It could include bytes like chr(0) that may cause issues for the text.

Thanks to all of you guys!
I decided to install a new hard drive (an SSD to improve things!), install a new and fresh windows 10, the printer drivers of both printers, and try with a little and simple program that just sends the ticket to one printer or the other. This way I will be sure why it used to work, and why it doesn’t now. I will include the 64encoding to make things right, and will let you now assap.
Best and kind regards. Merry christmass to all of you! Best whishes!

I didn’t read the entire thread, so sorry if this is unrelated…, but this one got me on Windows. We do print directly to a thermal printer without printer dialog and assume it is set as default printer. However, if this box is checked in Windows, it sets the default to the last one used. In that case if user prints to different printer in another app, Windows then assume that to be default.

1 Like

Hi Jose, there is probably nothing wrong with the way you did it in the first place.

It is certainly a good idea to Base64 encode the string for database storage.

I am not sure if you updated the configuration for the Xojo version of the program. It is well possible the content of that configuration string changed between the old RealBasic version and the current Xojo version.

I am not sure if these configuration strings are portable between machines. It is likely the are not.

I have reason to believe that the configuration string is different for a x86 and an x64 version of the same Xojo App, even for the same printer on the same machine.