• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 545
  • Last Modified:

Custom Print Dialog Form

I want to build a custom Print dialog form, with the same controls as the standard box at the top, but different controls at the bottom. I can see how to get the list of printers, but I can't see how to get some of the other properties, such as 'Status'; 'Where'; 'Comment'. And how to make the 'Properties' button.
0
michaelhiggins
Asked:
michaelhiggins
  • 11
  • 10
  • +1
1 Solution
 
intheCommented:
Hi
get the printer type first from the string called Default not (default)
contained at :
hkey_local_machine

config/0001/system/currentcontrolset/control/print/printers

now use this string in replacement for "epson stylus color 600"
in the following key
(unless of course this is also your default printer ;-)

hkey_local_machine

System/CurrentControlSet/Control/Print/Printers/epson sylus color 600/

has the keys that hold the info you want.
0
 
rwilson032697Commented:
Listening
0
 
michaelhigginsAuthor Commented:
Hi Inthe

Thanks for the help

I've never got stuff from the registry - how do I do it?

Secondly - How do I make the properties button? It must be a standard windows dialog, but I do not know how to call it.

Thanks

Michael
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
intheCommented:
sorry i do not understand what you mean by "properties button".can you explain more on that .

i will send some code in a minute for the registry stuff (i'd like to test code before i post it)
0
 
michaelhigginsAuthor Commented:
Hi Inthe

In the standard (Windows 95) print dialog box at the top on the right there is a button marked 'Properties', just to the right of the drop-down list of printers.

Cheers

Michael
0
 
intheCommented:
Hi this is the registry basics stuff:

procedure TForm1.Button1Click(Sender: TObject);
var
R: Tregistry;
PrinterName : string;
i : integer;
begin
R :=TRegistry.Create;
R.Rootkey:=HKEY_LOCAL_MACHINE;
 with R do try
CreateKey('\config\0001\system\currentcontrolset\control\print\printers');
OpenKey('\config\0001\system\currentcontrolset\control\print\Printers',True);
PrinterName := ReadString('Default');
label1.caption := PrinterName;
R.CloseKey;
CreateKey('\System\CurrentControlSet\Control\Print\Printers\');
OpenKey('\System\CurrentControlSet\Control\Print\Printers\' + PrinterName + '\',True);
Label2.Caption := ReadString('Description');
Label3.Caption := ReadString('Port');
CheckBox1.Checked := ReadBool('Status');
R.CloseKey;
finally
  R.Free;
   end;
   end;

note remember to add "registry" to your uses section.

i se the buton you eman,the properties button is just a normal button,that links to what is called a "property sheet"
(like a control panel applet).
what do you mean "make a properties buton?
do you mean  you want to know how to link this button to standard properties dialog?



0
 
yk030299Commented:
listen
0
 
michaelhigginsAuthor Commented:
Thanks for the code i will try it out this evening.
Concerning the "properties" button, I want to know how to link to the properties sheet ie what code do i put under the Button's Onclick event
0
 
intheCommented:
best i found thanks to man called alexander.

uses Printers;

function PrinterPropertiesDialog(Modal:boolean):boolean;
const
  PRINTACTION_PROPERTIES=1;
type
  pfSHInvokePrinterCommand = function(
    hwnd:THandle; uAction:UINT; lpBuf1:pchar; lpBuf2:pchar; fModal:BOOL
  ):BOOL; stdcall;
var
  Device, Driver, Port: array[0..79] of char;
  Instance,DeviceMode:THandle;
  SHInvokePrinterCommand:pfSHInvokePrinterCommand;
  FreeInstance:boolean;
begin
  Result := False;
  Printer.GetPrinter(Device, Driver, Port, DeviceMode);
  FreeInstance := False;
  Instance:=GetModuleHandle('shell32.dll');
  if Instance=0 then
    begin
      FreeInstance := True;
      Instance:=LoadLibrary('shell32.dll');
    end;
  try
    SHInvokePrinterCommand := GetProcAddress(Instance,'SHInvokePrinterCommandA');
     if Assigned(SHInvokePrinterCommand) then
      Result := SHInvokePrinterCommand(Application.Handle,PRINTACTION_PROPERTIES,Device,nil,Modal)
  finally
    if FreeInstance then
      FreeLibrary(Instance);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 PrinterPropertiesDialog(true);
end;


Regards Barry
0
 
michaelhigginsAuthor Commented:
Hello Barry,

Thanks for the code. I could not get to work.. Instance is always a high number, never zero., hence the shell32.dll is not loaded. Could there be a path problem?

Cheers

Michael
0
 
intheCommented:
Possible but shell32 should be on your windows systems path ,so windows should find it straightaway .
you could try it by putting the full path name in instead but asking windows where the system dir is.

put this before the  PrinterPropertiesDialog function

function getsysdir : string;
var
lpBuffer: array[0..255] of char;
SysDir: string;
begin
GetSystemDirectory(lpBuffer, 255);
Result := lpBuffer;
end;

now replace the instance lines with :

  Instance:=GetModuleHandle(pchar(getsysdir+'\shell32.dll'));
  if Instance=0 then
    begin
      FreeInstance := True;
      Instance:=LoadLibrary(pchar(getsysdir+'\shell32.dll'));
    end;

0
 
intheCommented:
ps.
SysDir: string; <-- can be deleted ..
0
 
michaelhigginsAuthor Commented:
Barry,

i tried that but with the same result: instance is still a large integer (does that mean that shell32.dll cannot be found?

Michael
0
 
intheCommented:
this strange ,is shell32.dll exist ?
when you tried it did you have any instance of the printer dialog already loaded?

try thus;
Result := False;
    Instance := 0; //<--ADD THIS
Printer.GetPrinter(Device, Driver, Port, DeviceMode);
FreeInstance := False;
 //comment out Instance:=GetModuleHandle(pchar(getsysdir+'\shell32.dll'));
  if Instance=0 then
0
 
michaelhigginsAuthor Commented:
Barry,

shell32.dll certainly seems to exist.. However, I still get the same result. Do you have a form with a properties button correctly configured that you could send me?

Michael
0
 
intheCommented:
yes sure just leave your email address.

i used the exact code pasted here and it worked nicely.

0
 
michaelhigginsAuthor Commented:
Barry,

shell32.dll certainly seems to exist.. However, I still get the same result. Do you have a form with a properties button correctly configured that you could send me?

Michael
0
 
michaelhigginsAuthor Commented:
Barry,

I'm at

mhiggins@uqac.uquebec.ca

thanks

Michael
0
 
intheCommented:
this should do it on win95 also :

uses printers, winspool;
 
{$R *.DFM}
 
procedure TForm1.Button1Click(Sender: TObject);
var
  hPrinter: THandle;
  Device : array[0..255] of char;
  Driver : array[0..255] of char;
  Port  : array[0..255] of char;
  hDeviceMode: THandle;
begin
  Printer.PrinterIndex := combobox1.itemindex;
  Printer.GetPrinter(Device, Driver, Port, hDeviceMode);
  if WinSpool.OpenPrinter(@Device, hPrinter, nil) then
  try
    PrinterProperties( Handle, hPrinter );
  finally
    WinSpool.ClosePrinter( hPrinter );
  end;
end;
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  combobox1.items:= printer.printers;
  combobox1.itemindex := 0;
end;
 
0
 
michaelhigginsAuthor Commented:
Adjusted points from 200 to 300
0
 
michaelhigginsAuthor Commented:
Great This works well. Is it possible to use Winspool to get at the 'status'

Michael
0
 
michaelhigginsAuthor Commented:
I seem to have accepted the wrong answer. I wanted to use the last one with winspool.

Michael
0
 
intheCommented:
Hello,
 all i have on the status is this to tell how many jobs are left in printers spooler:

type
  TForm1 = class(TForm)
    Label1: TLabel;
  private
    { Private declarations }
    procedure WM_SpoolerStatus(var Msg : TWMSPOOLERSTATUS);
      message WM_SPOOLERSTATUS;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.WM_SpoolerStatus(var Msg : TWMSPOOLERSTATUS);
begin
  Label1.Caption := IntToStr(msg.JobsLeft) +' Jobs currenly in spooler';
msg.Result := 0;
end;


maybe it is some help..
0

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

  • 11
  • 10
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now