I'm coding a smal utility that is intended to get the number of pixels of the selected area... For that I wanted something like this: You click your mouse button at a certain point, then a line is created at that point, as you drag your mouse the line goes following your cursor, once you release your mouse button the line size is calculated and showed to the user. I didn't manage to find any similar code on google... Drawing a static line isn't a problem, nor is geting the click and realease, I just can't figure how I would do this "dinamicaly".
By the way I'm using hooks to get the mouse input: mouse click, mouse release and mouse move, all of them has it's unique message (WM_MCLICK, WM_MUP, WM_MMOVE).
By the way I'm using hooks to get the mouse input: mouse click, mouse release and mouse move, all of them has it's unique message (WM_MCLICK, WM_MUP, WM_MMOVE).
I'd say WM_LBUTTONDOWN, SetCapture until WM_LBUTTONUP where ReleaseCapture occurs.
On WM_MOUSEMOVE (If Capture is ON) count the difference
On WM_MOUSEMOVE (If Capture is ON) count the difference
I had already thought of that method, but I don't see how it would work if the distance to be measured wan't horizontal or vertical. I wanted to use gdi because it would let user see the distance and I beleive that there might some way to get it's size. I really don't know if there's a formula I could use or something like that.
With GDI it will be the same thing - except you will be drawing a line starting from the point when WM_LBUTTONDOWN occured until the current position in WM_MOUSEMOVE.
Pythagora? (x2-x1)^2+(y2-y1)^2=length^2
imagine the line as a diagonal of a rectangle
imagine the line as a diagonal of a rectangle
Seems to be a nice idea... But I don't know how to implement that... My code so far:
pStart POINT <?>
MCdown dd 0
MCup dd 0
(...)
.elseif uMsg==WM_MCDOWN
cmp MCdown, 0
jz @F
mov MCdown, FALSE
mov MCup, TRUE
push wParam
pop pStart.x
push lParam
pop pStart.y
@@:
.elseif uMsg==WM_MCUP
cmp MCup, 0
jz @F
mov MCup, FALSE
; So now I would use that formula here, but how? I have the WM_MCDOWN cordinates (pStart.x, pStart.y)
; And the MC_UP ones (wParam, lParam)...
invoke SetDlgItemText, hWnd, IDC_GETSIZE, CTXT("Get size")
@@:
.elseif uMsg==WM_COMMAND
mov eax, wParam
cmp ax, IDC_GETSIZE
jnz @F
mov MCdown, TRUE
invoke SetDlgItemText, hWnd, IDC_GETSIZE, CTXT("Click and drag your mouse")
@@:
(...)
Holy crap - You're right. Sorry... took me to this moment to realize for good why you mentionned horizontal & vertical.
Drizz, I'm off probably by far... (and out of school for a damn long time) but shouldn't it be a triangle and a^2+b^2=c^2 ?
If you know the starting position (x1,x2), and the ending position (x3,x4) - oh I see.... (grin)
Pseudo-Code:
Drizz, I'm off probably by far... (and out of school for a damn long time) but shouldn't it be a triangle and a^2+b^2=c^2 ?
If you know the starting position (x1,x2), and the ending position (x3,x4) - oh I see.... (grin)
Pseudo-Code:
.IF x1 > x2
sub x1, x2
mov a, x1
.ELSE
sub x2,x1
mov a, x2
.ENDIF
.IF x3 > x4
sub x3, x4
mov b, x3
.ELSE
sub x4,x3
mov b, x4
.ENDIF
mul a * a
mul b * b
add a, b
mov c, a
sqrt(c) ; lenght of line.
there's no need to find out which one is bigger (or maybe my brain is sleeping).
mov eax, x2
sub eax, x1
mul eax ; a^2
mov ecx, eax
mov eax, y2
sub eax, y1
mul eax ; b^2
add eax, ecx ; a^2 + b^2 ( c^2 )
sqrt(eax) :P
mov eax, x2
sub eax, x1
mul eax ; a^2
mov ecx, eax
mov eax, y2
sub eax, y1
mul eax ; b^2
add eax, ecx ; a^2 + b^2 ( c^2 )
sqrt(eax) :P
My code is yelding pretty weird results... The weirdest thing is that there's no relation between the real number of pixels and the outputed one like:
Of course that it could be a problem with my method to catch the cordinates, if needed I'll post the whole code.
real: 28px, outputed: 626px, direction: horizontal
real: 50px, outputed:500px, direction: horizontal
real: 45px, outputed:581px, direction: vertical
real: 74px, outputed:308px, direction: vertical
real: 29px, outputed:250px, direction: diagonal
real: 50px, outputed:500px, direction: horizontal
real: 45px, outputed:581px, direction: vertical
real: 74px, outputed:308px, direction: vertical
real: 29px, outputed:250px, direction: diagonal
.elseif uMsg==WM_MCUP
cmp MCup, 0
jz @F
mov MCup, FALSE
invoke SetDlgItemText, hWnd, IDC_GETSIZE, CTXT("Get size")
mov ecx, pStart.x
.if ecx > pStart.y
mov eax, pStart.x
sub eax, pStart.y
.else
mov eax, pStart.y
sub eax, pStart.x
.endif
mul eax ; a^2
mov result, eax
mov ecx, wParam
.if ecx > lParam
mov eax, wParam
sub eax, lParam
.else
mov eax, lParam
sub eax, wParam
.endif
mul eax ; b^2
add result, eax ; c^2
fild result
fsqrt
fist result
fwait
invoke wsprintf, addr buffer, addr template, result
invoke MessageBox, hWnd, addr buffer, 0, MB_OK
@@:
Of course that it could be a problem with my method to catch the cordinates, if needed I'll post the whole code.
Well, I don't know your code but regarding the lParam & the wParam's: Under WM_MOUSEMOVE & LBUTTONDOWN/UP the coordinates for x/y are located in lParamHi & lParamLo respectively. Maybe that's your error.
ti_mo_n: You're probably right - but shouldn't we use the abs(x) for each of the substractions to prevent negative numbers?
ti_mo_n: You're probably right - but shouldn't we use the abs(x) for each of the substractions to prevent negative numbers?
When you square any real numbers, they become positive.
Well, I don't know your code but regarding the lParam & the wParam's: Under WM_MOUSEMOVE & LBUTTONDOWN/UP the coordinates for x/y are located in lParamHi & lParamLo respectively. Maybe that's your error.
I coded my DLL to pass me the x and y cordinates in wParam and lParam:
MouseProc proc nCode:DWORD,wParam:DWORD,lParam:DWORD
invoke CallNextHookEx,hHook,nCode,wParam,lParam
mov edx,lParam
assume edx:PTR MOUSEHOOKSTRUCT
.if wParam == WM_LBUTTONDOWN
invoke PostMessage,hWnd,WM_MCDOWN,.pt.x,.pt.y
.elseif wParam == WM_LBUTTONUP
invoke PostMessage,hWnd,WM_MCUP,.pt.x,.pt.y
.else
invoke PostMessage,hWnd,WM_MOUSEMV,.pt.x,.pt.y
.endif
assume edx:nothing
xor eax,eax
ret
MouseProc endp
This appears to give me correct lenghts:
.data?
Startx dd ?
Starty dd ?
Endx dd ?
Endy dd ?
dummy dd ?
Capture dd ?
.code
WndProc proc uses ebx hwnd:DWORD,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
LOCAL rect:RECT
LOCAL ps:PAINTSTRUCT
.IF uMsg==WM_CREATE
m2m hWnd, hwnd
;invoke OnCreate
.ELSEIF uMsg==WM_LBUTTONDOWN
invoke SetCapture,hWnd
mov Capture, TRUE
movzx eax, lParamL ; lParamL == WORD PTR
mov Startx, eax ; lParamH == WORD PTR
movzx eax, lParamH
mov Starty, eax
.ELSEIF uMsg==WM_LBUTTONUP
invoke ReleaseCapture
mov Capture, FALSE
;Get line lenght
mov eax, Startx
mov edx, Endx
sub eax, edx
imul eax, eax
push eax
mov eax, Starty
mov edx, Endy
sub eax, edx
imul eax, eax
pop edx
add eax, edx
mov dummy, eax
finit
fild dummy
fsqrt
fistp dummy
PrintDec dummy
.ELSEIF uMsg==WM_MOUSEMOVE
.IF Capture == TRUE
movzx eax, lParamL
mov Endx, eax
movzx eax, lParamH
mov Endy, eax
invoke InvalidateRect,hWnd,0,TRUE
.ENDIF
.ELSEIF uMsg==WM_PAINT
.IF Capture == TRUE
invoke BeginPaint,hWnd,a$ ps
invoke GetStockObject,BLACK_PEN
push eax
invoke SelectObject,ps.hdc,eax
invoke MoveToEx,ps.hdc,Startx,Starty,NULL
invoke LineTo,ps.hdc,Endx,Endy
invoke EndPaint,hWnd,a$ ps
call DeleteObject
.ENDIF
.ELSEIF uMsg==WM_DESTROY
invoke PostQuitMessage,0
.ELSE
invoke DefWindowProc,hwnd,uMsg,wParam,lParam
ret
.ENDIF
xor eax,eax
ret
WndProc endp
Thanks a lot :) For some weird reason after adapting my code (copy and pasting yours) my window became unresponsible... I'm pretty sure that it's because I'm handling WM_PAINT but I don't know how to fix it... Here's the code:
I took away a few features I had implemented to see if they were causing the errors, but they weren't.
.386
.model flat, stdcall ;32 bit memory model
option casemap :none ;case sensitive
include windows.inc
include kernel32.inc
include user32.inc
include gdi32.inc
include \masm32\macros\macros.asm
includelib AutoClickDll.lib
includelib kernel32.lib
includelib user32.lib
includelib gdi32.lib
DlgProc proto :DWORD,:DWORD,:DWORD,:DWORD
InstallHook proto :DWORD
UninstallHook proto
MouseProc proto :DWORD,:DWORD,:DWORD
.const
IDC_HOOK equ 12
IDC_XPOINT equ 10
IDC_YPOINT equ 11
IDC_COLORBOX equ 12
IDC_GETSIZE equ 13
WM_MOUSEMV equ WM_USER+6
WM_MCUP equ WM_USER+7
WM_MCDOWN equ WM_USER+8
.data?
rect RECT <?>
ps PAINTSTRUCT <?>
pStart POINT <?>
pEnd POINT <?>
result dd ?
buffer db 50 dup(?)
.data
template db "There are %lu pixels",0
MCdown dd 0
Capture dd 0
.code
start:
invoke GetModuleHandle, NULL
invoke DialogBoxParam, eax, 1, NULL, addr DlgProc, NULL
invoke ExitProcess, 0
DlgProc proc hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
.if uMsg==WM_PAINT
.if Capture
invoke BeginPaint,hWnd,addr ps
invoke GetStockObject, BLACK_PEN
push eax
invoke SelectObject,ps.hdc,eax
invoke MoveToEx,ps.hdc,pStart.x,pStart.y,NULL
invoke LineTo,ps.hdc,pEnd.x,pEnd.y
invoke EndPaint,hWnd,addr ps
call DeleteObject
.endif
.elseif uMsg==WM_MOUSEMV
invoke SetDlgItemInt, hWnd, IDC_XPOINT, wParam, FALSE
invoke SetDlgItemInt, hWnd, IDC_YPOINT, lParam, FALSE
.if Capture
m2m pEnd.x, wParam
m2m pEnd.y, lParam
invoke InvalidateRect,hWnd,0,TRUE
.endif
.elseif uMsg==WM_MCUP
mov Capture, FALSE
mov eax, pStart.x
mov edx, pEnd.x
sub eax, edx
imul eax, eax
push eax
mov eax, pStart.y
mov edx, pEnd.y
sub eax, edx
imul eax, eax
pop edx
add eax, edx
mov result, eax
finit
fild result
fsqrt
fistp result
invoke wsprintf, addr buffer, addr template, result
invoke MessageBox, hWnd, addr buffer, 0, MB_OK
.elseif uMsg==WM_MCDOWN
.if MCdown
mov MCdown, FALSE
mov Capture, TRUE
m2m pStart.x, wParam
m2m pStart.y, lParam
.endif
.elseif uMsg==WM_COMMAND
mov eax, wParam
.if ax==IDC_GETSIZE
mov MCdown, TRUE
invoke SetDlgItemText, hWnd, IDC_GETSIZE, CTXT("Click and drag your mouse")
.endif
.elseif uMsg==WM_INITDIALOG
invoke GetWindowRect,hWnd,addr rect
invoke SetWindowPos,hWnd,HWND_TOPMOST,rect.left,rect.top,rect.right,rect.bottom,SWP_SHOWWINDOW
invoke InstallHook, hWnd
.elseif uMsg==WM_CLOSE
invoke UninstallHook
invoke EndDialog,hWnd,0
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
DlgProc endp
end start
I took away a few features I had implemented to see if they were causing the errors, but they weren't.
Maybe because your forgot the calls to SetCapture & ReleaseCapture. Try that.
Oh I'm using hooks... I tested using SetCapture but it only aplies to my window... Like I can't detect the mouse events when it's out of my window.
The main purpose of this project is help me to build resource files, so I can open a program , get it's sizes, controls' sizes etc... I'm also getting it's colors, just removed that of the code posted here. If I can't catch mouse events from others windows then my project is just a big waste of my time :P
The main purpose of this project is help me to build resource files, so I can open a program , get it's sizes, controls' sizes etc... I'm also getting it's colors, just removed that of the code posted here. If I can't catch mouse events from others windows then my project is just a big waste of my time :P
How you're coming along there? All good? If you need to get rid of the WM_PAINT part just kick out the whole WM_PAINT handler and the call to InvalidateRect.
On another note, If you do what I think you're doing... Why not doing an enumeration of the selected window and list all the controls along with their sizes and colors?
On another note, If you do what I think you're doing... Why not doing an enumeration of the selected window and list all the controls along with their sizes and colors?
I don't know exactly what you think I'm doing :P
I took away the line part as you said and now it's working, not that precise, but it's working. Still I will leave the code here hoping that some kind soul might make the line work :)
Thanks a lot Jimmy, I didn't expect some to build the whole code for me.
I took away the line part as you said and now it's working, not that precise, but it's working. Still I will leave the code here hoping that some kind soul might make the line work :)
Thanks a lot Jimmy, I didn't expect some to build the whole code for me.
.386
.model flat, stdcall ;32 bit memory model
option casemap :none ;case sensitive
include windows.inc
include kernel32.inc
include user32.inc
include gdi32.inc
include \masm32\macros\macros.asm
includelib AutoClickDll.lib
includelib kernel32.lib
includelib user32.lib
includelib gdi32.lib
DlgProc proto :DWORD,:DWORD,:DWORD,:DWORD
InstallHook proto :DWORD
UninstallHook proto
MouseProc proto :DWORD,:DWORD,:DWORD
.const
IDC_HOOK equ 12
IDC_XPOINT equ 10
IDC_YPOINT equ 11
IDC_COLORBOX equ 12
IDC_GETSIZE equ 13
WM_MOUSEMV equ WM_USER+6
WM_MCUP equ WM_USER+7
WM_MCDOWN equ WM_USER+8
.data?
BoxColor dd ?
ColorBoxHwnd dd ?
rect RECT <?>
ps PAINTSTRUCT <?>
pStart POINT <?>
pEnd POINT <?>
result dd ?
buffer db 50 dup(?)
.data
template db "There are %lu pixels",0
MCdown dd 0
Capture dd 0
.code
start:
invoke GetModuleHandle, NULL
invoke DialogBoxParam, eax, 1, NULL, addr DlgProc, NULL
invoke ExitProcess, 0
DlgProc proc hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
.if uMsg==WM_MOUSEMV
invoke SetDlgItemInt, hWnd, IDC_XPOINT, wParam, FALSE
invoke SetDlgItemInt, hWnd, IDC_YPOINT, lParam, FALSE
comment * ==========================================
.if Capture
m2m pEnd.x, wParam
m2m pEnd.y, lParam
invoke InvalidateRect,hWnd,0,TRUE
.endif
.elseif uMsg==WM_PAINT
.if Capture
invoke BeginPaint,hWnd,addr ps
invoke GetStockObject, BLACK_PEN
push eax
invoke SelectObject,ps.hdc,eax
invoke MoveToEx,ps.hdc,pStart.x,pStart.y,NULL
invoke LineTo,ps.hdc,pEnd.x,pEnd.y
invoke EndPaint,hWnd,addr ps
call DeleteObject
.endif
comment * ==========================================
.elseif uMsg==WM_MCUP
.if Capture
mov Capture, FALSE
m2m pEnd.x, wParam
m2m pEnd.y, lParam
mov eax, pStart.x
mov edx, pEnd.x
sub eax, edx
imul eax, eax
push eax
mov eax, pStart.y
mov edx, pEnd.y
sub eax, edx
imul eax, eax
pop edx
add eax, edx
mov result, eax
finit
fild result
fsqrt
fistp result
invoke wsprintf, addr buffer, addr template, result
invoke MessageBox, hWnd, addr buffer, 0, MB_OK
invoke SetDlgItemText, hWnd, IDC_GETSIZE, CTXT("Get Size")
.endif
.elseif uMsg==WM_MCDOWN
.if MCdown
mov MCdown, FALSE
mov Capture, TRUE
m2m pStart.x, wParam
m2m pStart.y, lParam
.endif
.elseif uMsg==WM_COMMAND
mov eax, wParam
.if ax==IDC_GETSIZE
mov MCdown, TRUE
invoke SetDlgItemText, hWnd, IDC_GETSIZE, CTXT("Click and drag your mouse")
.endif
.elseif uMsg==WM_INITDIALOG
invoke GetWindowRect,hWnd,addr rect
invoke SetWindowPos,hWnd,HWND_TOPMOST,rect.left,rect.top,rect.right,rect.bottom,SWP_SHOWWINDOW
invoke InstallHook, hWnd
.elseif uMsg==WM_CLOSE
invoke UninstallHook
invoke EndDialog,hWnd,0
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
DlgProc endp
end start