Recent

Author Topic: SetWindowPos problem  (Read 5221 times)

KarenT

  • Full Member
  • ***
  • Posts: 120
SetWindowPos problem
« on: May 21, 2017, 08:37:09 pm »
Sorry to be a pest with basic questions, but I can't get this to compile and searching has not found me a solution.

Code: Pascal  [Select][+][-]
  1.   SetWindowPos(Self.Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE or SWP_NOMOVE
  2.      or   SWP_NOACTIVATE);
  3.  

I get "Identifier not found: SetWindowPos"

I checked the Code Browser and it shows it in LCL and LCLBase.

LCL is already in the "Uses" and LCLBase shows "Cannot find LCLBase" if I add that in, so stumped I be.

What do I need to add to a "Uses" clause?

Thaddy

  • Hero Member
  • *****
  • Posts: 10785
Re: SetWindowPos problem
« Reply #1 on: May 21, 2017, 08:53:15 pm »
If setWindowPos is in lclintf or its include files (check that!) add just lclintf.

If it isn't:
It is a windows specific function from the windows API for which there is no X-platform direct equivalen availablet.
In such a case it is fine to add the windows (or a specific declaration ) unit, but you should document it is not cross platform.
« Last Edit: May 21, 2017, 08:56:12 pm by Thaddy »

sky_khan

  • Guest
Re: SetWindowPos problem
« Reply #2 on: May 21, 2017, 09:01:19 pm »
Where did you get this ?

It looks like this only tries to set a window as topmost window,
in other words, it is same as TControl.BringToFront procedure.

Thaddy

  • Hero Member
  • *****
  • Posts: 10785
Re: SetWindowPos problem
« Reply #3 on: May 21, 2017, 09:05:41 pm »
in other words, it is same as TControl.BringToFront procedure.

Nope. BringToFront affects focus. This is a very old and bad Delphi hack to show a form or dialog window topmost in the left-top without receiving focus.
But it is a valid WINAPI call.

The proper fix is to have that form include the StayOnTop property. Which is also cross-platform and Delphi compatible..
« Last Edit: May 21, 2017, 09:12:32 pm by Thaddy »

GetMem

  • Hero Member
  • *****
  • Posts: 4017
Re: SetWindowPos problem
« Reply #4 on: May 21, 2017, 09:09:23 pm »
@KarenT
This is cross platform:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. begin
  3.   Self.Left := 0;
  4.   Self.Top := 0;
  5.   Self.FormStyle := fsSystemStayOnTop;
  6. end;

Thaddy

  • Hero Member
  • *****
  • Posts: 10785
Re: SetWindowPos problem
« Reply #5 on: May 21, 2017, 09:12:55 pm »
Exactly. Tnx GetMem.

Note that fsSystemStayOnTop is not available in Delphi. Hence I suggested StayOnTop.
« Last Edit: May 21, 2017, 09:18:41 pm by Thaddy »

RAW

  • Hero Member
  • *****
  • Posts: 868
Re: SetWindowPos problem
« Reply #6 on: May 22, 2017, 12:17:19 am »
Isn't it better to use SETBOUNDS only once ???
Code: Pascal  [Select][+][-]
  1.  SetBounds(0, 0, Width, Height);

As far as I know LEFT and TOP and WIDTH and HEIGHT calls SETBOUNDS...  :P
Windows 7 Pro (x64 Sp1) And Windows XP Pro (x86 Sp3). I use mostly LAZ 2.0.8 FPC 3.0.4.
// This is polarity (hell) and hell is reigned by lies, nothing but lies. Be careful what you believe ...
// There are 10 types of people in this world, those who understand mind control and ...

GetMem

  • Hero Member
  • *****
  • Posts: 4017
Re: SetWindowPos problem
« Reply #7 on: May 22, 2017, 05:37:44 am »
On second thought the OP doesn't want to move the window at all. Take a look at the parameters: SWP_NOSIZE or SWP_NOMOVE or  SWP_NOACTIVATE. So the solution is:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. begin
  3.    Self.FormStyle := fsSystemStayOnTop; //or fsStayOnTop
  4. end;

GetMem

  • Hero Member
  • *****
  • Posts: 4017
Re: SetWindowPos problem
« Reply #8 on: May 22, 2017, 06:37:03 am »
And just to prove that SetWindowPos is not completely useless(at least not under windows), below is a small demo that will set the Z order of an external application's main window. Make sure notepad is running first, then click button1:
Code: Pascal  [Select][+][-]
  1. uses JwaWindows, jwatlhelp32;
  2.  
  3. function GetProcessMainWindow(const PID: DWORD; const wFirstHandle: HWND): HWND;
  4. var
  5.   wHandle: HWND;
  6.   ProcID: DWord;
  7. begin
  8.   Result := 0;
  9.   wHandle := GetWindow(wFirstHandle, GW_HWNDFIRST);
  10.   while wHandle > 0 do
  11.   begin
  12.     GetWindowThreadProcessID(wHandle, @ProcID);
  13.     if (ProcID = PID) and (GetParent(wHandle) = 0) and (IsWindowVisible(wHandle)) then
  14.     begin
  15.       Result := wHandle;
  16.       Break;
  17.     end;
  18.     wHandle := GetWindow(wHandle, GW_HWNDNEXT);
  19.   end;
  20. end;
  21.  
  22. function FindProcessByName(const ProcName:string): DWORD;
  23. var
  24.   Proc: TPROCESSENTRY32;
  25.   hSnap: HWND;
  26.   Looper: BOOL;
  27. begin
  28.   Result := 0;
  29.   Proc.dwSize := SizeOf(Proc);
  30.   hSnap := CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);
  31.   Looper := Process32First(hSnap, Proc);
  32.   while Integer(Looper) <> 0 do
  33.   begin
  34.     if UpperCase(ExtractFileName(proc.szExeFile)) = UpperCase(ProcName) then
  35.     begin
  36.       Result:=proc.th32ProcessID;
  37.       Break;
  38.     end;
  39.     Looper := Process32Next(hSnap, Proc);
  40.   end;
  41.   CloseHandle(hSnap);
  42. end;
  43.  
  44. procedure TForm1.Button1Click(Sender: TObject);
  45. var
  46.   PID: DWord;
  47.   wHandle: THandle;
  48. begin
  49.   PID := FindProcessByName('notepad.exe');
  50.   if PID <> 0 then
  51.   begin
  52.     wHandle := GetProcessMainWindow(PID, Form1.Handle);
  53.     if wHandle <> 0 then
  54.       SetWindowPos(wHandle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE);
  55.   end
  56.   else
  57.     MessageDlg('Notepad is not running.', mtInformation, [mbOk], 0);
  58. end;

KarenT

  • Full Member
  • ***
  • Posts: 120
Re: SetWindowPos problem
« Reply #9 on: May 22, 2017, 07:05:18 pm »
Thanks, when I read the Help it said (implied?) that "fsSystemStayOnTop" only stayed on top of all other forms in that program. I want it to stay on top of everything and all the time it is open.

But, I just tried setting the FormStyle to "fsSystemStayOnTop" and it seems to do what I want. So, I either misread the Help or the Help is... :)

 

TinyPortal © 2005-2018