Solved

TPrintDialog

Posted on 2001-08-28
7
218 Views
Last Modified: 2010-04-04
Hello

How can I handel ONPrinterChange event when TPintDialog is executing?

I want to get Printer.PrinterIndex during the PrintDialog is appearing.

I want to get all printer's settings before Execute metod.

Thanks.
0
Comment
Question by:pmarkov
  • 3
  • 3
7 Comments
 
LVL 9

Expert Comment

by:ITugay
ID: 6431430
Hi pmarkov,

sorry, have no time to write complete sample, here is only idea:

type
  TWindowProc = function (H, Msg, L, W: Integer): Integer; stdcall;
var
  OldPDWndProc: TWindowProc;

function PDWndProc(H, Msg, L, W: Integer): Integer; stdcall;
begin
  // here you can check some values of dailog
  // e.g. get text for printer's combobox
  Result := OldPDWndProc(H, Msg, L, W);
end;

procedure TForm1.PrintDialog1Show(Sender: TObject);
begin
  OldPDWndProc := Pointer(GetWindowLong(PrintDialog1.Handle, GWL_WNDPROC));
  SetWindowLong(PrintDialog1.Handle, GWL_WNDPROC, Integer(@PDWndProc));
end;

-----
Igor.
0
 

Author Comment

by:pmarkov
ID: 6431618
But I want handle ON printer Change event! :(
0
 
LVL 10

Expert Comment

by:Jacco
ID: 6446484
Hi pmarkov,

I have spent some hours trying to get things working. Igor was right. Here is the working code. The TPrintDialog does not have an OnPrinterChange event. That is why you need to bend the message handling chain so that you catch the windows messages send to the combobox. For that you first have to find the combobox.

To achieve this you implement the OnShow event of the TPrintDialog. There you have access to the Handle of the dialog. The you loop all WinControls on the dialog using FindWindowEx until you find one of ClassName "ComboBox" (you can get the ClassName of a HWND using GetClassName). Then you reroute the message handling chain for the found handle by GetWindowLong and SetWindowLong passing the object instance of your new window proc (which is made using MakeObjectInstance).

The message handler must do the following:

catch WM_COMMAND check if NotifyCode = 1 get the selected index of the combo and report it (or call an event...).

Good luck,

Regards Jacco

procedure TForm1.Button4Click(Sender: TObject);
begin
  PrintDialog1.Execute;
end;

var
  OldPDWndProc: Pointer;
  NewPDWndProc: Pointer;
  PrinterComboHandle: HWND;

procedure TForm1.PDWndProc(var Message: TMessage);
var
  liIndex: Integer;
begin
  // Check whether combobox changes
  if Message.Msg = WM_COMMAND then
    if TWMCommand(Message).NotifyCode = CBN_SELCHANGE then
    begin
      // get the current index
      liIndex := SendMessage(PrinterComboHandle, CB_GETCURSEL, 0, 0);
      // report the selected printer index
      Memo1.Lines.Add('Printer selected: ' + IntToStr(liIndex));
    end;
  // call the old WindowProc
  with Message do
    Result := CallWindowProc(OldPDWndProc, PrinterComboHandle, Msg, wParam, lParam);
end;

procedure TForm1.PrintDialog1Show(Sender: TObject);
var
  t: Pointer;
  p: PChar;
  h: HWND;
begin
  NewPDWndProc := MakeObjectInstance(PDWndProc);
  GetMem(p, 100);
  h := FindWindowEx(PrintDialog1.Handle, 0, nil, nil);
  while h <> 0 do
  begin
    GetClassName(h, p, 100);
    if p = 'ComboBox' then
    begin
      PrinterComboHandle := h;
      OldPDWndProc := Pointer(GetWindowLong(h, GWL_WNDPROC));
      SetWindowLong(h, GWL_WNDPROC, LongInt(NewPDWndProc));
    end;
    h := FindWindowEx(PrintDialog1.Handle, h, nil, nil);
  end;
  FreeMem(p);
end;
0
Free Tool: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 10

Expert Comment

by:Jacco
ID: 6457851
Hi pmarkov,

Is this what you are looking for?

Regards Jacco
0
 

Author Comment

by:pmarkov
ID: 6469646
YES!
Thank you.

0
 
LVL 10

Accepted Solution

by:
Jacco earned 100 total points
ID: 6469737
Hi pmarkov,

I posted the previous comment as an answer.

Regards Jacco

procedure TForm1.Button4Click(Sender: TObject);
begin
 PrintDialog1.Execute;
end;

var
 OldPDWndProc: Pointer;
 NewPDWndProc: Pointer;
 PrinterComboHandle: HWND;

procedure TForm1.PDWndProc(var Message: TMessage);
var
 liIndex: Integer;
begin
 // Check whether combobox changes
 if Message.Msg = WM_COMMAND then
   if TWMCommand(Message).NotifyCode = CBN_SELCHANGE then
   begin
     // get the current index
     liIndex := SendMessage(PrinterComboHandle, CB_GETCURSEL, 0, 0);
     // report the selected printer index
     Memo1.Lines.Add('Printer selected: ' + IntToStr(liIndex));
   end;
 // call the old WindowProc
 with Message do
   Result := CallWindowProc(OldPDWndProc, PrinterComboHandle, Msg, wParam, lParam);
end;

procedure TForm1.PrintDialog1Show(Sender: TObject);
var
 t: Pointer;
 p: PChar;
 h: HWND;
begin
 NewPDWndProc := MakeObjectInstance(PDWndProc);
 GetMem(p, 100);
 h := FindWindowEx(PrintDialog1.Handle, 0, nil, nil);
 while h <> 0 do
 begin
   GetClassName(h, p, 100);
   if p = 'ComboBox' then
   begin
     PrinterComboHandle := h;
     OldPDWndProc := Pointer(GetWindowLong(h, GWL_WNDPROC));
     SetWindowLong(h, GWL_WNDPROC, LongInt(NewPDWndProc));
   end;
   h := FindWindowEx(PrintDialog1.Handle, h, nil, nil);
 end;
 FreeMem(p);
end;
0
 

Author Comment

by:pmarkov
ID: 6478751
Hi Jacco

With this example I can get Printer Index in DropDownBox but it is DIFFERENT from Printer Index In Printer.Printers.

How Can I get real Printer Index ot Printer Name selected in drop-down?

Thanks
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
Microsoft Active Directory, the widely used IT infrastructure, is known for its high risk of credential theft. The best way to test your Active Directory’s vulnerabilities to pass-the-ticket, pass-the-hash, privilege escalation, and malware attacks …
This video shows how to use Hyena, from SystemTools Software, to bulk import 100 user accounts from an external text file. View in 1080p for best video quality.

808 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