Solved

Dropdown component

Posted on 1998-04-10
5
1,107 Views
Last Modified: 2008-02-01
Hi

I'm looking for a way do show a form ( or TWinControl with child components
) as a popup window without causing a deactivate event in the main form.
The popup form can't be modal because I need to hide the form when the user
clicks outside the form client area.

I already looked in the vcl source code for TDBLookupCombobox but they
popup only one component. This technique can not work if you've several
wincontrols on the popupform which all need their own focus.
Same for the rx - datetime picker popup component and all datetime picker
components on Delphi super page.

The popup control cannot be a child from the main window because the popup
window needs to draw outside the main windows client area.

I need this popup for a component which is able to dropdown a complex
component with lots of TWinControls inside.

Anybody an idea ?

Thanks for your help.

Benny
0
Comment
Question by:bennyo
5 Comments
 
LVL 3

Expert Comment

by:KE
ID: 1361370
You should be able to take a normal form, without borders and titlebar, and place it where you want, with whatever you need in it. It should be working as a normal form, so if you can get your work done by a normal form, it's should straightforward.
Anyway, you can take a form and place it into every TWinControl.
Get the boundingbox of the control, and set your form boundings to the same positions, and make the form a parent of the control.

0
 

Author Comment

by:bennyo
ID: 1361371
No, displaying another form causes the deactivate event in my parent form. (exept if I show it modal, but I don't want to do that because I need to hide the popup form when the user click outside the popup form area.

Summarize :
I'm looking for a way to display a form without causing a DEACTIVATE in the parent form !!!!!!

0
 
LVL 3

Expert Comment

by:KE
ID: 1361372
Aint it possible to return the focus to the caller ?
Setting the StayOnTop property and the caller send the active control as a param to your form, which then set the focus to this.
0
 
LVL 4

Expert Comment

by:BoRiS
ID: 1361373
Why don't who use CreateParams and create the popup form that way

if you need example then just leave a comment...

Later
BoRiS

0
 
LVL 2

Accepted Solution

by:
Hagen040798 earned 200 total points
ID: 1361374
unit PopupPanel;
{Hi bennyo.
 Code for D3.
 TPopupPanel implem. a Panel-descend. This can use as Popup.
 You must call CloseUp(ModalResult) to Hide the Panel,
 Mouseclick's outside the Panel and Deactivation calls CloseUp(mrCancel).}
 
interface

uses ExtCtrls, Controls, Messages;

type
  TPopupPanel = class(TPanel)
  private
    FPopupResult: Integer;
    FInPopup: Boolean;
  protected
    procedure CreateParams(var Params: TCreateParams); override;
    procedure WMActivate(var Msg: TWMActivate); message wm_Activate;
  public
    function Popup(X, Y: Integer): Integer;
    procedure CloseUp(AResult: Integer);
  end;

procedure Register;

implementation

uses Windows, Classes, Forms;

const
  FMouseHook: hHook = 0;
  FInProc: Integer = 0;
  FPopupList: TList = nil;

var
  Old: LongInt;

function AcProc(Wnd: hWnd; Msg, wParam: WParam; lParam: LParam): LResult; stdcall; export;
begin
  Result := 0;
  if Msg = wm_NCActivate then wParam := 1;
  Result := CallWindowProc(Pointer(Old), Wnd, Msg, wParam, lParam);
end;

function TPopupPanel.Popup(X, Y: Integer): Integer;
var
  AWnd: hWnd;
  SaveBounds: TRect;
begin
  CloseUp(mrCancel);
  try
    FInPopup := True;
    SaveBounds := BoundsRect;
    AWnd := GetActiveWindow;
    if IsWindow(AWnd) then
    begin
      Old := GetWindowLong(AWnd, gwl_WndProc);
      SetWindowLong(AWnd, gwl_WndProc, LongInt(@AcProc));
    end;
    RecreateWnd;
    SetWindowPos(Handle, hWnd_Top, X, Y, Width, Height, swp_ShowWindow or swp_NoActivate);
    Visible := True;
    SetFocus;
    SelectNext(Self, True, True);
    FPopupList.Add(Self);
    while not Application.Terminated and IsWindowVisible(Handle) and FInPopup do
      Application.HandleMessage;
    Result := FPopupResult;
  finally
    if IsWindow(AWnd) then SetWindowLong(AWnd, gwl_WndProc, Old);
    CloseUp(mrCancel);
    BoundsRect := SaveBounds;
  end;
end;

procedure TPopupPanel.CloseUp(AResult: Integer);
begin
  if FInPopup then
  begin
    FInPopup := False;
    FPopupResult := AResult;
    if HandleAllocated and IsWindowVisible(Handle) then
      SetWindowPos(Handle, 0, 0, 0, 0, 0, swp_NoMove or swp_NoZOrder or
                   swp_NoSize or swp_HideWindow or swp_NoActivate);
    Hide;
  end;
  FPopupList.Remove(Self);
end;

procedure TPopupPanel.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  if FInPopup then
    with Params do
    begin
      Style := ws_ClipChildren or ws_ClipSiblings or ws_Popup;
      if TabStop then Style := Style or ws_TabStop;
      with WindowClass do
        Style := Style and not (cs_HRedraw or cs_VRedraw) or cs_ByteAlignWindow or cs_SaveBits;
    end;
end;

procedure TPopupPanel.WMActivate(var Msg: TWMActivate);
begin
  if (Msg.Active = wa_InActive) and FInPopup then CloseUp(mrCancel);
  inherited;
end;

procedure Register;
begin
  RegisterComponents('Samples', [TPopupPanel]);
end;

function MouseProc(Code: Integer; wParam: WParam; lParam: LParam): LResult; stdcall; export;
var
  P: TPoint;
  I: Integer;
  R: TRect;
begin
  if (Code = hc_Action) and (FInProc = 0) then
  try
    Inc(FInProc);  {Disables Recursion's}
    if (FPopupList <> nil) and (FPopupList.Count > 0) and
       ((wParam = wm_LButtonDown) or (wParam = wm_NCLButtonDown) or
        (wParam = wm_RButtonDown) or (wParam = wm_NCRButtonDown) or
        (wParam = wm_MButtonDown) or (wParam = wm_NCMButtonDown)) then
    begin
      GetCursorPos(P);
      for I := FPopupList.Count-1 downto 0 do
        with TPopupPanel(FPopupList[I]) do
        begin
          GetWindowRect(Handle, R);
          if not PtInRect(R, P) then CloseUp(mrCancel);
        end;
    end;
  finally
    Dec(FInProc);
  end;
  Result := CallNextHookEx(FMouseHook, Code, wParam, lParam);
end;

initialization
  FPopupList := TList.Create;
  FMouseHook := SetWindowsHookEx(WH_MOUSE, MouseProc, 0, GetCurrentThreadID);
finalization
  if FMouseHook <> 0 then UnHookWindowsHookEx(FMouseHook);
  FMouseHook := 0;
  FPopupList.Free;
end.

0

Featured Post

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
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…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

747 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

11 Experts available now in Live!

Get 1:1 Help Now