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).
Posted on 2005-11-11 20:04:28 by Lenin
I'd say WM_LBUTTONDOWN, SetCapture until WM_LBUTTONUP where ReleaseCapture occurs.
On WM_MOUSEMOVE (If Capture is ON) count the difference
Posted on 2005-11-11 20:56:38 by JimmyClif
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.
Posted on 2005-11-11 21:12:30 by Lenin
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.
Posted on 2005-11-12 05:16:31 by JimmyClif
Pythagora? (x2-x1)^2+(y2-y1)^2=length^2
imagine the line as a diagonal of a rectangle
Posted on 2005-11-12 09:15:14 by drizz
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")	@@:(...)``
Posted on 2005-11-12 14:08:05 by Lenin
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:
``.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.ENDIFmul a * amul b * badd a, bmov c, asqrt(c) ; lenght of line.``
Posted on 2005-11-12 17:09:59 by JimmyClif
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
Posted on 2005-11-12 18:47:37 by ti_mo_n
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:

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

``    .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.
Posted on 2005-11-12 19:59:11 by Lenin
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?
Posted on 2005-11-12 22:39:44 by JimmyClif
When you square any real numbers, they become positive.
Posted on 2005-11-12 23:04:41 by roticv

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	retMouseProc endp``
Posted on 2005-11-13 10:42:23 by Lenin
This appears to give me correct lenghts:

``.data?Startx	dd ?Starty	dd ?Endx	dd ?Endy	dd ?dummy	dd	?Capture	dd	?.codeWndProc proc uses ebx hwnd:DWORD,uMsg:UINT,wParam:WPARAM,lParam:LPARAMLOCAL rect:RECTLOCAL 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    retWndProc endp``
Posted on 2005-11-13 13:14:43 by JimmyClif
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:

``.386.model flat, stdcall  ;32 bit memory modeloption casemap :none  ;case sensitiveinclude windows.incinclude kernel32.incinclude user32.incinclude gdi32.incinclude \masm32\macros\macros.asmincludelib AutoClickDll.libincludelib kernel32.libincludelib user32.libincludelib gdi32.libDlgProc proto :DWORD,:DWORD,:DWORD,:DWORDInstallHook proto :DWORDUninstallHook protoMouseProc 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.codestart:	invoke GetModuleHandle, NULL 	invoke DialogBoxParam, eax, 1, NULL, addr DlgProc, NULL	invoke ExitProcess, 0DlgProc 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	retDlgProc endpend start``

I took away a few features I had implemented to see if they were causing the errors, but they weren't.
Posted on 2005-11-13 20:03:56 by Lenin
Maybe because your forgot the calls to SetCapture & ReleaseCapture. Try that.
Posted on 2005-11-13 20:45:29 by JimmyClif
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
Posted on 2005-11-13 20:58:48 by Lenin
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?
Posted on 2005-11-14 15:39:37 by JimmyClif
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.

``.386.model flat, stdcall  ;32 bit memory modeloption casemap :none  ;case sensitiveinclude windows.incinclude kernel32.incinclude user32.incinclude gdi32.incinclude \masm32\macros\macros.asmincludelib AutoClickDll.libincludelib kernel32.libincludelib user32.libincludelib gdi32.libDlgProc proto :DWORD,:DWORD,:DWORD,:DWORDInstallHook proto :DWORDUninstallHook protoMouseProc 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.codestart:	invoke GetModuleHandle, NULL 	invoke DialogBoxParam, eax, 1, NULL, addr DlgProc, NULL	invoke ExitProcess, 0DlgProc 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, FALSEcomment * ==========================================        .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        .endifcomment * ==========================================    .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	retDlgProc endpend start``
Posted on 2005-11-15 17:28:41 by Lenin