[Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 564
  • Last Modified:

Draw or anchor a panel (or other TWinControl) over external window

Hi, waht is the best way (if exist) to anchor over an external window a custom panel?
I need to add my custom control on a form...can I do it?
With ParentWindow, the draw of the control undergoes distortion :(
0
ISIGest
Asked:
ISIGest
  • 4
  • 2
1 Solution
 
epasquierCommented:
can you precise (with images) what you are trying to do, what do you mean by "the draw of the control undergoes distortion", and what code you have tried so far ?
0
 
ISIGestAuthor Commented:
I try to set the ParentWindow handle with the window (destination) handle.
I need to add a custom controls (like a plugin) to a specified window in an external process.
This control (panel) must be interactive using a textbox or other controls.
0
 
epasquierCommented:
It works for me. I search the handle of the main window of one of my own application, then set the parent of a panel in my controling application to that window handle, and there goes my panel from the controling application to the other application.
No pb at all.

Only thing : I cannot close the controling application while the second application is not closed, probably because we messed with Delphi "Parent" system. The solution is to get back the panel to its rightful parent (the origin form)

Here is the code for that, including my function to search a window by name
procedure TForm1.btn1Click(Sender: TObject);
Var
 Hnd:THandle;
begin
 Hnd:=SearchMainWindowByName('Caisse');
 Windows.SetParent(pnl1.Handle, Hnd );
end;

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
 Windows.SetParent(pnl1.Handle, Handle );
end;

Var
 SearchWindowList:TStrings; // this is a global var, if set to something 
// then it will gather useful informations about the windows 
// found by EnumWindows. Ex : SearchWindowList:=ListBox1.Items;

function SearchMainWindowByName(Start:String;Mid:String='';UpC:boolean=True):THandle;
type
 RR=Record
     S,M:String;
     L:integer;
     U:boolean;
     hWindow:HWND;
    end;
 pRR=^RR;
Var
 R:RR;
 function EnumProcess(hHwnd: HWND; lParam : integer): boolean; stdcall;
 var
  pPid : DWORD;
  title, ClassName : string;
  R:pRR;
 begin
  //if the returned value in null the
  //callback has failed, so set to false and exit.
  if (hHwnd=0) then result := false else
   begin
    R:=pRR(lParam);
    //additional functions to get more
    //information about a process.
    //get the Process Identification number.
{$ifdef VER140}
      GetWindowThreadProcessId(hHwnd,pPid);
{$else}
      GetWindowThreadProcessId(hHwnd,@pPid);
{$endif}
    SetLength(ClassName, 255);
    SetLength(ClassName,
              GetClassName(hHwnd,
                           PChar(className),
                           Length(className)));
    SetLength(title, 255);
    SetLength(title, GetWindowText(hHwnd, PChar(title), Length(title)));
    //Display the process information
    //by adding it to a list box
    if Assigned(SearchWindowList) Then SearchWindowList.Add
      ('Class Name = ' + className +
       '; Title = ' + title +
       '; HWND = '+ IntToStr(hHwnd) +
       '; Pid = ' + IntToStr(pPid));
    if R^.U Then title:=UpperCase(title);
    if Copy(title,1,R^.L)=R^.S Then
     begin
      if (R^.M='')
       Or (Pos(R^.M,title)>0)
        Then R^.hWindow:=hHwnd;
     end;
    Result := true;
  end;
 end;
begin
 R.hWindow:=0;
 if UpC Then
  begin
   R.S:=UpperCase(Start);
   R.M:=UpperCase(Mid);
  end Else
  begin
   R.S:=Start;
   R.M:=Mid;
  end;
 R.L:=Length(Start);
 R.U:=Upc;
 if Assigned(SearchWindowList) Then SearchWindowList.Clear;
 EnumWindows(@EnumProcess,Integer(@R));
 Result:=R.hWindow;
end;

Open in new window

0
Technology Partners: 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!

 
epasquierCommented:
I actually have been able to put that panel in all applications I tried : Word, Firefox, Delphi, the desktop even.. And the button code I place in that panel is executing fine each time I click it.
BUT : Once I clicked once on the button, it messes with the origin application message loop : this one will not react to my user interaction until I closed the destination application.

I knew it would not go so smoothly to do such "uncommon" things, to say the least. But I suppose your application, once launch and having setup the panel in the destination app, will hide itself and not require interaction
0
 
ISIGestAuthor Commented:
Ok it work but there are some problem:
1. The control a painter correctlly when the own form is repainted.
2. The focus of an TEdit on the panel is linked to the main window (if you tr to add a TEdit on the panel and when you are with the focus on this control and you press the tab if on the MAIN FORM there is anhoter TEdit the focus jump to it)

0
 
epasquierCommented:
> 1. The control a painter correctlly when the own form is repainted.
?? can you rephrase that ?
I have no problems or repaint neither in the origin application, nor in the target application. If you have problems in the target application, then it is probably specific to this application. There have to be some problems in the edges of this technique, we are really messing with the applications...

2> yes, and that is expected, it is up to you to code onEnter/onExit, or keypress events on some  elements to control the focus moves in your form. For example, in the last element in your panel, if you move out from it and the focus get immediately in a control in your main form, then in the onEnter event of this control you call SetFocus on the first control in your panel.
Same for the last control of the main form, if you hit tab and enter in a control that is in the panel, you go back to a precise control of the main form.
In fact, you will then create 2 different loops of components. But surely Delphi designers did not have that kind of application in mind when they coded their tab behaviour.
0

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

  • 4
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now