A Aldeia Numaboa ancestral ainda está disponível para visitação. É a versão mais antiga da Aldeia que eu não quis simplesmente descartar depois de mais de 10 milhões de pageviews. Como diz a Sirley, nossa cozinheira e filósofa de plantão: "Misericórdia, ai que dó!"

Se você tiver curiosidade, o endereço é numaboa.net.br.

Leia mais...

Informática Numaboa - Tutoriais e Programação

Menu malandro (masm)

Qui

16

Abr

2009


20:57

(2 votos, média 5.00 de 5) 


Criando a função que desloca a janela

Os itens escolhidos para deslocarem a janela são "Sopa de Piranha" e "Amendoim". Quando o usuário os escolher, a janela deve se deslocar na tela para uma posição diferente. Para tanto, vamos declarar a função "foge". Esta função calcula as novas coordenadas do canto superior esquerdo da janela e fará com que assuma a nova posição.

Declarando a função foge

A primeira providência será declarar o protótipo da função e, logo a seguir, declarar a pópria função. Vamos precisar do manipulador da janela para podermos alterar algumas das suas propriedades e, por isto, o único parâmetro da função será o manipulador:

.386 .model flat,stdcall option casemap:none gerenteJanela proto :DWORD,:DWORD,:DWORD,:DWORD foge proto :DWORD ... .CODE inicio: ... foge proc hWnd:HWND ... foge endp end inicio

Calculando a resolução da tela

Tudo bem. Queremos deslocar nossa janela pela tela, porém ainda não sabemos quantos pixels poderemos deslocá-la no sentido horizontal ou vertical por que desconhecemos quantos pixels estão disponíveis. A função que pode nos fornecer todas as medidas de elementos do sistema, entre elas a resolução de tela, é a GetSystemMetrics:

int GetSystemMetrics( int nIndex // medida do sistema ou configuração desejada );

O parâmetro nIndex, entre outros, pode ser SM_CXSCREEN. Neste caso, o valor de retorno é o número de pixels da horizontal (eixo X). Usando o SM_CYSCREEN obtemos o número de pixels na vertical (eixo Y). Como usaremos as coordenadas do canto superior esquerdo da janela para movimentá-la na tela, os pixels disponíveis na horizontal serão os do eixo X MENOS o número de pixels da largura da janela. Se não descontarmos os pixels da largura da janela corremos o risco de posicioná-la fora da tela (ou mostrá-la apenas parcialmente). Da mesma forma, os pixels disponíveis na vertical serão os do eixo Y MENOS o número de pixels da altura da janela. Os valores assim obtidos serão armazenados nas variáveis locais largMax e altMax.

foge proc hWnd:HWND LOCAL largMax, altMax:DWORD invoke GetSystemMetrics, SM_CXSCREEN sub eax, largJanela mov largMax, eax invoke GetSystemMetrics, SM_CYSCREEN sub eax, altJanela mov altMax, eax ... foge endp end inicio

Determinando a posição atual da janela

A posição atual de uma janela pode ser obtida através da função GetWindowRect. Esta função precisa do manipulador da janela e de uma estrutura RECT, onde serão armazenadas as coordenadas de tela da posição da janela cujo manipulador foi fornecido:

BOOL GetWindowRect( HWND hWnd, // manipulador da janela LPRECT lpRect // endereço da estrutura RECT ); typedef struct _RECT { // rc LONG left; // esquerda LONG top; // superior LONG right; // direita LONG bottom; // inferior } RECT; foge proc hWnd:HWND LOCAL largMax, altMax:DWORD LOCAL retang:RECT invoke GetSystemMetrics, SM_CXSCREEN sub eax, largJanela mov largMax, eax invoke GetSystemMetrics, SM_CYSCREEN sub eax, altJanela mov altMax, eax invoke GetWindowRect, ADDR ... foge endp end inicio

Obtendo a hora do sistema

As posições que a janela deve ocupar são aleatórias e, para calculá-las, usaremos um expediente: a nova posição dependerá dos milésimos de segundo indicados pelo relógio do sistema, pois a possibilidade de repetição deste valor é muito remota. A função GetSystemTime não possui valor de retorno, mas preenche uma estrutura SYSTEMTIME com a hora do sistema:

VOID GetSystemTime( LPSYSTEMTIME lpSystemTime // endereço da estrutura SYSTEMTIME );

A estutura SYSTEMTIME possui os seguintes membros:

typedef struct _SYSTEMTIME { // st WORD wYear; // ano WORD wMonth; // mês WORD wDayOfWeek; // dia da semana WORD wDay; // dia WORD wHour; //hora WORD wMinute; // minutos WORD wSecond; // segundos WORD wMilliseconds; milésimos de segundo } SYSTEMTIME;

Para obter os dados desejados, precisamos declarar uma variável local do tipo SYSTEMTIME e chamar a função GetSystemTime que tenha como parâmetro o endereço da nossa variável:

foge proc hWnd:HWND LOCAL largMax, altMax:DWORD LOCAL retang:RECT LOCAL system_time:SYSTEMTIME invoke GetSystemMetrics, SM_CXSCREEN sub eax, largJanela mov largMax, eax invoke GetSystemMetrics, SM_CYSCREEN sub eax, altJanela mov altMax, eax invoke GetWindowRect, ADDR invoke GetSystemTime, ADDR system_time ... foge endp end inicio

O valor que desejamos será encontrado em system_time.wMilliseconds.

Calculando a nova posição da janela

Teremos que calcular o novo valor de X (posição horizontal na tela) e de Y (posição vertical na tela). A posição atual está no membro da estrutura retang.left e retang.top. Se somarmos o valor de retang.left (posição X atual da janela) aos milésimos de segundo que estão em system_time.wMilliseconds, podem ocorrer duas situações: o novo valor de X ou é maior ou é menor do que a largMax calculada. Caso seja maior, se movermos a janela para este ponto, ela ficará parcialmente visível ou então fora da tela. Faremos uso da sintaxe de alto nível do MASM para criar um loop: se o novo valor de X for maior que largMax, diminuímos este valor de X (novo X - largMax) tantas vezes quantas forem necessárias para que o novo valor de X seja menor que largMax. Assim que o novo valor de X for menor que largMax, saímos do loop e guardamos o valor de X na variável local novoX. O mesmo raciocínio se aplica para o cálculo do novo valor de Y.

foge proc hWnd:HWND LOCAL largMax, altMax:DWORD LOCAL retang:RECT LOCAL system_time:SYSTEMTIME LOCAL novoX, novoY:DWORD invoke GetSystemMetrics, SM_CXSCREEN sub eax, largJanela mov largMax, eax invoke GetSystemMetrics, SM_CYSCREEN sub eax, altJanela mov altMax, eax invoke GetWindowRect, ADDR invoke GetSystemTime, ADDR system_time mov ax, system_time.wMilliseconds add eax, retang.left .WHILE TRUE .BREAK .IF (eax < largMax) sub eax, largMax .ENDW mov novoX, eax mov ax, system_time.wMilliseconds add eax, retang.top .WHILE TRUE .BREAK .IF (eax < altMax) sub eax, altMax .ENDW mov novoY, eax ... foge endp end inicio

Note que transferimos para AX (e não EAX) o valor dos milisegundos. É que a estrutura system_time foi criada a partir do modelo SYSTEMTIME, cujos membros são todos do tipo WORD (16 bits). Caso você tentar transferir para EAX (32 bits) o valor de qualquer membro de system_time (16 bits), o assembler indicará o erro "instruction operands must be the same size", ou seja, os operandos da instrução precisam ser do mesmo tamanho.

Mudando a posição da janela

De posse de todos os parâmetros necessários para mudar a posição da janela, agora podemos chamar a função MoveWindow:

BOOL MoveWindow( HWND hWnd, // manipulador da janela int X, // posição horizontal int Y, // posição vertical int nWidth, // largura int nHeight, // altura BOOL bRepaint // indicador de repintura );

O parâmetro hWnd veio como parâmetro para nossa função "foge". Os parâmetros X e Y são os nossos novoX e novoY. A largura e a altura não serão modificadas, portanto usaremos as variáveis globais largJanela e altJanela. O indicador de repintura será TRUE (verdadeiro) para forçar o sistema a enviar uma mensagem WM_PAINT, devidamente interceptada e onde faremos nossa pintura personalizada. Depois disto, basta um ret para terminarmos a função foge:

foge proc hWnd:HWND LOCAL largMax, altMax:DWORD LOCAL retang:RECT LOCAL system_time:SYSTEMTIME LOCAL novoX, novoY:DWORD invoke GetSystemMetrics, SM_CXSCREEN sub eax, largJanela mov largMax, eax invoke GetSystemMetrics, SM_CYSCREEN sub eax, altJanela mov altMax, eax invoke GetWindowRect, ADDR invoke GetSystemTime, ADDR system_time mov ax, system_time.wMilliseconds add eax, retang.left .WHILE TRUE .BREAK .IF (eax < largMax) sub eax, largMax .ENDW mov novoX, eax mov ax, system_time.wMilliseconds add eax, retang.top .WHILE TRUE .BREAK .IF (eax < altMax) sub eax, altMax .ENDW mov novoY, eax invoke MoveWindow, hWnd, novoX, novoY, largJanela, altJanela, TRUE ret foge endp end inicio

Tutorial para download

Este tutorial, juntamente com o código fonte, imagens e o executável está na seção de Downloads / Tutoriais / Assembly Numaboa, mas você também pode baixá-lo aqui.

Вадим Логофет Sberbankникас адресаооо полигон плюсqlik biпогода в харькове на синоптикадреса никас отзывы класс

Informações adicionais