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
Código:
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
Código:
_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:
Código:
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