Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Temas - hosuko

#1
ASM / posición del ratón
8 Julio 2011, 18:46 PM
No he encontrado un tema que lo explique así que hago mi pregunta:

Estoy usando FASM y programando en Windows modo gráfico.

Quiero leer la posición del ratón y comprobar si se encuentra dentro de un area al hacer click. He echo esto:

Definición de las variables
   punto             POINT
   cPosx1            dd ?
   cPosy1            dd ?
   cPosx2            dd ?
   cPosy2            dd ?
   posicionx1        dd ?
   posicionx2        dd ?
   posiciony1        dd ?
   posiciony2        dd ?


Luego mediante el mensaje WM_LBUTTONDOWN hago lo siguiente
  _mouse_click:
   invoke GetCursorPos, punto   ;Comprobamos las coordenadas del cursor
                                              ;y lo guardamos en la estructura punto
   mov    eax, [cPosx1]     ;Punto izquierdo del area
   cmp    [punto.x], eax    ;Compara "X" del cursor con punto izquierdo del area
   jl     _final                    ;si es inferior no sigue.

   mov    eax, [cPosx2]    ;Punto derecho del area
   cmp    [punto.x], eax    ;Compara "X" del cursor con punto derecho del area
   ja     _final                   ;si es superior no sigue.

   mov    eax, [cPosy1]    ;Punto superior del area
   cmp    [punto.y], eax    ;Compara "Y" del cursor con punto superior del area
    jl     _final                   ;si es inferior no sigue.

   mov    eax, [cPosy2]    ;Punto inferior del area
   cmp    [punto.y], eax   ;Compara "Y" del cursor con punto inferior del area
   ja     _final                  ;si es superior no sigue.


En principio la comprobación está bien; sin envargo cuando hago click con el ratón, las coordenadas siempre son inferiores a las del area, aunque haga click dentro del area.

El area está dibujada mediante un procedimiento y por lo tanto lo veo y puedo hacer click dentro del mismo, pero las coordenadas devueltas siempre son inferiores a las del area y no tengo ni idea del motivo.  :-[

Aquí os dejo el código entero excepto donde hay gráficos para que podais copiar-pegar y ejecutarlo si quereis:

format PE GUI
entry comienzo

include 'win32a.inc'

cdxPos          EQU 128
cdyPos          EQU 128
cdxTamano       EQU 800
cdyTamano       EQU 600

cdColFondo      EQU 002h
cdIcono         EQU IDI_APPLICATION
cdCursor        EQU IDC_ARROW
cdTipoBar       EQU 0; WS_EX_CLIENTEDGE :Borde alrededor de la ventana.
cdTipoBoton     EQU WS_VISIBLE + WS_DLGFRAME

id_Muralla_H    EQU 100
id_Muralla_VI   EQU 101
id_Muralla_VD   EQU 102
id_Muralla_EI   EQU 103
id_Muralla_ED   EQU 104

;++++++++++++++++++++++++++++++++++++++++++++++++
;++ Sección de datos                           ++
;++++++++++++++++++++++++++++++++++++++++++++++++
section '.data' data readable writeable
   NombreClase       db 'VentanaSimple', 0
   Titulo            db 'Editor de ciudad v.0.0', 0
   ErrorRegistro     db 'Error al Registrar', 0
   ErrorCrear        db 'Error al Crear', 0
   CommandLine       dd ?

   wc                WNDCLASS 0, WindowProc, 0, 0, 0, 0, 0, cdColFondo, 0, NombreClase
   msg               MSG
   punto             POINT

   ps                PAINTSTRUCT
   rect              RECT

   Posx              dd ?
   Posy              dd ?
   Posy2             dd ?
   Posy3             dd ?
   Posy4             dd ?
   Posy5             dd ?

   hMuralla_H        rd 1
   hMuralla_VI       rd 1
   hMuralla_VD       rd 1
   hMuralla_EI       rd 1
   hMuralla_ED       rd 1
   id_Elegido        rd 1

   hPen              dd ?
   hPenOld           dd ?
   cPosx1            dd ?
   cPosy1            dd ?
   cPosx2            dd ?
   cPosy2            dd ?
   posicionx1        dd ?
   posicionx2        dd ?
   posiciony1        dd ?
   posiciony2        dd ?

   hdc               rd 1
   hMemDC            rd 1

;++++++++++++++++++++++++++++++++++++++++++++++++
;++ Sección ejecutable                         ++
;++++++++++++++++++++++++++++++++++++++++++++++++

section '.text' code readable executable
comienzo:
   invoke GetModuleHandle, 0
   mov    [wc.hInstance], eax
   invoke GetCommandLine
   mov    [CommandLine], eax
   invoke LoadCursor, 0, cdCursor
   mov    [wc.hCursor], eax
   invoke LoadIcon, 0, cdIcono
   mov    [wc.hIcon], eax
   invoke RegisterClass, wc
   test   eax, eax
   jne    _principal
   invoke MessageBox, 0, ErrorRegistro, 0, MB_OK + MB_ICONERROR

  _principal:
   stdcall WinMain, [wc.hInstance], 0, [CommandLine], SW_SHOWNORMAL

   invoke  ExitProcess, 0

;++++++++++++++++++++++++++++++++++++++++++++++++
;++ Procedimiento principal del programa       ++
;++++++++++++++++++++++++++++++++++++++++++++++++

proc WinMain uses ebx esi edi, hInst, hPrevInst, CmdLine, CmdShow
   invoke CreateWindowEx,\
          cdTipoBar,\
          NombreClase,\
          Titulo,\
          cdTipoBoton,\
          cdxPos,\
          cdyPos,\
          cdxTamano,\
          cdyTamano,\
          0,\
          0,\
          [hInst],\
          0
   test   eax, eax
   jne    _msg_loop
   invoke MessageBox, 0, ErrorCrear, 0, MB_OK + MB_ICONERROR

  _msg_loop:
   invoke GetMessage, msg, 0, 0, 0
   cmp    eax, 1
   jb     _end_loop
   jne    _msg_loop
   invoke TranslateMessage, msg
   invoke DispatchMessage, msg
  jmp _msg_loop
  _end_loop:
   ret
endp

;++++++++++++++++++++++++++++++++++++++++++++++++
;++ Procedimiento de los mensajes principal    ++
;++++++++++++++++++++++++++++++++++++++++++++++++
proc WindowProc uses ebx esi edi, hwnd, wmsg, wparam, lparam
   cmp    [wmsg], WM_CREATE
   je     _crear
   cmp    [wmsg], WM_PAINT
   je     _pintar
   cmp    [wmsg], WM_KEYDOWN
   je     _tecla
   cmp    [wmsg], WM_LBUTTONDOWN
   je     _mouse_click
   cmp    [wmsg], WM_DESTROY
   je     _destruye

  _defecto:
   invoke DefWindowProc, [hwnd], [wmsg], [wparam], [lparam]
   jmp    _final
  _crear:
;Aquí vendria la carga de los gráficos

mov    [hMuralla_ED], eax

   mov    [Posx], 750d
   mov    [Posy], 2d
   mov    [Posy2], 45d
   mov    [Posy3], 88d
   mov    [Posy4], 131d
   mov    [Posy5], 174d

   mov    [cPosx1], 749d
   mov    [cPosy1], 1d
   mov    [cPosx2],  790d
   mov    [cPosy2], 43d

   jmp    _final

  _mouse_click:
   invoke GetCursorPos, punto
   mov    eax, [cPosx1]
   cmp    [punto.x], eax
   jl     _final
   mov    eax, [cPosx2]
   cmp    [punto.x], eax
   ja     _final
   mov    eax, [cPosy1]
   cmp    [punto.y], eax
   jl     _final
   mov    eax, [cPosy2]
   cmp    [punto.y], eax
   ja     _final

   invoke InvalidateRect, [hwnd], NULL, TRUE

  jmp _final

  _tecla:
   cmp    [wparam], VK_DOWN
   jne    .otra
   cmp    [cPosy1], 0ADh   ;Mira si es el último recuadro y si lo es no sigue sumando
   je     _final
   add    [cPosy1], 43d
   add    [cPosy2], 43d
   jmp    .pintando
   .otra:
   cmp    [wparam], VK_UP
   jne    _final
   cmp    [cPosy1], 1d
   je     _final
   sub    [cPosy1], 43d
   sub    [cPosy2], 43d

   .pintando:
   invoke InvalidateRect, [hwnd], NULL, TRUE

  jmp _final

  _pintar:

   invoke BeginPaint, [hwnd], ps
          mov    [hdc], eax
          invoke CreateCompatibleDC, [hdc]
          mov    [hMemDC], eax

          invoke GetClientRect, [hwnd], rect
;Aquí vendrían los gráficos

          stdcall Dibuja_Lineas, [cPosx1], [cPosx2], [cPosy1], [cPosy2],0000FF00h

          invoke DeleteDC, [hMemDC]
   invoke EndPaint, [hwnd], ps
   jmp    _final

  _destruye:
   invoke PostQuitMessage, 0
  _final:
   ret
endp

proc Dibuja_Lineas uses ebx esi edi, posicionx1, posicionx2, posiciony1, posiciony2, color
   invoke CreatePen, PS_SOLID, 1, [color]
   mov    [hPen], eax
   invoke SelectObject, [hdc], [hPen]
   mov    [hPenOld], eax
   invoke MoveToEx, [ps.hdc], [posicionx1], [posiciony1], 0
   invoke LineTo, [ps.hdc], [posicionx2], [posiciony1]
   invoke LineTo, [ps.hdc], [posicionx2], [posiciony2]
   invoke LineTo, [ps.hdc], [posicionx1], [posiciony2]
   invoke LineTo, [ps.hdc], [posicionx1], [posiciony1]
   ret
endp

;++++++++++++++++++++++++++++++++++++++++++++++++
;++ Sección de datos importación               ++
;++++++++++++++++++++++++++++++++++++++++++++++++
section '.idata' import data readable
library kernel32, 'kernel32.dll',\
        user32, 'user32.dll',\
        gdi32, 'gdi32.dll'

include 'api\kernel32.inc'
include 'api\user32.inc'
include 'api\gdi32.inc'

;++++++++++++++++++++++++++++++++++++++++++++++++
;++ Sección de recursos                        ++
;++++++++++++++++++++++++++++++++++++++++++++++++

;Aquí vendrían los gráficos



Puedes usar las teclas del cursor ARRIBA y ABAJO, para mover el area. Se que aunque funcionase no haría nada, pero eso es porque al no funcionar no lo he echo  :huh:
#2
ASM / Mov edi, edi
15 Enero 2011, 21:26 PM
Hola que tal?, soy nuevo en esto del ensamblador y al mirar que hacia la libreria user32.dll cuando le llamas a MessageBox usando OllyDbg, me encontré con este código:
.  Mov edi, edi

Cuando lo ejecuto carga los datos que puse en la pila. ¿Acaso mov no se limita a mover los datos de un argumento a otro?.
   Si alguien me pudiera explicar el porqué de esa instrucción y su funcionamiento, gracias.