Título: posición del ratón
Publicado por: hosuko en 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:
Título: Re: posición del ratón
Publicado por: _Enko en 8 Julio 2011, 19:29 pm
la posicion del raton se guarda en el paramentro lParam. X se encuentra en low word de lparam. Y se encuentra en high word de lparam. Lo que tienes que hacer en el evento WM_LBUTTONDOWN es mov eax,[lparam] and eax, 0xFFFF mov [XPos],eax mov eax,[lparam] shr eax,16 mov [YPos],eax
referencia mas detallada en los tutoriales de Iczelion http://win32assembly.online.fr/tut7.html
Título: Re: posición del ratón
Publicado por: hosuko en 8 Julio 2011, 20:13 pm
Me imaginaba esa contestación. Conocía lo del lparam y comprendo el código que has usado; lo miraré a ver si así va mejor.
Use el GetCursorPos por comodidad, pues se supone que te da las coordenadas del cursor de todas formas.
Título: Re: posición del ratón
Publicado por: _Enko en 8 Julio 2011, 20:25 pm
Si el problema no esta allí, hecha un vistazo a ClientToScreen.
http://msdn.microsoft.com/en-us/library/aa931003.aspx
Depura el programa. haz click en la esquina superior izquierda, y la esquina inferior derecha. Compara los valores. Si no son los que deberian, pues algo esta mal en como obtienes las coordendas.
Título: Re: posición del ratón
Publicado por: hosuko en 8 Julio 2011, 20:54 pm
Muchísimas gracias _Enko. No soy capaz de ver el problema pues realmente lo que pasa es que las coordenadas no son las que deberían.
Con el modo "normal", el que has escrito tú, funciona correctamente. Si alguien sabe el motivo, lo que hice mal, agradecería su comentario pues es así como mejor se aprende.
Gracias de nuevo _Enko
Título: Re: posición del ratón
Publicado por: _Enko en 8 Julio 2011, 23:40 pm
GetCursorPos Retrieves the cursor's position, in screen coordinates. Es decir, devuelve las coordenadas del raton en relacion a la Pantalla. Mientas que lparam en el evento del click, tiene las coordenadas en relacion a la ventana.
Título: Re: posición del ratón
Publicado por: hosuko en 9 Julio 2011, 13:11 pm
Ya sabia yo que tenía que ser un error de comprensión. No me di cuenta de lo de las coordenadas de pantalla / ventana. La próxima vez estaré má atento.
Gracias de nuevo ;-)
|