Iniciar sessão com a Microsoft
Iniciar sessão ou criar uma conta.
Olá,
Selecione uma conta diferente.
Tem várias contas
Selecione a conta com a qual pretende iniciar sessão.

Sintomas

A barra de deslocação desloca-se continuamente mesmo depois de soltar o botão do rato esquerdo. O tipo de barra de deslocação é irrelevante para este problema, ou seja, o mesmo problema ocorre independentemente de a barra de deslocação ser parte da janela ou é um controlo de barra de deslocação.

Causa

Este problema ocorre geralmente quando um ciclo de recuperação de mensagens é executado como resultado de ações tomadas para rolar ao receber uma das mensagens de notificação da barra de deslocamento. Ao deslocar-se, inicia-se um ciclo interno de recuperação de mensagens no Windows. A tarefa deste ciclo de mensagens é acompanhar o scrolling e enviar as mensagens de notificação de barra de deslocamento, WM_HSCROLL e WM_VSCROLL apropriados. O deslocamento é terminado uma vez WM_LBUTTONUP é recebido. Se for iniciado um outro ciclo de mensagens durante o scrolling, o WM_LBUTTONUP é recuperado por esse ciclo de mensagem, e porque uma aplicação não tem acesso ao ciclo interno de recuperação de mensagens da barra de deslocamento, WM_LBUTTONUP não pode ser despachado corretamente. Portanto, o WM_LBUTTONUP nunca é recebido pelo recuperador de mensagens internas, e o scrolling nunca termina. A aplicação que está a ser deslocal não tem de recuperar mensagens explicitamente para causar este problema. Ligar para qualquer uma das seguintes funções ou processar qualquer mensagem que tenha um ciclo de recuperação de mensagens, enquanto desloca, pode fazer com que o WM_LBUTTONUP se perca. As funções abaixo enumeradas enquadram-se nesta categoria:

DialogBox() DialogBoxIndirect() DialogBoxIndirectParam() DialogBoxParam() GetMessage() MessageBox() PeekMessage()

Resolução

Enquanto o Scrolling, a mensagem WM_LBUTTONUP não deve ser recuperada da fila por qualquer laço de recuperação de mensagens que não seja o da barra de deslocamento interna. Uma aplicação pode encontrar este problema da seguinte forma:

  • Uma aplicação implementa um ciclo de recuperação de mensagens para implementar o processamento de fundo, por exemplo, o processamento de fundo enquanto executa uma pintura demorada.

  • Uma aplicação implementa um ciclo de recuperação de mensagens para implementar a comunicação com outra aplicação ou DLL. Por exemplo, para deslocar, a aplicação precisa de receber dados de outros países.

Possíveis soluções alternativas

Duas possíveis soluções alternativas estão listadas abaixo. A primeira solução é utilizada por muitas aplicações de saída e pelo Windows; no entanto, em circunstâncias raras, a primeira solução pode não ser viável. Neste caso, pode ser utilizada a segunda solução. No entanto, se possível, tente evitar a recuperação de mensagens completamente durante o deslocamento.

  • Utilize o processamento baseado em mensagens tempor e temporizador. Decompor o processamento complicado em tarefas menores e mantenha-se atento ao local onde cada tarefa começa e termina e, em seguida, execute cada tarefa com base numa mensagem de temporizador. Quando todos os componentes do processamento estiverem completos, desligue o temporizador. Veja abaixo um exemplo desta solução alternativa.

  • Implemente um ciclo de recuperação de mensagens, mas certifique-se de WM_LBUTTONUP não seja recuperado por ele. Isto pode ser conseguido utilizando filtros. Veja abaixo alguns exemplos desta solução.

Exemplo demonstrando a Solução-de-obra em torno de 1

Uma aplicação tem um procedimento complexo de pintura. Chamar o ScrollWindow para deslocar, gera mensagens de tinta. O processamento de fundo ocorre durante a pintura.

  1. Quando receber a mensagem WM_PAINT faça o seguinte:

    1. Ligue para o BeginPaint().

    2. Copie a rect invalidada para uma variável de rect global (por exemplo, grcPaint) a ser usada no passo 2. O rect grcPaint global seria uma união do rect previamente obtido (grcPaint) e do novo rect invalidado (ps.rcPaint). O código para tal assemelhar-se-á ao seguinte:

               RECT grcPaint;    // Should be initialized before getting the                           // first paint message.            :            :         UnionRect(&grcPaint, &ps.rcPaint,&grcPaint);
    3. Chamada ValidateRect() com ps.rcPaint.

    4. Ligue para endPaint().

    5. Desema esta hora.

    Desta forma, não são geradas mais WM_PAINT mensagens, porque não existem regiões inválidas, e é criado um temporizador, que gerará mensagens WM_TIMER.

  2. Ao receber uma mensagem WM_TIMER, verifique a variável global rect; se não estiver vazio, pegue uma secção e pinte-a. Em seguida, ajuste a variável de rect global para que não inclua mais a região pintada.

  3. Uma vez que a variável rect global está vazia, então mate o temporizador.

Exemplo demonstrando a Solução 2

Uma aplicação precisa de obter alguns dados através do DDE ou de algum outro mecanismo a partir de outra aplicação, que é depois exibida na janela. Para deslocar, a aplicação precisa de solicitar e, em seguida, obter os dados a partir de uma aplicação de servidor. Existem três filtros diferentes que podem ser usados para configurar um PeekMessage e obter a informação. Os filtros podem ser configurados utilizando os parâmetros uFilterFirst e uFilterLast do PeekMessage(). O uFilterFirst especifica a mensagem do punho no intervalo a ser verificada e o uFilterLast especifica a última mensagem no intervalo a ser verificada.

  1. Verifique e recupere apenas as mensagens relacionadas para obter os dados necessários.

  2. Verifique se WM_LBUTTONUP sem a retirar, forme a fila; se estiver na fila, quebre. Caso contrário, recupere e despacha todas as mensagens.

  3. Recupere todas as mensagens com menos de WM_LBUTTONUP e superiores a WM_LBUTTONUP, mas não recupere WM_LBUTTONUP.

Mais Informações

Passos para reproduzir o problema

Segue-se a sequência de eventos que levaram à perda da mensagem WM_LBUTTONUP:

  1. Clique na barra de deslocação utilizando o rato.

  2. O passo 1 gera uma mensagem WM_NCLBUTTONDOWN.

  3. O passo 2 provoca o início de um ciclo de mensagens internas do Windows. Este ciclo de mensagens procura mensagens relacionadas com barras de pergaminho. O objetivo deste ciclo de mensagens é gerar mensagens WM_HSCROLL ou WM_VSCROLL apropriadas. O ciclo de mensagem e o deslocamento terminam assim que WM_LBUTTONUP é recebido.

  4. Ao receber a WM_HSCROLL ou WM_VSCROLL mensagem, a aplicação entra diretamente num ciclo de recuperação de mensagens ou chama funções que resultam na recuperação de mensagens.

  5. WM_LBUTTONUP é removido da fila pelo ciclo de mensagem mencionado no passo 4. WM_LBUTTONUP é então despachado.

  6. Como resultado do passo 5 WM_LBUTTONUP mensagem é enviada para outro lugar e o ciclo de recuperação de mensagens internas, mencionado no passo 3 nunca a recebe. O loop de mensagem no passo 3 está à procura da WM_LBUTTONUP para parar de rolar. Como não é recebida, a barra de pergaminho continua a rolar.

Precisa de mais ajuda?

Quer mais opções?

Explore os benefícios da subscrição, navegue em cursos de formação, saiba como proteger o seu dispositivo e muito mais.

As comunidades ajudam-no a colocar e a responder perguntas, a dar feedback e a ouvir especialistas com conhecimentos abrangentes.

Estas informações foram úteis?

Quão satisfeito está com a qualidade do idioma?
O que afetou a sua experiência?
Ao selecionar submeter, o seu feedback será utilizado para melhorar os produtos e serviços da Microsoft. O seu administrador de TI poderá recolher estes dados. Declaração de Privacidade.

Obrigado pelo seu feedback!

×