Solved

Custom Print Dialog Form

Posted on 2000-03-11
23
524 Views
Last Modified: 2010-04-04
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
Comment
Question by:michaelhiggins
  • 11
  • 10
  • +1
23 Comments
 
LVL 17

Expert Comment

by:inthe
ID: 2608318
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
 
LVL 12

Expert Comment

by:rwilson032697
ID: 2608459
Listening
0
 

Author Comment

by:michaelhiggins
ID: 2609465
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
 
LVL 17

Expert Comment

by:inthe
ID: 2610164
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
 

Author Comment

by:michaelhiggins
ID: 2610192
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
 
LVL 17

Expert Comment

by:inthe
ID: 2610236
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
 
LVL 1

Expert Comment

by:yk030299
ID: 2611090
listen
0
 

Author Comment

by:michaelhiggins
ID: 2612400
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
 
LVL 17

Accepted Solution

by:
inthe earned 300 total points
ID: 2641595
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
 

Author Comment

by:michaelhiggins
ID: 2645084
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
 
LVL 17

Expert Comment

by:inthe
ID: 2645390
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
How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

 
LVL 17

Expert Comment

by:inthe
ID: 2645405
ps.
SysDir: string; <-- can be deleted ..
0
 

Author Comment

by:michaelhiggins
ID: 2645473
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
 
LVL 17

Expert Comment

by:inthe
ID: 2645612
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
 

Author Comment

by:michaelhiggins
ID: 2645865
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
 
LVL 17

Expert Comment

by:inthe
ID: 2645899
yes sure just leave your email address.

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

0
 

Author Comment

by:michaelhiggins
ID: 2645925
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
 

Author Comment

by:michaelhiggins
ID: 2645939
Barry,

I'm at

mhiggins@uqac.uquebec.ca

thanks

Michael
0
 
LVL 17

Expert Comment

by:inthe
ID: 2649500
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
 

Author Comment

by:michaelhiggins
ID: 2653204
Adjusted points from 200 to 300
0
 

Author Comment

by:michaelhiggins
ID: 2653205
Great This works well. Is it possible to use Winspool to get at the 'status'

Michael
0
 

Author Comment

by:michaelhiggins
ID: 2653214
I seem to have accepted the wrong answer. I wanted to use the last one with winspool.

Michael
0
 
LVL 17

Expert Comment

by:inthe
ID: 2655491
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

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
This video discusses moving either the default database or any database to a new volume.
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now