Link to home
Start Free TrialLog in
Avatar of abrakadabra1
abrakadabra1

asked on

Moving a borderless window

Hi

I have a window creted with:

procedure TOknoAbout.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  with Params do
    Style := (Style or WS_POPUP) and (not WS_DLGFRAME);
end;

and a window move procedures that take care of it:

procedure TOknoAbout.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  myszX := X;
  myszY := Y;
end;

procedure TOknoAbout.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
  if shift = [ssLeft] then
    begin
      OknoAbout.Left := OknoAbout.Left + (X - myszX);
      OknoAbout.Top := OknoAbout.Top + (Y - myszY);
    end;
end;


how to modify the formmousemove procedure for it not to let the windows get out of the screen.workarea ??

thanks for any advice
ASKER CERTIFIED SOLUTION
Avatar of TheRealLoki
TheRealLoki
Flag of New Zealand image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of abrakadabra1
abrakadabra1

ASKER

thank you for your help
@TheRealLoki

i have a problem with this. the answer that you gave wasn'e working if the mouse was moved to fat to the screen side. i've modified the procedure to this:

procedure TOknoAbout.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
var
  NewTop, NewLeft : integer;

begin
  if shift = [ssLeft] then
    begin
      NewLeft := OknoAbout.Left + (X - myszX);
      NewTop := OknoAbout.Top + (Y - myszY);
      if ((NewLeft >= 0) and ((NewLeft + OknoAbout.Width) < Screen.WorkAreaWidth)) then
        OknoAbout.Left := NewLeft;
      if ((NewTop >= 0) and ((NewTop + OknoAbout.Height) < Screen.WorkAreaHeight)) then
        OknoAbout.Top := NewTop;
      if (X < 10) then
        OknoAbout.Left := 0;
      if (Y < 10) then
        OknoAbout.Top := 0;
      if (X > (Screen.WorkAreaWidth - 10)) then
        OknoAbout.Left := Screen.WorkAreaWidth - OknoAbout.Width;
      if (Y > (Screen.WorkAreaHeight - 10)) then
        OknoAbout.Top := Screen.WorkAreaHeight - OknoAbout.Height;
    end;
end;

and now the top and left screen side work ok but there is some kind of a problem with this part of the code:

      if (X > (Screen.WorkAreaWidth - 10)) then
        OknoAbout.Left := Screen.WorkAreaWidth - OknoAbout.Width;
      if (Y > (Screen.WorkAreaHeight - 10)) then
        OknoAbout.Top := Screen.WorkAreaHeight - OknoAbout.Height;

now if the mouse is moved to fast to the right or bottom side of the screen the window still stays far on the screen... http://spisik.szm.sk/img.jpg ... any idea how to correct this ??
hmmm, not sure what is happening.
I've simplified the procedure a bit, maybe this will help

uses math;

procedure TOknoAbout.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  myszX := X;
  myszY := Y;
end;

procedure TOknoAbout.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
var
  NewTop, NewLeft : integer;
begin
  if shift = [ssLeft] then
    begin
      NewLeft := OknoAbout.Left + (X - myszX);
      NewTop := OknoAbout.Top + (Y - myszY);

      NewLeft := Max(0, NewLeft);
      NewLeft := Min(Screen.WorkAreaWidth - OknoAbout.Width, NewLeft);
      NewTop := Max(0, NewTop);
      NewTop := Min(Screen.WorkAreaHeight - OknoAbout.Height, NewTop);

      OknoAbout.Left := NewLeft;
      OknoAbout.Top := NewTop;
    end;
end;


btw, another way to move the form is to make it act as a titlebar, eg.
pubic
    procedure WMNCHitTest(var M: TWMNCHitTest); message wm_NCHitTest;

procedure TOknoAbout.WMNCHitTest(var M: TWMNCHitTest);
begin
  inherited;                    { call the inherited message handler }
  if  M.Result = htClient then  { is the click in the client area?   }
    M.Result := htCaption;      { if so, make Windows think it's     }
                                { on the caption bar.                }
end;
just doing the above code, you can move the form around now.

and you can check the position being moved to with
    procedure WMPosChange(var Message: TWMWINDOWPOSCHANGING); message WM_WINDOWPOSCHANGING;
Message.WindowPos.x and Message.WindowPos.y, although I had trouble checking the left bounds, so didn't look into it.