vrad
vrad

Reputation: 836

"Operation not supported" and "Printer selected is not valid" errors while printing

Hopefully somebody will be able to help. In my Delphi 7 application small percentage of users report errors when printing and I'm trying to resolve this with last of them. I'm slightly limited when it comes to testing (as user is physically distant and we are working it out via e-mail), but I get some additional information from EurekaLog.

Anyway, first error that he got is "Operation not supported on selected printer", at this line of code:

Printer.Orientation := AOrientation;

So, I assumed that his printer doesn't support Orientation (I never heard of this, but I guess it's possible) and tried without this line of code. But now he gets "Printer selected is not valid" at this line:

Result := Printer.PageWidth / GetDeviceCaps(Printer.Handle, LOGPIXELSX);

As far as I know, printer is correctly selected (it's Canon Pixma iP1500, but other users have other models, inkjet or laser), and he already tried to update drivers. OS also varies - from XP to Vista SP1).

I suggested to him to try with another printer, but whatever he responds, I don't know where to look next. Google search didn't give any useful results (for me, at least). Does anyone have an idea?

Thanks in advance!

Upvotes: 11

Views: 24342

Answers (10)

Hugh Jones
Hugh Jones

Reputation: 2694

This is purely anecdotal but it just might be relevant.

I have just been chasing down a 'Printer selected is not valid' error message in a Delphi 5 application.

The software was creating a virtual printer in order to generate .pdf files. I found that the 'old' printer was being stored by its index which was an unreliable means of returning to it after the pdf operation had finished.

By changing the logic so that the old printer was restored by name I believe I was able to resolve my problem. (We go into test in a few days)


By the way - QuickReports was involved.

Upvotes: 0

ivan_pozdeev
ivan_pozdeev

Reputation: 36106

http://zpay.com/vbulletin/showthread.php?2310-Printer-selected-is-not-valid , http://support.quickbooks.intuit.com/support/articles/SLN40193 and Delphi Win32 Service "Printer Selected is not valid" error on 2008 64bit standard server list possible causes.

In brief, they are all configuration issues, i.e. your program cannot access the printer for whatever reason.

I guess Delphi tries to open the printer on demand when you access a relevant property and, as frameworks are infamous for doing this, hides the real error.

I'd suggest you try to open the printer as explicitly as possible (e.g. with OpenPrinter, then try smth like GetPrinterDataEx) so you get some error message that would give as specific a hint as possible of what exactly goes wrong.

Upvotes: 0

Sebastian Z
Sebastian Z

Reputation: 4740

The error you get points in the direction that SetDefaultPrinter or the printer enumeration fails. SetDefaultPrinter looks a bit scary in Delphi 7. For example it tries to read the default printer from the Registry. It got better in newer Delphi versions, but I still patch Printers.pas in every new version.

This is my patch for Delphi 2009. You might have to make some adjustments for Delphi 7, but this should give you an idea. There is not much left from the original function.

{$IFDEF UNICODE}
function GetDefaultPrinter(DefaultPrinter: PChar; var I: Integer): BOOL; stdcall;
  external winspl name 'GetDefaultPrinterW';
{$ELSE}
function GetDefaultPrinter(DefaultPrinter: PChar; var I: Integer): BOOL; stdcall;
  external winspl name 'GetDefaultPrinterA';
{$ENDIF}

procedure TPrinter.SetToDefaultPrinter; //@@@ SZ
var
  I: Integer;
  Err: DWORD;
  Device: PChar;
begin
  I := 0;
  if not GetDefaultPrinter(nil, I) then       //  (this should return false because the buffer is too small)
  begin
    Err := GetLastError;
    if (Err = ERROR_FILE_NOT_FOUND) or (I = 0) then
       RaiseError(SNoDefaultPrinter)
    else if Err = ERROR_INSUFFICIENT_BUFFER then
    begin
      Device := StrAlloc(I);
      try
        if GetDefaultPrinter(Device, I) then
        with Printers do
          for I := 0 to Count-1 do
          begin
            if AnsiSameText(TPrinterDevice(Objects[I]).Device, Device) then
            begin
              with TPrinterDevice(Objects[I]) do
                SetPrinter(PChar(Device), PChar(Driver), PChar(Port), 0);
              Exit;
            end;
          end
        else
          RaiseLastOSError;
      finally
        StrDispose(Device);
      end;
    end
    else
      RaiseLastOSError;
  end;
  RaiseError(SNoDefaultPrinter);
end;

If this does not work, then the next step would be checking why printer enumeration fails. Take a look at "Device", "Driver", "Port" of the TPrinterDevice list.

Upvotes: 1

Trinidad
Trinidad

Reputation: 2826

This worked for me. I use it before trying to get the printer handle.

procedure InvalidatePrinter;
var
  dev,
  driv,
  port: array[0..80] of Char;
  deviceMode: THandle;
begin
  Printer.GetPrinter(dev, driv, port, deviceMode);
  Printer.SetPrinter(dev, driv, port, 0)
end;

Upvotes: 1

Robert
Robert

Reputation: 11

I have had users report this same error but only on Windows Vista. Windows XP and 7 do not appear to have the same issue. I have found that on Windows Vista computers turning off the UAC will eliminate this problem.

Upvotes: 1

Scott W
Scott W

Reputation: 9872

I have a customer with what sounds like the same (or at least a similar) problem. The line of code where we get the "Printer selected is not valid" message is slightly different (in the quick reports library), but it is similarly a call to GetDeviceCaps.

While we have yet to find a real solution, we have found a workaround. If the user visits the "Printer Setup" dialog before attempting to print the report, the error does not appear.

Have you had a look at these sites that I have found with some help from Google:

http://www.delphipages.com/threads/thread.cfm?ID=19871&G=19828

http://www.contactplus.com/cfaq/index.php?qid=381&catid=4

Upvotes: 1

Tom
Tom

Reputation: 6707

You may need to tweak delphi's printer.pas - there are a few bugs in printer implementation at least with older delphi versions, e.g. if network printer UNC name is too long delphi may crash.

Upvotes: -1

Mihai Limbășan
Mihai Limbășan

Reputation: 67826

Not a solution but a tip for reducing the bug surface: Install (or have the user install) a virtual printer on that system and try to print to that one. A free (both as in beer, and as in freedom) virtual PDF printer comes with the excellent PDFCreator. It definitely supports page orientation. That will give you a known good baseline against which to test.

Upvotes: 4

mj2008
mj2008

Reputation: 6757

Not a direct solution, but it may help solve the problem. First thing I do with this sort of problem is get the exact driver version from the customer, and then download the driver and install it on my PC, using LPT1. I can then print against it for testing, and resolve any issues with the driver. Obviously I can't actually print, but that isn't usually a problem. Using a virtual machine helps a lot too.

Upvotes: 4

Toon Krijthe
Toon Krijthe

Reputation: 53476

You say that a small percentage of users report the problems. Do you have any idea what is the difference between these and the other users?

In think about:

  • used printers
  • printer drivers (version)
  • OS used, including patches and updates (don't forget the IE updates)
  • version of your software
  • other installed software

Do the users have print problems with other applications?

It would be a great help if you could reproduce the problem.

Upvotes: 2

Related Questions