Xочу перетаскивать окно за любую точку, для этого: Код (Text): case WM_NCHITTEST: return HTCAPTION; break; но перестает работать PtInRegion() Код (Text): case WM_NCLBUTTONUP: // or WM_NCRBUTTONUP xPos = GET_X_LPARAM(lParam); yPos = GET_Y_LPARAM(lParam); for (int i=0; i<iRegionsCount; i++) { if (PtInRegion(hRgns[i],xPos,yPos)) { iActiveRgn = i; continue; } } break; Как поправить?
; Двигать форму мышью за любую точку .if uMsg == WM_MOUSEMOVE mov eax,[wParam] cmp eax,1 jne @@MF invoke ReleaseCapture invoke SendMessage,[hWin], WM_SYSCOMMAND, SC_MOVE+2, 0 xor eax,eax @@MF: ret
Как вариант: case WM_LBUTTONDOWN: DefWindowProc(hWnd, message, wParam, lParam); return DefWindowProc(hWnd, WM_NCLBUTTONDOWN, HTCAPTION, lParam);
Насчет драгдропа окна по uMsg==WM_MOUSEMOVE && wParam==MK_LBUTTON (piritus): для SendMessage(hWnd,WM_SYSCOMMAND,x,0) при x=SC_MOVE+2 либо x=SC_MOVE+1 добавка && wParam==MK_LBUTTON бесполезна. Но она необходима при x=SC_SIZE+9. verelex: Причем тут регионы ? Как понять "перестает работать PtInRegion" ? Пожалуйста, проясните, а то ваш код как-то до меня не доходит.
kero, да в данном случае это, возможно, не нужно... копировал из своего кода, там это необходимо, т.к. за @@MF идет заполнение структуры TRACKMOUSEEVENT и вызов TrackMouseEvent. Проверка, находится ли курсор над формой.
Короче, PtInRegion поминался тут всуе (а жаль). Суть же в том, что момент завершения драгдропа (отпускание мышки) ловится не по напрашивающемуся WM_NCLBUTTONUP, а - прдокс! - по WM_NCLBUTTONDOWN: Код (Text): .data _ft db "( %d , %d ) // " _class db "UpOrDown",0 .data? .code UpProc proc hWnd:HWND local buf[128]:BYTE local pt:POINT invoke GetCursorPos,addr pt invoke wsprintf,addr buf,offset _ft,pt.x,pt.y invoke SetWindowText,hWnd,addr buf ret UpProc endp WndProc proc hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM .if uMsg==WM_DESTROY invoke PostQuitMessage,0 xor eax,eax .elseif uMsg==WM_NCHITTEST mov eax,HTCAPTION .else invoke DefWindowProc,hWnd,uMsg,wParam,lParam push eax .if uMsg==WM_NCLBUTTONDOWN ; || uMsg==WM_NCLBUTTONUP, if WS_MAXIMIZE. invoke UpProc,hWnd .endif pop eax .endif ret WndProc endp
Сорри, что долго не пояснял суть проблемы. Имеется фигура (Polygon): Код (Text): points->x=20; points->y=30; (points+1)->x=20; (points+1)->y=20; (points+2)->x=80; (points+2)->y=20; (points+3)->x=80; (points+3)->y=30; hRgns = CreatePolygonRgn(points,4,ALTERNATE); ... Код (Text): SetWorldTransform(...);// поворачиваем все на угол, напримкр 90 градусов //как я понял это привязывается к HDC. ... PaintRgn(hdc,hRgn);// повернут(перемещен) после SetWorldTransform() // все номально, он рисуется повернутым. ... далее, если мы сделаем перемещение формы(окна) за любую точку стандартным способом, то ничего не получится (у меня не получилось), т.к. при перемемещении курсора по горизонатли, фигура перемещается по другому (координатные оси смещены), поэтому использую WM_NC... Код (Text): case WM_NCRBUTTONUP: point.x = GET_X_LPARAM(lParam); point.y = GET_Y_LPARAM(lParam); ScreenToClient(hWnd,&point); //в WM_NCRBUTTONUP передаются screen-координаты, а в PtInRegion() - client. for (int i=0; i<iRegionsCount; i++) { if (PtInRegion(hRgns[i],point.x,point.y)) { MessageBox(hWnd,"xe xe",NULL,MB_OK); continue; } } break; //PtInRegion находит полигон в "прошлом" месте (в котором он был до вызова ф-ии SetWorldTransform). По-моему это из-за того, что не учитывается hdc. P.S. PtInRegion(hRgn,x,y) работает с координатами, в которых начало в верхем левом углу окна. И берет видимо points из RGNDATA (как и PaintRgn(hdc,hRgn)). Если бы была функция: PtInRegion(hdc,hrgn,x,y) ...
verelex >По-моему это из-за того, что не учитывается hdc. Боюсь, не из-за этого. Почему бы вам не все-таки не выложить здесь exe-иллюстрацию проблемы с полным исходником (чтобы исключить недосказанности вроде SetWorldTransform) ?
verelex Видимо, я все еще не ухватил суть вашей проблемы, потому как опять не удалось воспроизвести описанный вами феномен. Налицо и CreatePolygonRgn, и SetWorldTransform, и PaintRgn, - а окно перемещается вполне банально: Код (Text): R4toR4 macro v1,v2 fld v1 fstp v2 endm XFORM4 struct eM11 REAL4 ? eM12 REAL4 ? eM21 REAL4 ? eM22 REAL4 ? ex REAL4 ? ey REAL4 ? XFORM4 ends .data _class db "test",0 pts dd 100,40, 100,10, 180,10, 180,40 cos_ REAL4 0.8660 ; (angle=30°) sin_ REAL4 0.5000 nsin_ REAL4 -0.5000 xy_ REAL4 0.0 .data? hrgn HRGN ? flag dd ? .code WndProc proc hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM local ps:PAINTSTRUCT local hdc:HDC local xform4:XFORM4 .if uMsg==WM_DESTROY invoke DeleteObject,hrgn invoke PostQuitMessage,0 xor eax,eax .elseif uMsg==WM_CREATE invoke CreatePolygonRgn,addr pts,4,ALTERNATE mov hrgn,eax xor eax,eax .elseif uMsg==WM_PAINT invoke BeginPaint,hWnd,addr ps mov hdc,eax invoke SetGraphicsMode,hdc,GM_ADVANCED R4toR4 cos_, xform4.eM11 R4toR4 sin_, xform4.eM12 R4toR4 nsin_, xform4.eM21 R4toR4 cos_, xform4.eM22 R4toR4 xy_ , xform4.ex R4toR4 xy_ , xform4.ey invoke SetWorldTransform,hdc,addr xform4 invoke PaintRgn,hdc,hrgn invoke ModifyWorldTransform,hdc,addr xform4,MWT_IDENTITY invoke SetGraphicsMode,hdc,GM_COMPATIBLE invoke EndPaint,hWnd,addr ps xor eax,eax .elseif uMsg==WM_NCHITTEST && flag==0 mov eax,HTCAPTION .elseif uMsg==WM_MBUTTONDOWN || uMsg==WM_NCMBUTTONDOWN xor flag,1 xor eax,eax .else invoke DefWindowProc,hWnd,uMsg,wParam,lParam .endif ret WndProc endp
verelex >Спасибо. 1) Ну, и зачем вы стерли пост, который наконец-то объяснял, что вам надо? Теперь придется его цитировать... 2) Прилагаю прикидочный черновичок для регионов (которым, кстати, SetworldTransform без надобности): Код (Text): XFORM4 struct eM11 REAL4 ? eM12 REAL4 ? eM21 REAL4 ? eM22 REAL4 ? ex REAL4 ? ey REAL4 ? XFORM4 ends .data _class db "XFORM_4_REGION",0 plgn dd 100,80, 100,50, 180,50, 180,80, 140,100 ; (polygon, 5 points) angle dd 45 ; (45°) .data? hrgn HRGN ? x0 dd ? y0 dd ? drdr dd ? ; (region dragdrop) htflag dd ? ; (window dragdrop) .code XformRotation proc angl:DWORD,x:DWORD,y:DWORD,lpxform:DWORD local val:DWORD mov ecx,lpxform assume ecx:ptr XFORM4 mov val,180 fldpi fimul angl fidiv val fsincos fst [ecx].eM11 ; (cos) fstp [ecx].eM22 ; (cos) fst [ecx].eM12 ; (sin) fchs fstp [ecx].eM21 ; (-sin) fild x fstp [ecx].ex fild y fstp [ecx].ey assume ecx:nothing ret XformRotation endp XformRotationRgn proc uses ebx edi rgn:HRGN,angl:DWORD,lpxform:DWORD invoke GetRegionData,rgn,0,0 mov ebx,eax ; (dwCount) invoke VirtualAlloc,0,ebx,MEM_COMMIT,PAGE_READWRITE mov edi,eax ; (lpRgnData) invoke GetRegionData,rgn,ebx,edi invoke XformRotation,angl,0,0,lpxform invoke ExtCreateRegion,lpxform,ebx,edi push eax invoke VirtualFree,edi,0,MEM_RELEASE invoke DeleteObject,rgn ; (old hrgn) pop eax ; (new hrgn) ret XformRotationRgn endp ClientPtInRgn proc uses ebx hWnd:HWND,rgn:HRGN,lppt:DWORD mov ebx, lppt assume ebx:ptr POINT invoke GetCursorPos,ebx invoke ScreenToClient,hWnd,ebx invoke PtInRegion,rgn,[ebx].x,[ebx].y assume ebx:nothing ret ClientPtInRgn endp WndProc proc uses ebx edi hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM local pt:POINT local rt:RECT local ps:PAINTSTRUCT local xform:XFORM4 .if uMsg==WM_DESTROY invoke DeleteObject,hrgn invoke PostQuitMessage,0 xor eax,eax .elseif uMsg==WM_CREATE invoke CreatePolygonRgn,addr plgn,4,ALTERNATE mov hrgn,eax mov eax,80000001h jmp @f .elseif uMsg==WM_MOUSEWHEEL mov eax,wParam @@: mov ecx,angle .if eax<80000000h neg ecx .endif invoke XformRotationRgn,hrgn,ecx,addr xform mov hrgn,eax invoke InvalidateRect,hWnd,0,1 xor eax,eax .elseif uMsg==WM_PAINT invoke BeginPaint,hWnd,addr ps invoke PaintRgn,eax,hrgn invoke EndPaint,hWnd,addr ps xor eax,eax .elseif uMsg==WM_LBUTTONDOWN && drdr==0 invoke ClientPtInRgn,hWnd,hrgn,addr pt .if eax!=0 mov drdr,eax mov eax,pt.x mov x0,eax mov eax,pt.y mov y0,eax .endif jmp @dwp .elseif uMsg==WM_LBUTTONUP && drdr!=0 xor eax,eax mov drdr,eax jmp @dwp .elseif uMsg==WM_MOUSEMOVE && wParam==MK_LBUTTON invoke ClientPtInRgn,hWnd,hrgn,addr pt .if drdr!=0 .if eax!=0 mov eax,pt.x mov edx,x0 mov x0,eax sub eax,edx mov ecx,pt.y mov edx,y0 mov y0,ecx sub ecx,edx invoke OffsetRgn,hrgn,eax,ecx invoke InvalidateRect,hWnd,0,1 .else mov drdr,eax .endif .else jmp @dwp .endif .elseif uMsg==WM_MBUTTONDOWN || uMsg==WM_NCMBUTTONDOWN xor htflag,1 xor eax,eax .elseif uMsg==WM_NCHITTEST && htflag!=0 invoke ClientPtInRgn,hWnd,hrgn,addr pt .if eax==0 mov eax,HTCAPTION .else jmp @dwp .endif .else @dwp: invoke DefWindowProc,hWnd,uMsg,wParam,lParam .endif ret WndProc endp Включить/выключить драгдроп окна: клик средней кнопки мышки (попутно меняется и курсор: с лапы на стрелку). Драгдроп и окна, и региона - как обычно: левой кнопкой. Повернуть регион (а точнее - заменить старый новым, повернутым): мышкино колесико вперед/назад => поворот на угол +45°/-45°. Покрутите колесико туда-сюда подольше...