sexta-feira, 8 de maio de 2009

Movimentando o Form


Contador de acessoVisitas



Neste post resolvi mostrar como mudar a posição do form via código. Para melhorar a "brincadeira", resolvi fazer o form se movimentar ao se arrastar a caneta igual a movimentação em uma janela desktop.

Para fazer essa movimentação, será necessário a utilização:

Dos tipos

FormPtr - encontra-se no arquivo PalmOS/Form.pas

   FormType = record
   {$ifdef ALLOW_ACCESS_TO_INTERNALS_OF_FORMS} // These fields will not be available in the next OS release!
      window: WindowType;
      formId: UInt16;
      attr: FormAttrType;
      bitsBehindForm: WinHandle;
      handler: FormEventHandlerType;
      focus: UInt16;
      defaultButton: UInt16;
      helpRscId: UInt16;
      menuRscId: UInt16;
      numObjects: UInt16;
      objects: ^FormObjListType;
   {$endif}
   end;

   FormPtr = ^FormType;



WinHandle - encontra-se no arquivo PalmOS/Window.pas

WindowType = record
   {$ifdef ALLOW_ACCESS_TO_INTERNALS_OF_WINDOWS} // These fields will not be available in the next OS release!
      displayWidthV20: Coord; // use WinGetDisplayExtent instead
      displayHeightV20: Coord; // use WinGetDisplayExtent instead
      displayAddrV20: Pointer; // use the drawing functions instead
      windowFlags: WindowFlagsType;
      windowBounds: RectangleType;
      clippingBounds: AbsRectType;
      bitmapP: BitmapPtr;
      frameType: FrameBitsType;
      drawStateP: ^DrawStateType; // was GraphicStatePtr
      nextWindow: ^WindowType;
   {$endif}
   end;

   WinPtr = ^WindowType;
   WinHandle = ^WindowType;


RectangleType - encontra-se no arquivo PalmOS/Rect.pas


   PointType = record
      x: Coord;
      y: Coord;
   end;
   PointPtr = ^PointType;

   RectangleType = record
      topLeft: PointType;
      extent: PointType;
   end;



Precisamos também das rotinas que se encontram no arquivo PalmOS/Form.pas

FrmGetActiveForm
function FrmGetActiveForm: FormPtr; external sysTrapFrmGetActiveForm;

FrmGetWindowHandle(Frm);
function FrmGetWindowHandle(const formP: FormPtr): WinHandle; external sysTrapFrmGetWindowHandle;

FrmGetFormBounds
procedure FrmGetFormBounds(const formP: FormPtr; var rP: RectangleType); external sysTrapFrmGetFormBounds;


FrmDrawForm(Frm);
procedure FrmDrawForm(formP: FormPtr); external sysTrapFrmDrawForm;


e no arquivo PalmOS/Window.pas

WinSetBounds(Wnd, rp);
procedure WinSetBounds(winHandle: WinHandle; {const} var rP: RectangleType); external sysTrapWinSetBounds;

o código para movimentação do form é bem simples. Criar as variável privadas que irão armazenar o ponto de toque.


var
    posX: int16;
    posY: int16;


No evento PenDown do form, o código

procedure Form1PenDown(X, Y: Int16);
begin
   posX:=X;
   posY:=Y;
   PSApplication.Handled := False; // leave event unhandled
end;


Obs.: o form não pode ser desenhado em posição negativa, ou seja o canto superior direito não pode estar acima da posição 0 e também não pode estar mais a esquerda do que a posição 0.

Sendo assim, o codigo do evento PenMove ficará


procedure Form1PenMove(X, Y: Int16);
var
    DifX: integer;
    DifY: integer;

    Frm: FormPtr;
    Wnd: WinHandle;
    rp: RectangleType;
begin
   if PenDown then
       begin
            DifX := X - posX;
            DifY := Y - posY;

            //Pega o form ativo
            Frm := FrmGetActiveForm;

            //Pega o Handle do form ativo
            Wnd := FrmGetWindowHandle(Frm);

            //Pega os valores de grafico do form
            FrmGetFormBounds(Frm, rp);

            //garante que o calculo de quanto se movel a caneta não será inferior a 0, o que causaria um erro
            posX := rp.TopLeft.x + DifX;
            if posX < 0 then posX := 0;
            posY := rp.TopLeft.y + DifY;
            if posY < 0 then posY := 0;

            //Repondo os valores corretos
            rp.TopLeft.x := posX;
            rp.TopLeft.y := posY;

            //setando os novos valores do form
            WinSetBounds(Wnd, rp);

            //redesenhando o Form
            FrmDrawForm(Frm);
       end;

       posX := X;
       posY := Y;

   PSApplication.Handled := False; // leave event unhandled
end;

Nenhum comentário:

Postar um comentário

Advogados
Visitas