Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2008-04

Unmoveable forms?

17 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Luca Olivetti

With delphi I used a trick involving windows messages to make a form unmoveable:

   procedure WMNCHitTest(var Msg: TWMNCHitTest);message WM_NCHitTest;
   procedure WMInitMenuPopup(var Msg: TWMInitMenuPopUp);message
WM_INITMENUPOPUP;

[...]

procedure TMainFrm.WMNCHitTest(var Msg: TWMNCHitTest);
begin
     inherited;
     if Msg.Result=Windows.HTCAPTION then
     begin
       Msg.Result:= Windows.HTCLIENT
     end;
end;
procedure TMainFrm.WMInitMenuPopup(var Msg: TWMInitMenuPopup);
begin
     inherited;
     if Msg.SystemMenu then
        EnableMenuItem(Msg.MenuPopup, SC_MOVE, MF_BYCOMMAND or MF_GRAYED)
end;

Is there a way to do the same with lazarus? (and possibly in a cross-platform way?).

I tried to crudely reset Top and Left in OnChangeBounds but the effect is really ugly.

Bye

Luca Olivetti Wetron Automatizaci?n S.A. http://www.wetron.es/ Tel. +34 93 5883004 Fax +34 93 5883007

Reply by email

Luca Olivetti

With delphi I used a trick involving windows messages to make a form unmoveable:

   procedure WMNCHitTest(var Msg: TWMNCHitTest);message WM_NCHitTest;
   procedure WMInitMenuPopup(var Msg: TWMInitMenuPopUp);message
WM_INITMENUPOPUP;

[...]

procedure TMainFrm.WMNCHitTest(var Msg: TWMNCHitTest);
begin
     inherited;
     if Msg.Result=Windows.HTCAPTION then
     begin
       Msg.Result:= Windows.HTCLIENT
     end;
end;
procedure TMainFrm.WMInitMenuPopup(var Msg: TWMInitMenuPopup);
begin
     inherited;
     if Msg.SystemMenu then
        EnableMenuItem(Msg.MenuPopup, SC_MOVE, MF_BYCOMMAND or MF_GRAYED)
end;

Is there a way to do the same with lazarus? (and possibly in a cross-platform way?).

I tried to crudely reset Top and Left in OnChangeBounds but the effect is really ugly.

Bye

Luca Olivetti Wetron Automatizaci?n S.A. http://www.wetron.es/ Tel. +34 93 5883004 Fax +34 93 5883007

Reply by email

Felipe Monteiro de Carvalho
to Luca Olivetti: With delphi I used a trick involving windows messages to make a form unmoveable:…
Luca Olivetti wrote
With delphi I used a trick involving windows messages to make a form unmoveable:

I don't think this is implementable in a cross-platform way. On X11 the conection with the window manager is loose, and it may ignore any request you make.

If you don't want the user to move the form and set the borderstyle to bsNone. You can paint your own title if you really need one.

Having said that, I can't imagine why one would wish to do this.

Felipe Monteiro de Carvalho

Reply by email

Luca Olivetti
to Felipe Monteiro de Carvalho

En/na Felipe Monteiro de Carvalho ha escrit:

Show quoted text 7 lines
On Wed, Apr 16, 2008 at 11:12 AM, Luca Olivetti wrote: > With delphi I used a trick involving windows messages to make a form > unmoveable: I don't think this is implementable in a cross-platform way. On X11 the conection with the window manager is loose, and it may ignore any request you make.

Well, I just need it under windows right now, it would just be nice if it could be done in a cross platform way, but it's not a strict requirement

If you don't want the user to move the form and set the borderstyle to bsNone. You can paint your own title if you really need one.

Oh, but I like the system-drawn title bar with the application icon and the big X to close the form ;-)

Having said that, I can't imagine why one would wish to do this.

My main reason is that the layout of the screeen(s) has to be fixed, besides avoiding the dragging of the form avoids freezing threads waiting on a Synchronize (though dragging a scrollbar will freeze them anyway, and that's really bad for my application). I'm not the only one with such a need (i.e. unmoveable forms), since I found that trick somewhere in the internet many years ago.

Bye

Luca Olivetti Wetron Automatizaci?n S.A. http://www.wetron.es/ Tel. +34 93 5883004 Fax +34 93 5883007

Reply by email

Luca Olivetti
to Luca Olivetti

En/na Luca Olivetti ha escrit:

Show quoted text 25 lines
En/na Felipe Monteiro de Carvalho ha escrit: > On Wed, Apr 16, 2008 at 11:12 AM, Luca Olivetti wrote: >> With delphi I used a trick involving windows messages to make a form >> unmoveable: > I don't think this is implementable in a cross-platform way. On X11 > the conection with the window manager is loose, and it may ignore any > request you make. Well, I just need it under windows right now, it would just be nice if it could be done in a cross platform way, but it's not a strict requirement > If you don't want the user to move the form and set the borderstyle to > bsNone. You can paint your own title if you really need one. Oh, but I like the system-drawn title bar with the application icon and the big X to close the form ;-) > Having said that, I can't imagine why one would wish to do this. My main reason is that the layout of the screeen(s) has to be fixed, besides avoiding the dragging of the form avoids freezing threads waiting on a Synchronize (though dragging a scrollbar will freeze them anyway, and that's really bad for my application). I'm not the only one with such a need (i.e. unmoveable forms), since I found that trick somewhere in the internet many years ago.

I'm sorry to revive this old thread, but I'm going to need it, at least under windows.
Any other suggestion (besides BorderStyle:=bsNone)?

As a remainder, with delphi I used to to this:

    procedure WMNCHitTest(var Msg: TWMNCHitTest);message WM_NCHitTest;
    procedure WMInitMenuPopup(var Msg: TWMInitMenuPopUp);message
WM_INITMENUPOPUP;
procedure TMainFrm.WMNCHitTest(var Msg: TWMNCHitTest);
begin
      inherited;
      if Msg.Result=Windows.HTCAPTION then
      begin
        Msg.Result:= Windows.HTCLIENT
      end;
end;
procedure TMainFrm.WMInitMenuPopup(var Msg: TWMInitMenuPopup);
begin
      inherited;
      if Msg.SystemMenu then
         EnableMenuItem(Msg.MenuPopup, SC_MOVE, MF_BYCOMMAND or MF_GRAYED)
end;

Bye

Luca Olivetti Wetron Automatizaci?n S.A. http://www.wetron.es/ Tel. +34 93 5883004 Fax +34 93 5883007

Reply by email

Luca Olivetti
to Luca Olivetti: En/na Felipe Monteiro de Carvalho ha escrit: Well, I just need it under windows right…

En/na Luca Olivetti ha escrit:

My main reason is that the layout of the screeen(s) has to be fixed, besides avoiding the dragging of the form avoids freezing threads waiting on a Synchronize (though dragging a scrollbar will freeze them anyway, and that's really bad for my application).

I now found out that this bad behaviour is lazarus specific: under delphi I can drag the window and/or the scrollbar and the synchronized procedure won't stop the thread, while under lazarus it does. This is *really* bad, since a user could inadvertently stop the background threads.
I could try some workaround (i.e not using synchronize but set some variables in the main form and use a timer to update the visual compnents) but it's ugly and error-prone.

I opened a bug with an example program
http://bugs.freepascal.org/view.php?id=11561

Later I'll try if under linux it does the same.

Bye

Luca Olivetti Wetron Automatizaci?n S.A. http://www.wetron.es/ Tel. +34 93 5883004 Fax +34 93 5883007

Reply by email

Graeme Geldenhuys
to Luca Olivetti

2008/6/26 Luca Olivetti :

Show quoted text 13 lines
> My main reason is that the layout of the screeen(s) has to be fixed, > besides avoiding the dragging of the form avoids freezing threads > waiting on a Synchronize (though dragging a scrollbar will freeze them > anyway, and that's really bad for my application). I now found out that this bad behaviour is lazarus specific: under delphi I can drag the window and/or the scrollbar and the synchronized procedure won't stop the thread, while under lazarus it does. This is *really* bad, since a user could inadvertently stop the background threads. I could try some workaround (i.e not using synchronize but set some variables in the main form and use a timer to update the visual compnents) but it's ugly and error-prone.

I don't think it's just Lazarus. I think Windows is to blame as well. I have noticed the same freezing behavior on numerous occasions under Win2000 and WinXP. eg: I was coping files with Windows Explorer. I then scrolled some other windows with the mouse button down on the scrollbar. The copying stopped until I released the mouse! This happened over and over. No idea if it's related to your problem though. What I can say, is that nothing like this has never happened under Linux.

Regards,
- Graeme -

_______________________________________________
fpGUI - a cross-platform Free Pascal GUI toolkit
http://opensoft.homeip.net/fpgui/

Reply by email

Kostas Michalopoulos
to Luca Olivetti: En/na Luca Olivetti ha escrit: I'm sorry to revive this old thread, but I'm going to need…

Thats a hack, but it will probably work:
1. Save the size/position in a TRect when onShow event occurs
2. Put a timer that periodically (say, every 50ms or so) checks if the size or position changed and restore it if so

A 50ms timer won't create any kind of resource waste (ok, it might eat 000000025% of your CPU :-P), but the dragging back to the original place will be visible. But that shouldn't be a problem i think.

Kostas

Earlier message 68 lines
----- Original Message ----- From: "Luca Olivetti" To: "General mailing list" Sent: Thursday, June 26, 2008 5:43 PM Subject: Re: [Lazarus] Unmoveable forms? En/na Luca Olivetti ha escrit: > En/na Felipe Monteiro de Carvalho ha escrit: >> On Wed, Apr 16, 2008 at 11:12 AM, Luca Olivetti wrote: >>> With delphi I used a trick involving windows messages to make a form >>> unmoveable: >> I don't think this is implementable in a cross-platform way. On X11 >> the conection with the window manager is loose, and it may ignore any >> request you make. > > Well, I just need it under windows right now, it would just be nice if > it could be done in a cross platform way, but it's not a strict > requirement > >> If you don't want the user to move the form and set the borderstyle to >> bsNone. You can paint your own title if you really need one. > > Oh, but I like the system-drawn title bar with the application icon and > the big X to close the form ;-) > >> Having said that, I can't imagine why one would wish to do this. > > My main reason is that the layout of the screeen(s) has to be fixed, > besides avoiding the dragging of the form avoids freezing threads > waiting on a Synchronize (though dragging a scrollbar will freeze them > anyway, and that's really bad for my application). > I'm not the only one with such a need (i.e. unmoveable forms), since I > found that trick somewhere in the internet many years ago. I'm sorry to revive this old thread, but I'm going to need it, at least under windows. Any other suggestion (besides BorderStyle:=bsNone)? As a remainder, with delphi I used to to this: procedure WMNCHitTest(var Msg: TWMNCHitTest);message WM_NCHitTest; procedure WMInitMenuPopup(var Msg: TWMInitMenuPopUp);message WM_INITMENUPOPUP; procedure TMainFrm.WMNCHitTest(var Msg: TWMNCHitTest); begin inherited; if Msg.Result=Windows.HTCAPTION then begin Msg.Result:= Windows.HTCLIENT end; end; procedure TMainFrm.WMInitMenuPopup(var Msg: TWMInitMenuPopup); begin inherited; if Msg.SystemMenu then EnableMenuItem(Msg.MenuPopup, SC_MOVE, MF_BYCOMMAND or MF_GRAYED) end; Bye -- Luca Olivetti Wetron Automatizaci?n S.A. http://www.wetron.es/ Tel. +34 93 5883004 Fax +34 93 5883007

Reply by email

Luca Olivetti
to Kostas Michalopoulos

En/na Kostas Michalopoulos ha escrit:

Thats a hack, but it will probably work: 1. Save the size/position in a TRect when onShow event occurs 2. Put a timer that periodically (say, every 50ms or so) checks if the size or position changed and restore it if so

Already tried it (used OnChangeBounds instead of a timer) and the effect is horrible.

Bye

Luca Olivetti Wetron Automatizaci?n S.A. http://www.wetron.es/ Tel. +34 93 5883004 Fax +34 93 5883007

Reply by email

Luca Olivetti
to Graeme Geldenhuys: 2008/6/26 Luca Olivetti : I don't think it's just Lazarus. I think Windows is to blame as…

En/na Graeme Geldenhuys ha escrit:

Show quoted text 8 lines
> This is *really* bad, since a user could inadvertently stop the > background threads. > I could try some workaround (i.e not using synchronize but set some > variables in the main form and use a timer to update the visual > compnents) but it's ugly and error-prone. I don't think it's just Lazarus. I think Windows is to blame as well.

Maybe, but the same problem with delphi (or with lazarus under Linux) doesn't stop my thread.

Bye

Luca Olivetti Wetron Automatizaci?n S.A. http://www.wetron.es/ Tel. +34 93 5883004 Fax +34 93 5883007

Reply by email

Luca Olivetti
to Luca Olivetti

En/na Luca Olivetti ha escrit:

Show quoted text 12 lines
En/na Graeme Geldenhuys ha escrit: >> This is *really* bad, since a user could inadvertently stop the >> background threads. >> I could try some workaround (i.e not using synchronize but set some >> variables in the main form and use a timer to update the visual >> compnents) but it's ugly and error-prone. > > I don't think it's just Lazarus. I think Windows is to blame as well. Maybe, but the same problem with delphi (or with lazarus under Linux) doesn't stop my thread.

I meant "the same program"

Bye

Luca Olivetti Wetron Automatizaci?n S.A. http://www.wetron.es/ Tel. +34 93 5883004 Fax +34 93 5883007

Reply by email

Luca Olivetti
to Luca Olivetti: En/na Graeme Geldenhuys ha escrit: Maybe, but the same problem with delphi (or with…

En/na Luca Olivetti ha escrit:

Show quoted text 12 lines
En/na Graeme Geldenhuys ha escrit: >> This is *really* bad, since a user could inadvertently stop the >> background threads. >> I could try some workaround (i.e not using synchronize but set some >> variables in the main form and use a timer to update the visual >> compnents) but it's ugly and error-prone. > > I don't think it's just Lazarus. I think Windows is to blame as well. Maybe, but the same problem with delphi (or with lazarus under Linux) doesn't stop my thread.

I've been debugging the lcl and effectively it's windows that's blocking the main loop (I've added that information to the bug report).

However timers doesn't suffer the same fate, so, as a simple workaround, I can put a timer on the main form that in turn calls CheckSynchronize.

Do you see any adverse effect of this workaround?
I mean, I think the timer fires in the context of the main thread (otherwise checksynchronize would raise an exception) but outside the main application loop.

Bye

Luca Olivetti Wetron Automatizaci?n S.A. http://www.wetron.es/ Tel. +34 93 5883004 Fax +34 93 5883007

Reply by email

Graeme Geldenhuys
to Luca Olivetti
Luca Olivetti wrote
Do you see any adverse effect of this workaround? I mean, I think the timer fires in the context of the main thread (otherwise checksynchronize would raise an exception) but outside the main application loop.

I can't see any issue with that workaround. As for the LCL internals, I'm not very knowledable about that, sorry.

Regards,
- Graeme -

_______________________________________________
fpGUI - a cross-platform Free Pascal GUI toolkit
http://opensoft.homeip.net/fpgui/

Reply by email

Luca Olivetti
to Felipe Monteiro de Carvalho

En/na Felipe Monteiro de Carvalho ha escrit:

Just use the same code you were using in Delphi. It will work in Windows only.

No, the same code doesn't work, I don't receive the messages, probably the LCL isn't forwarding them.
I tried both with WM_NCHITTEST and LM_NCHITTEST.

What I got mostly working is to use SetWindowProc as per http://wiki.lazarus.freepascal.org/Win32/64_Interface#Processing_non-user_messages_in_your_window

at least for WM_NCHITTEST, not yet for WM_INITMENUPOPUP.

Bye

Luca Olivetti Wetron Automatizaci?n S.A. http://www.wetron.es/ Tel. +34 93 5883004 Fax +34 93 5883007

Reply by email

Luca Olivetti
to Luca Olivetti

En/na Luca Olivetti ha escrit:

Show quoted text 9 lines
En/na Felipe Monteiro de Carvalho ha escrit: > Just use the same code you were using in Delphi. It will work in Windows only. No, the same code doesn't work, I don't receive the messages, probably the LCL isn't forwarding them. I tried both with WM_NCHITTEST and LM_NCHITTEST. What I got mostly working is to use SetWindowProc as per http://wiki.lazarus.freepascal.org/Win32/64_Interface#Processing_non-user_messages_in_your_window

I added what I did as an example in the wiki

at least for WM_NCHITTEST, not yet for WM_INITMENUPOPUP.

I cannot make it work, I put this code in my handler:

   if uMsg=WM_INITMENUPOPUP then
   begin
     if hi(LParam)0 then
     begin
       EnableMenuItem(HMENU(WParam), SC_MOVE, MF_BYCOMMAND or MF_GRAYED);
       result:=0;
       exit;
     end
   end;

I get the message, LParam indicates it's the system menu, I call EnableMenuItem but the "move" command is still there enabled.

Bye

Luca Olivetti Wetron Automatizaci?n S.A. http://www.wetron.es/ Tel. +34 93 5883004 Fax +34 93 5883007

Reply by email

Luca Olivetti
to Felipe Monteiro de Carvalho: Just use the same code you were using in Delphi. It will work in Windows only. What you…

En/na Felipe Monteiro de Carvalho ha escrit:

Just use the same code you were using in Delphi. It will work in Windows only. What you wish is impossible to implement anywhere else.

BTW, the window manager I'm currently using (the default one under kde, I think it's kwin) has a bunch of options, among them there's one to keep a window in a fixed position, so in theory it should possible (if not 100% guaranteed with all wm) to do it under Linux. See:

http://standards.freedesktop.org/wm-spec/wm-spec-1.3.html#id2507474

Bye

Luca Olivetti Wetron Automatizaci?n S.A. http://www.wetron.es/ Tel. +34 93 5883004 Fax +34 93 5883007

Reply by email