Ir para conteúdo
Fórum Script Brasil
  • 0

Hdc


Thales Pontes Martins

Pergunta

Coloquem no evento OnPaint do form o seguinte ->

procedure TForm1.FormPaint(Sender: TObject);
begin
  Caption:=IntToStr(Canvas.Handle);
end;

Verão que o Handle do canvas muda a cada repintagem. Arrastem o form para fora do limite da tela e devagar traga de volta e o handle vai ficar mudando.

Então minha pergunta é: É necessário pegar um DC e liberá-lo a cada vez que eu vou pintar alguma coisa no form? Não posso pegar um DC e usá-lo até o término do programa?

Desculpem estar perguntando isso por aqui mas não conseguí achar a resposta na documentação do Delphi e não sei que palavras usar para achar isso numa busca no Google.

Valeu.

Link para o comentário
Compartilhar em outros sites

14 respostass a esta questão

Posts Recomendados

  • 0
Então minha pergunta é: É necessário pegar um DC e liberá-lo a cada vez que eu vou pintar alguma coisa no form? Não posso pegar um DC e usá-lo até o término do programa?
Acho que sim porque GetDC aloca um HDC e deve manter o Rect da janela sob seu controle e para isso aloca recursos e é por isso que tem que ser dado ReleaseDC.

Link para o comentário
Compartilhar em outros sites

  • 0

Ainda não entendí porque eu não posso chamar um DC no início do programa, usar ele até o final e depois chamar ReleaseDC.

Veja que curioso que aconteceu-> Seu eu pego um DC e dou um FilRect com ele no form todo beleza, ele pinta o form todo, mas quando eu arrasto ou dimensiono o form (Supostamente deveria pegar outro DC mas não pego) ele pinta o form todo certinho menos os botões. Porque isso acontece?

Link para o comentário
Compartilhar em outros sites

  • 0
Ainda não entendí porque eu não posso chamar um DC no início do programa, usar ele até o final e depois chamar ReleaseDC.
O que eu disse foi o oposto. o Sim foi para sua última pergunta.
Veja que curioso que aconteceu-> Seu eu pego um DC e dou um FilRect com ele no form todo beleza, ele pinta o form todo, mas quando eu arrasto ou dimensiono o form (Supostamente deveria pegar outro DC mas não pego) ele pinta o form todo certinho menos os botões. Porque isso acontece?

Botões ? que botões ? Esse FillRect é em toda área client do Form ?
Link para o comentário
Compartilhar em outros sites

  • 0

O que eu disse foi o oposto. o Sim foi para sua última pergunta.
Então porque o TForm faz daquele jeito, pegando um DC a cada Paint?
Botões ? que botões ? Esse FillRect é em toda área client do Form ?
Eu fiz assim ->
var 
  dc : HDC;
  r : TRect;
  cn : TCanvas;
begin
  DC:=GetWindowDC(handle);

  r.left:=0;
  r.top:=0;
  r.right:=width;
  r.bottom:=height;

  cn:=TCanvas.create;
  cn.Handle:=DC;

  cn.FillRect(r); // o form tem 3 botões e ele pinta por cima de todos, fica tudo preto.
  
  //Aqui eu movimento o form ou redimensiono, saindo com ele todo pra fora da tela pra que repinte
  cn.FillRect(r); // Aqui é pintado todo o form menos os botões, a area dos botões não é preenchida.
end;

Isso aí eu botei uma parte no OnClick de cada botão, um pra pegar DC, um pra FillRect e um pra releaseDC.

Link para o comentário
Compartilhar em outros sites

  • 0

Perdão, é que eu apaguei o código que eu escreví no Delphi, eu usei o GetWindowDC mesmo. E aconteceu isto, quando não se move a janela ele pinta por cima de tudo, mas se mecher e não pegar outroDC ele não pinta por cima dos botões.

Link para o comentário
Compartilhar em outros sites

  • 0
Beleza, mas porque então o TForm pega um a cada Paint se pode fazer assim, não ficaria mais lento?
Bom, aí teria que ver nas classes do Delphi como ele faz; eu realmente não sei.

Mas se você utiliza GetDC com o Handle do Form, porque não utilizar o próprio Form.Canvas.Handle ? Não funcionaria ? Daí você não se preocupa em alocar e desalocar.

Link para o comentário
Compartilhar em outros sites

  • 0
Mas se você utiliza GetDC com o Handle do Form, porque não utilizar o próprio Form.Canvas.Handle ? Não funcionaria ? Daí você não se preocupa em alocar e desalocar.
Pois é, mas o handle do canvas do form só pega área cliente eu eu quero a janela toda.
Link para o comentário
Compartilhar em outros sites

  • 0

Bom, eu queria que alguém me dissesse como é que o Windows espera que os programas façam, ou seja, ele foi programado para se pegar um DC a cada Paint ou pegar um e usar o programa inteiro.

Link para o comentário
Compartilhar em outros sites

  • 0
Então minha pergunta é: É necessário pegar um DC e liberá-lo a cada vez que eu vou pintar alguma coisa no form? Não posso pegar um DC e usá-lo até o término do programa?
Sempre entendi que a resposta para esta pergunta é NÃO.

Com toda a comodidade das janelas encapsuladas em objetos, poucas pessoas passaram pela experiência de ter que escrever todo o procedimento de janela. Naquela oportunidade sempre ficou claro que ao processar a mensagem WM_PAINT, um handler para o DC deve ser alocado no início (BeginPaint) de seu processamento e liberado após seu término (EndPaint). É uma questão de não alocar recursos do sistemas, os quais são limitados. (Because only a limited number of common device contexts exist, an application should release them after it has finished drawing. - msdn)

Leve em consideração que cada botão, cada label, cada elemento em uma janela (form) é uma outra janela. Já imaginou quantos DC's estariam alocados integralmente se fossem mantido do início ao fim da aplicação ao invés de serem alocados apenas quando necessário?

O que eu disse foi o oposto. o Sim foi para sua última pergunta.
Então porque o TForm faz daquele jeito, pegando um DC a cada Paint?
Botões ? que botões ? Esse FillRect é em toda área client do Form ?
Eu fiz assim ->
var 
  dc : HDC;
  r : TRect;
  cn : TCanvas;
begin
  DC:=GetWindowDC(handle);

  r.left:=0;
  r.top:=0;
  r.right:=width;
  r.bottom:=height;

  cn:=TCanvas.create;
  cn.Handle:=DC;

  cn.FillRect(r); // o form tem 3 botões e ele pinta por cima de todos, fica tudo preto.
  //Aqui eu movimento o form ou redimensiono, saindo com ele todo pra fora da tela pra que repinte
  cn.FillRect(r); // Aqui é pintado todo o form menos os botões, a area dos botões não é preenchida.
end;

Isso aí eu botei uma parte no OnClick de cada botão, um pra pegar DC, um pra FillRect e um pra releaseDC.

Observe que preferencialmente o desenho na janela deve ocorrer processando a mensagem WM_PAINT. Mesmo assim, sempre que chamar GetWindowDC ou GetDC, após a "pintura" deve ser chamado ReleaseDC. (After painting is complete, the ReleaseDC function must be called to release the device context. Not releasing the window device context has serious effects on painting requested by applications. - msdn)

Mas se você utiliza GetDC com o Handle do Form, porque não utilizar o próprio Form.Canvas.Handle ? Não funcionaria ? Daí você não se preocupa em alocar e desalocar.
Pois é, mas o handle do canvas do form só pega área cliente eu eu quero a janela toda.

Não seria o caso de criar uma janela sem título? Subscreva CreateParams para este fim.

Bom, eu queria que alguém me dissesse como é que o Windows espera que os programas façam, ou seja, ele foi programado para se pegar um DC a cada Paint ou pegar um e usar o programa inteiro.

Acho que o primeiro comentário responde a isto.

[]s

Link para o comentário
Compartilhar em outros sites

  • 0
Não seria o caso de criar uma janela sem título? Subscreva CreateParams para este fim.
Mas eu quero o título na minha janela, homem.

Bom com esse seu post essa dúvida já está resolvida. Valeu.

Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,3k
    • Posts
      652,3k
×
×
  • Criar Novo...