Ir para conteúdo
Faça parte da equipe! (2024) ×
Conheça nossa Beta Zone! Novas áreas a caminho! ×
  • Quem está por aqui   0 membros estão online

    • Nenhum usuário registrado visualizando esta página.

Varias dicas de Formulários - Delphi


Surfistinha£
 Compartilhar

Posts Recomendados

Lista de Dicas

* Forçar foco em janela

* Anexar dois forms

* Impedir que o form seja fechado com Alt+F4

* Impedir que o form seja arrastado para fora das margens da tela

* Enviar comandos de rolagem vertical para um TMemo

* Construir a barra de título do form com um Panel

* Criar form sem título que possa ser arrastado

* Criar caixas de diálogo em tempo de execução

* Determinar se uma janela (form) está maximizada

* Determinar se o aplicativo está minimizado

* Maximizar um form de forma que cubra toda a tela, inclusive a barra de tarefas

* Posicionar Form's em relação ao Desktop do Windows

* Salvar/restaurar o tamanho e posição de Form's

* Mostrar um Form de LogOn antes do Form principal

* Fazer a barra de título ficar intermitente (piscante)

 

 

 

 

Forçar foco em janela

 

As funções abaixo forçam para que a janela informada fique em primeiro plano.

 

Primeira alternativa

 

function ForceForegroundWindow(hwnd: THandle): Boolean;

const

SPI_GETFOREGROUNDLOCKTIMEOUT = $2000;

SPI_SETFOREGROUNDLOCKTIMEOUT = $2001;

var

ForegroundThreadID: DWORD;

ThisThreadID: DWORD;

timeout: DWORD;

begin

if IsIconic(hwnd) then ShowWindow(hwnd, SW_RESTORE);

 

if GetForegroundWindow = hwnd then Result := True

else

begin

// Windows 98/2000 doesn't want to foreground a window when some other

// window has keyboard focus

 

if ((Win32Platform = VER_PLATFORM_WIN32_NT) and (Win32MajorVersion > 4)) or

((Win32Platform = VER_PLATFORM_WIN32_WINDOWS) and

((Win32MajorVersion > 4) or ((Win32MajorVersion = 4) and

(Win32MinorVersion > 0)))) then

begin

// Code from Karl E. Peterson,

É necessário se cadastrar para acessar o conteúdo.

// Converted to Delphi by Ray Lischner

// Published in The Delphi Magazine 55, page 16

 

Result := False;

ForegroundThreadID := GetWindowThreadProcessID(GetForegroundWindow, nil);

ThisThreadID := GetWindowThreadPRocessId(hwnd, nil);

if AttachThreadInput(ThisThreadID, ForegroundThreadID, True) then

begin

BringWindowToTop(hwnd); // IE 5.5 related hack

SetForegroundWindow(hwnd);

AttachThreadInput(ThisThreadID, ForegroundThreadID, False);

Result := (GetForegroundWindow = hwnd);

end;

if not Result then

begin

// Code by Daniel P. Stasinski

SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, @timeout, 0);

SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, TObject(0),

SPIF_SENDCHANGE);

BringWindowToTop(hwnd); // IE 5.5 related hack

SetForegroundWindow(hWnd);

SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, TObject(timeout), SPIF_SENDCHANGE);

end;

end

else

begin

BringWindowToTop(hwnd); // IE 5.5 related hack

SetForegroundWindow(hwnd);

end;

 

Result := (GetForegroundWindow = hwnd);

end;

end; { ForceForegroundWindow }

 

 

Segunda alternativa

 

A função abaixo consegue forçar o foco na janela especificada criando-se um formulário com dimensão de um apenas 1 ponto e simulando um clique de mouse neste formulário para que a aplicação receba o foco de entrada. Em seguida a janela especificada é colocada em primeiro plano usando-se a função SetForegroundWindow da API do Windows.

 

procedure ForceForegroundWindow(hwnd: THandle);

// (W) 2001 Daniel Rolf

//

É necessário se cadastrar para acessar o conteúdo.

// [email protected]

var

hlp: TForm;

begin

hlp := TForm.Create(nil);

try

hlp.BorderStyle := bsNone;

hlp.SetBounds(0, 0, 1, 1);

hlp.FormStyle := fsStayOnTop;

hlp.Show;

mouse_event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);

mouse_event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);

SetForegroundWindow(hwnd);

finally

hlp.Free;

end;

end;

 

 

Terceira alternativa

 

A biblioteca USER32.DLL possui uma função não documentada que propõe forçar o foco em determinada janela. A declaração da função é:

 

procedure SwitchToThisWindow(h1: hWnd; x: bool); stdcall;

external user32 Name 'SwitchToThisWindow';

{x = false: Size unchanged, x = true: normal size}

 

{ Exemplo }

 

procedure TForm1.Button2Click(Sender: TObject);

begin

SwitchToThisWindow(FindWindow('notepad', nil), True);

end;

 

 

Atenção!

 

Nos testes que fiz usando Windows XP Professional e Delphi 6, a primeira e segunda alternativas funcionaram perfeitamente. A última não funcionou nos testes, mas foi mantida aqui para que outras pessoas possam experimentá-la.

 

Anexar dois forms

 

É comum encontrarmos aplicativos que possuem dois ou mais

formulários que se mantém o tempo todo "colados" um ao outro.

É o caso, por exemplo, do conhecido Winamp. Como fazer isto

em aplicações Delphi? Vamos aos passos:

 

1. Crie um novo projeto com um form (Form1).

2. Adicione mais um form (Form2).

3. Declare os métodos abaixo na seção private do Form1:

 

private

procedure AjustarForm2;

procedure WMMove(var Msg: TMessage); message WM_MOVE;

 

4. Abaixo da palavra implementation escreva:

 

procedure TForm1.AjustarForm2;

begin

if Form2 <> nil then begin

Form2.Width := Width;

Form2.Left := Left;

Form2.Top := Top + Height;

end;

end;

 

procedure TForm1.WMMove(var Msg: TMessage);

begin

AjustarForm2;

end;

 

5. Escreva o evento OnShow do Form1 como abaixo:

 

procedure TForm1.FormShow(Sender: TObject);

begin

Form2.Show;

end;

 

6. Escreve o evento OnHide do Form1 como abaixo:

 

procedure TForm1.FormHide(Sender: TObject);

begin

Form2.Hide;

end;

 

7. Escreve o evento OnReSize do Form1 como abaixo:

 

procedure TForm1.FormResize(Sender: TObject);

begin

AjustarForm2;

end;

 

Pronto! Execute e experimente arrastar ou redimensionar o

Form1 para ver o efeito.

 

 

Observações

 

Neste exemplo, se o usuário mexer no Form2 o Form1 não se ajustará automaticamente. Existem no mínimo duas alternativas para resolver este caso: deixar o Form2 sem borda ou codificar os eventos do Form2 para ajustar o Form1.

 

Impedir que o form seja fechado com Alt+F4

 

 

Este é um problema fácil de resolver. Vejamos porque.

 

Toda vez que um form recebe um comando para ser fechado,

tal como Form1.Close ou mesmo uma mensagem WM_CLOSE, o evento

OnCloseQuery é disparado. Este evento passa um parâmetro por

referência normalmente chamado CanClose. Se alternarmos o valor

deste parâmetro para false o processo de fechar o formulário

será cancelado.

 

Uma vez que queremos impedir que o form seja fechado com

Alt+F4, temos que dar ao usuário outra forma de fechá-lo.

Neste exemplo vamos colocar um botão para esta tarefa.

 

Vamos aos passos:

 

1. Declare um campo (variável) na seção private do Form:

 

private

FPodeFechar: boolean;

 

2. No evento OnCreate do form coloque:

 

FPodeFechar := false;

 

3. No evento OnCloseQuery do form coloque:

 

CanClose := FPodeFechar;

 

4. Coloque um botão no form e no seu evento Click coloque:

 

FPodeFechar := true;

Close;

 

Pronto! Execute e teste.

 

Impedir que o form seja arrastado para fora das margens da tela

 

- Na seção Private declare a procedure abaixo:

 

private

procedure WMMove(var Msg: TWMMove); message WM_MOVE;

 

- Abaixo da palavra implementation escreva a procedure

abaixo:

 

procedure TForm1.WMMove(var Msg: TWMMove);

begin

if Left < 0 then

Left := 0;

if Top < 0 then

Top := 0;

if Screen.Width - (Left + Width) < 0 then

Left := Screen.Width - Width;

if Screen.Height - (Top + Height) < 0 then

Top := Screen.Height - Height;

end;

 

Para testar:

 

- Execute o programa e tente arrastar o form para fora

das margens da tela e veja o que acontece.

 

Enviar comandos de rolagem vertical para um TMemo

 

Inclua na seção uses: Windows

 

Problema:

 

Gostaria que o meu programa rolasse automaticamente o

conteúdo de um TMemo, simulando o deslizamento da barra de

rolagem vertical. Isto é possível no Delphi?

 

Solução:

 

Sim. Utilizando mensagens do Windows isto é fácil. Vejamos

algums exemplos:

 

SendMessage(Memo1.Handle, WM_VSCROLL, SBPAGEDOWN, 0);

 

Onde:

Memo1.Handle = manipulador da janela do Memo1.

WM_VSCROLL = Mensagem do Windows - rolagem vertical.

SB_PAGEDOWN = Comanndo de rolagem - página para baixo.

 

Outros exemplos:

 

{ Página para cima }

SendMessage(Memo1.Handle, WM_VSCROLL, SBPAGEUP, 0);

 

{ Linha para baixo }

SendMessage(Memo1.Handle, WM_VSCROLL, SBLINEDOWN, 0);

 

{ Linha para cima }

SendMessage(Memo1.Handle, WM_VSCROLL, SBLINEUP, 0);

 

 

Observações

 

Além desta técnica existem API's do Windows que fazem um trabalho equivalente.

 

Criar form sem título que possa ser arrastado

 

Problema:

 

Fazer um relógio num form é fácil. Porém gostaria que esse

form não possuísse a barra de título, mas que o usuário

ainda pudesse arrastá-lo com o mouse. Isto é possível

no Delphi?

 

Solução:

 

Sim, é possível e é fácil. Siga os passos abaixo:

 

- Crie um novo projeto;

- Mude as seguintes propriedades do Form1:

BorderStyle = bsNone, FormStyle = fsStayOnTop,

- Coloque um Label;

- Coloque um Timer;

- Altere o evento OnTimer do Timer1 conforme abaixo:

 

procedure TForm1.Timer1Timer(Sender: TObject);

begin

Label1.Caption := TimeToStr(Time);

end;

 

- Altere o evento OnCreate do Form1 conforme abaixo:

 

procedure TForm1.FormCreate(Sender: TObject);

begin

Width := 80;

Height := 40;

Label1.Left := 10;

Label1.Top := 10;

end;

 

- Vá na seção private do Form1 e declare a procedure abaixo:

 

private

procedure WMNCHitTest(var Msg: TMessage);

message WM_NCHitTest;

public

{ Public declarations }

end;

 

- Vá na seção implementation e escreva a procedure abaixo:

 

implementation

 

{$R *.DFM}

 

procedure TForm1.WMNCHitTest(var Msg: TMessage);

begin

if GetAsyncKeyState(VK_LBUTTON) < 0 then

Msg.Result := HTCAPTION

else

Msg.Result := HTCLIENT;

end;

 

- Execute e experimente arrastar form com o mouse.

 

 

Observações

 

Para fechar este aplicativo pressione Alt+F4. Uma alternativa mais elegante é colocar um menu local (PopupMenu) com um comando para fechar.

 

Criar caixas de diálogo em tempo de execução

 

Inclua na seção uses: Forms, StdCtrls, Buttons

 

A função abaixo demonstra a criação de uma caixa de diálogo

que pode ser usada para permitir ao usuário digitar o seu

nome:

 

{ Esta função retorna true se for pressionado OK e false

em caso contrário. Se for OK, o texto digitado pelo usuário

será copiado para a variável Nome }

 

function ObterNome(var Nome: string): boolean;

var

Form: TForm; { Variável para o Form }

Edt: TEdit; { Variável para o Edit }

begin

Result := false; { Por padrão retorna false }

{ Cria o form }

Form := TForm.Create(Application);

try

{ Altera algumas propriedades do Form }

Form.BorderStyle := bsDialog;

Form.Caption := 'Atenção';

Form.Position := poScreenCenter;

Form.Width := 200;

Form.Height := 150;

{ Coloca um Label }

with TLabel.Create(Form) do begin

Parent := Form;

Caption := 'Digite seu nome:';

Left := 10;

Top := 10;

end;

{ Coloca o Edit }

Edt := TEdit.Create(Form);

with Edt do begin

Parent := Form;

Left := 10;

Top := 25;

{ Ajusta o comprimento do Edit de acordo com a largura

do form }

Width := Form.ClientWidth - 20;

end;

{ Coloca o botão OK }

with TBitBtn.Create(Form) do begin

Parent := Form;

{ Posiciona de acordo com a largura do form }

Left := Form.ClientWidth - (Width * 2) - 20;

Top := 80;

Kind := bkOK; { Botão Ok }

end;

{ Coloca o botão Cancel }

with TBitBtn.Create(Form) do begin

Parent := Form;

Left := Form.ClientWidth - Width - 10;

Top := 80;

Kind := bkCancel; { Botão Cancel }

end;

{ Exibe o form e aguarda a ação do usuário. Se for OK... }

if Form.ShowModal = mrOK then begin

Nome := Edt.Text;

Result := true;

end;

finally

Form.Free;

end;

end;

 

Para chamar esta função siga o exemplo abaixo:

 

procedure TForm1.Button1Click(Sender: TObject);

var

S: string;

begin

if ObterNome(S) then

Edit1.Text := S;

end;

 

 

Observações

 

Os componentes Label, Edit (var Edt) e BitBtn's (botões) não são destruídos explicitamente (Componente.Free). Isto não é necessário, pois ao criá-los informei como proprietário o Form (ex: TLabel.Create(Form)). Neste caso, estes componentes são destruídos automaticamente ao destruir o Form (Form.Free).

 

Determinar se uma janela (form) está maximizada

 

Inclua na seção uses: Windows

 

if IsZoomed(Form1.Handle) then

{ Form1 está maximizado }

else

{ Form2 NÃO está maximizado }

 

Determinar se o aplicativo está minimizado

 

Inclua na seção uses: Windows

 

if IsIconic(Application.Handle) then

{ Minimizado }

else

{ Não minimizado }

 

 

 

Maximizar um form de forma que cubra toda a tela, inclusive a barra de tarefas

 

{ É um "maximizar" com jeitinho brasileiro... mas funciona.

No evento OnShow do form coloque o código abaixo: }

 

Top := 0;

Left := 0;

Width := Screen.Width;

Height := Screen.Height;

 

 

Observações

 

Nos testes que fiz, mesmo com a barra de tarefas marcada como "Sempre Visível", funcionou perfeitamente. Fiz os testes usando o Win95. Talvez em novas versões, possa apresentar problemas.

 

Posicionar Form's em relação ao Desktop do Windows

 

{ Quando usamos a propridade Position de um Form para

centralizá-lo estamos sujeitos a um inconveniente:

dependendo da posição/tamanho da barra de tarefas do

Windows, o nosso Form poderá ficar parcialmente coberto

por ela. Uma forma eficaz de resolver este problema é

posicionar o form considerando apenas a área livre do

Desktop. Vejamos este exemplo:

 

- Crie um novo projeto;

- Na seção implementation digite a procedure abaixo:

}

 

procedure FormPos(Form: TForm; const Horz, Vert: byte);

{ Horz: 1=esquerda, 2=centro, 3=direita

Vert: 1=topo, 2=centro, 3=em baixo }

var

R: TRect;

begin

if not SystemParametersInfo(SPI_GETWORKAREA, 0, @R, 0) then

R := Rect(0, 0, Screen.Width, Screen.Height);

with Form do

case Horz of

1: Form.Left := 0;

2: Form.Left := (R.Right - R.Left - Width) div 2;

3: Form.Left := R.Right - Width;

end;

with Form do

case Vert of

1: Form.Top := 0;

2: Form.Top := (R.Bottom - R.Top - Height) div 2;

3: Form.Top := R.Bottom - Height;

end;

end;

 

{ - Coloque dois TEdit's: Edit1 e Edit2;

- Coloque um TButton e altere o evento OnClick deste

conforme abaixo:

}

 

procedure TForm1.Button1Click(Sender: TObject);

begin

FormPos(Form1, StrToInt(Edit1.Text), StrToInt(Edit2.Text));

end;

 

 

Observações

 

Para testar, execute este exemplo e experimente digitar números de 1 a 3 em ambos os Edit's e clique no Button para ver o resultado. O Edit1 indica a posição horizontal (esquerda, centro e direita) e o Edit2 indica a posição vertical (topo, centro e em baixo).

 

Salvar/restaurar o tamanho e posição de Form's

 

{ Crie uma nova Unit conforme abaixo: }

unit uFormFunc;

 

interface

uses Forms, IniFiles, SysUtils, Messages, Windows;

 

procedure tbLoadFormStatus(Form: TForm; const Section: string);

procedure tbSaveFormStatus(Form: TForm; const Section: string);

 

implementation

 

procedure tbSaveFormStatus(Form: TForm; const Section: string);

var

Ini: TIniFile;

Maximized: boolean;

begin

Ini := TIniFile.Create(ChangeFileExt(

ExtractFileName(ParamStr(0)),'.INI'));

try

Maximized := Form.WindowState = wsMaximized;

Ini.WriteBool(Section, 'Maximized', Maximized);

if not Maximized then begin

Ini.WriteInteger(Section, 'Left', Form.Left);

Ini.WriteInteger(Section, 'Top', Form.Top);

Ini.WriteInteger(Section, 'Width', Form.Width);

Ini.WriteInteger(Section, 'Height', Form.Height);

end;

finally

Ini.Free;

end;

end;

 

procedure tbLoadFormStatus(Form: TForm; const Section: string);

var

Ini: TIniFile;

Maximized: boolean;

begin

Maximized := false; { Evita msg do compilador }

Ini := TIniFile.Create(ChangeFileExt(

ExtractFileName(ParamStr(0)),'.INI'));

try

Maximized := Ini.ReadBool(Section, 'Maximized', Maximized);

Form.Left := Ini.ReadInteger(Section, 'Left', Form.Left);

Form.Top := Ini.ReadInteger(Section, 'Top', Form.Top);

Form.Width := Ini.ReadInteger(Section, 'Width', Form.Width);

Form.Height := Ini.ReadInteger(Section, 'Height', Form.Height);

if Maximized then

Form.Perform(WM_SIZE, SIZE_MAXIMIZED, 0);

{ A propriedade WindowState apresenta Bug.

Por isto usei a mensagem WM_SIZE }

finally

Ini.Free;

end;

end;

 

end.

 

{

Em cada formulário que deseja salvar/restaurar:

- Inclua na seção uses: uFormFunc

- No evento OnShow digite:

tbLoadFormStatus(Self, Self.Name);

- No evento OnClose digite:

tbSaveFormStatus(Self, Self.Name);

}

 

 

Observações

 

O arquivo INI terá o nome do executável e extensão INI e será salvo no diretório do Windows. A palavra Self indica o Form relacionado com a unit em questão. Poderia ser, por exemplo, Form1, Form2, etc. Onde aparece Self.Name poderá ser colocado um nome a sua escolha. Este nome será usado como SectionName no arquivo INI e deve ser idêntico no evento OnShow e OnClose de um mesmo Form, porém para cada Form deverá ser usado um nome diferente.

 

Mostrar um Form de LogOn antes do Form principal

 

{

* Crie um novo Projeto. Este certamente terá o Form1.

* Adicione um novo Form (Form2).

* Coloque no Form2 dois botões TBitBtn.

* Mude a propriedade Kind do BitBtn1 para bkOK.

* Mude a propriedade Kind do BitBtn2 para bkCancel.

* Vá no menu "Project/Options" na aba "Forms" e passe o

Form2 de "Auto-create Forms" para "Available Forms".

* Abra o arquivo Project.dpr (menu Project/View Source).

* Altere o conteúdo deste arquivo conforme abaixo:

}

 

program Project1;

 

uses

Forms, Controls,

Unit1 in 'Unit1.pas' {Form1},

Unit2 in 'Unit2.pas' {Form2};

 

{$R *.RES}

 

var

F: TForm2;

 

begin

F := TForm2.Create(Application);

try

if F.ShowModal = mrOK then begin

Application.Initialize;

Application.CreateForm(TForm1, Form1);

Application.Run;

end;

finally

F.Free;

end;

end.

 

 

Observações

 

O Form2 do exemplo é o Form de LogOn. Este deverá ser preparado para que se possa escolher o usuário, digitar a senha, etc.

 

Fazer a barra de título ficar intermitente (piscante)

 

Inclua na seção uses: Windows

 

{ Coloque um TTimer no Form desejado. Define a propriedade

Interval do Timer para 1000 (1 segundo). Modifique

o evento OnTimer do Timer conforme abaixo: }

 

procedure TForm1.Timer1Timer(Sender: TObject);

begin

FlashWindow(Handle, true);

FlashWindow(Application.Handle, true);

end;

 

Créditos

Surfistinha e Daniel

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

aew surfistinha eu queria um metodo pra nao deixa o usuario nao ficar estendendo a janela do projeto porque o projeto esta centrado numa unica area da form mas quando vc executa ele a janela pode ser extendida eu queria um metodo pra janela ficar num tamanho unico tem como?

Link para o comentário
Compartilhar em outros sites

Este tópico está impedido de receber novos posts.
 Compartilhar

×
×
  • Criar Novo...

Informação Importante

Nós fazemos uso de cookies no seu dispositivo para ajudar a tornar este site melhor. Você pode ajustar suas configurações de cookies , caso contrário, vamos supor que você está bem para continuar.