Solved

TPrintDialog

Posted on 2001-08-28
7
211 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
Comment Utility
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
Comment Utility
But I want handle ON printer Change event! :(
0
 
LVL 10

Expert Comment

by:Jacco
Comment Utility
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
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 
LVL 10

Expert Comment

by:Jacco
Comment Utility
Hi pmarkov,

Is this what you are looking for?

Regards Jacco
0
 

Author Comment

by:pmarkov
Comment Utility
YES!
Thank you.

0
 
LVL 10

Accepted Solution

by:
Jacco earned 100 total points
Comment Utility
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
Comment Utility
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

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
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…
This video discusses moving either the default database or any database to a new volume.
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…

762 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

9 Experts available now in Live!

Get 1:1 Help Now