sexta-feira, 8 de maio de 2009

Identificando o em qual Field está o Foco


Contador de acessoVisitas



Pra saber em qual fiel está o foco não é muito difícil, para isso iremos usar algumas API's do Palm OS.

Todas sa rotina estão dentro do arquivo PalmOS/Form.pas e serão elas:
FrmGetActiveForm - retorna o form ativo e sua declaração é function FrmGetActiveForm: FormPtr; external sysTrapFrmGetActiveForm;

FrmGetFocus - retorna o objeto ativo dentro do form. Sua declaração é function FrmGetFocus(const formP: FormPtr): UInt16; external sysTrapFrmGetFocus;

FrmGetObjectType - retorna o tipo de objeto, para sabermos se é um Field. Sua declaração é function FrmGetObjectType(const formP: FormPtr; objIndex: UInt16): FormObjectKind; external sysTrapFrmGetObjectType;

FrmGetObjectID - retorna o ID do Objeto focado, sua declaração é function FrmGetObjectId(const formP: FormPtr; objIndex: UInt16): UInt16; external sysTrapFrmGetObjectId;

Sendo assim, a função abaixo retorna o ID do Filed selecionado ou retorna 0 caso não haja nenhum filed focado.


function FieldFocuse: UInt16;
var
   frm: FormPtr;
   ffoc: UInt16;
begin
   result := 0;

   frm := FrmGetActiveForm;
   ffoc := FrmGetFocus(frm);
   if ffoc=noFocus then exit;
   if FrmGetObjectType(frm, ffoc)<>frmFieldObj then exit;
   result := FrmGetObjectID(frm, ffoc);
end;


O exemplo abaixo mostra como utilizar essa função, o código abaixo deixará invisível o campo Field que estiver focado.


   fieldFoc := FieldFocuse; // fieldFoc é uma variável do tipo UInt16;
   if fieldFoc <> 0 then PSField.Hide(fieldFoc);

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;

terça-feira, 5 de maio de 2009

Alterando a data via código


Contador de acessoVisitas



Os funções para manipulação de data e hora no Pocketstudio são encontradas no arquivo PalmOS/DateTime.pas. Nós iremos usar o tipo DateTimeType e a função TimDateTimeToSeconds que recebe como parâmetro um ponteiro para o tipo DateTimeType.

O tipo DateTimeType é:

DateTimeType = record
   second: Int16;
   minute: Int16;
   hour: Int16;
   day: Int16;
   month: Int16;
   year: Int16;
   weekDay: Int16; // Days since Sunday (0 to 6)
end;


A função TimDateTimeToSeconds é declarada:

function TimDateTimeToSeconds(dateTimeP: DateTimePtr): UInt32; external sysTrapTimDateTimeToSeconds;


De posse dessas informações, basta incluir o código abaixo no evento que fará a alteração da hora. No exemplo abaixo são utilizados valores fixos.


var
   DtHo: DateTimeType;
begin
   DtHo.Day := 4;
   DtHo.Month := 5;
   DtHo.Year := 2009;   DtHo.Hour := 20;
   DtHo.Minute := 15;
   DtHo.Second := 34;

   //Como nossa variável não é um ponteiro e a função requer um ponteiro
   //passaremos o endereço da variável.
   TimSetSeconds(TimDateTimeToSeconds(@DtHo));
end;

segunda-feira, 4 de maio de 2009

Acionar o menu via código


Contador de acessoVisitas


No Palm, para acessar o menu é necessário clicar na barra de título, porém, pode ser que seu form não tenha barra de título, você não quis, sendo assim ele ocupa toda a área da tela.

Então, vou postar aqui uma forma de chamar o menu atravez de um botão.

O menu tem que estar criado normalmente no Resources e associado ao Form.

Para chamar o Menu, nós iremos usar as rotinas abaixo, ambas se encontram no arquivo PalmOS/Menu_.pas.

MenuInit - sua declaração é MenuInit(resourceId: UInt16): MenuBarPtr; external sysTrapMenuInit; Ela retorna o ponteriro para o menu referente ao resourceId passado como parâmetro.

MenuSetActiveMenu - sua declaração é function MenuSetActiveMenu(menuP: MenuBarPtr): MenuBarPtr; external sysTrapMenuSetActiveMenu; Ela ativa o Menu passado como ponteiro no parâmetro.

MenuGetActiveMenu - declaração function MenuGetActiveMenu: MenuBarPtr; external sysTrapMenuGetActiveMenu; Retorna um ponteiro referente ao menu ativo.

MenuDrawMenu - declaração procedure MenuDrawMenu(menuP: MenuBarPtr); external sysTrapMenuDrawMenu; Desenha na tela o menu passado como parâmetro em forma de ponteiro.

Entã, para chamar o menu basta incluir o código abaixo.


MenuSetActiveMenu(MenuInit(Menu1));
MenuDrawMenu(MenuGetActiveMenu);


uma outra forma seria guardar o ponterio do menu que foi ativado, assim não precisaremos usar a função MenuGetActiveMenu, pois já temos o ponteiro para o menu.


var
   MenuP: MenuBarPtr;
begin
   MenuP := MenuInit(Menu1);
   MenuSetActiveMenu(MenuP);
   MenuDrawMenu(MenuP);
end;
Advogados
Visitas