Solved

TPrintDialog

Posted on 2001-08-28
7
222 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

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

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
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…
If you're a developer or IT admin, you’re probably tasked with managing multiple websites, servers, applications, and levels of security on a daily basis. While this can be extremely time consuming, it can also be frustrating when systems aren't wor…
Monitoring a network: why having a policy is the best policy? Michael Kulchisky, MCSE, MCSA, MCP, VTSP, VSP, CCSP outlines the enormous benefits of having a policy-based approach when monitoring medium and large networks. Software utilized in this v…

705 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