ورود

View Full Version : حرکت دادن یک عکس با استفاده از موس



BeginnerProgrammer
یک شنبه 10 مرداد 1389, 18:33 عصر
سلام
چطوری میشه عکسی رو که تویه دیالوگ باکس وارد کردیم هنگام اجرا با نگه داشتن کلیک چپ موس رو صفحه نمایش حرکت کنه ، بعد از رها کردن کلیک موس هم بتونیم مکان جدید عکس رو پیدا کنیم( برنامه با ام اف سیه)
Tanx

Nima_NF
دوشنبه 11 مرداد 1389, 01:02 صبح
نمایش عکس شما باید در Onpaint یا OnDraw یا مانند آن باشد تا همواره نشان داده شود.
اگر عکس به شکل control picture هست که فقط کافیست متغیرها را دریافت کنید و سپس با SetWindowPos مکان کنونی control عکس را تغییر دهید و InvalidateRect نیز نیاز نیست.

مکان های کنونی موس را با چند متغیر از پیام های زیر باید دریافت کنید:

پیام WM_LBUTTONDOWN وقنی کلید چپ موس پایین هست، این موقع یک متغیر bool را true کنید و در پیام WM_MOUSEMOVE چک کنید اگر این متغیر Down به شکل true شده است اطلاعات کنونی point که X , Y موس هست را بگیرید. (این متغیر ها باید در تابع نمایش عکس در OnPaint استفاده شده باشد)

در پایان هر پیام حتما تابع InvalidateRect را فراخوانی کنید تا یک مربته در هر حرکت موس صفحه refresh شود.

برای مرحله نهایی نیز متغیر ها را در پیام WM_LBUTTONUP هنگام ول کردن کلید موس بگیرید.

دقت کنید X و Y موس در پارامتر این پیام ها به شکل Point به شما داده می شود.
توابع پردازش کننده WM_LBUTTONUP نیز پیش فرض OnLButtonUp هست.

BeginnerProgrammer
دوشنبه 11 مرداد 1389, 14:53 عصر
من یه عکس با استفاده از Picture control گذاشتم تو صفحه م بعدشم یک دکمه و این کدو برای دکمه م نوشتم ولی هیچ کاری انجام نمیده


void CModlessDlg::OnBnClickedButton1()
{
UpdateData(1);
m_picCtrl.SetWindowPos(this,20,20,120,120,NULL);
// TODO: Add your control notification handler code here
}

m_picCtrl اسمیه که برای کنترل عکسم گذاشتم.
اشکالش کجاس؟؟؟؟؟؟:عصبانی++:

Nima_NF
دوشنبه 11 مرداد 1389, 17:22 عصر
وقتی picture control را ساختید، ID را مثلا به IDC_STATIC_PIC تغییر دهید، سپس متغیری از نوع CStatic بسازید.

کد زیر بدون مشکل باید آن را تغییر مکان یا تغییر اندازه دهد:



m_pic1.SetWindowPos(NULL,20,20,120,120,SWP_NOZORDE R);

BeginnerProgrammer
سه شنبه 12 مرداد 1389, 02:12 صبح
چیزی که شما نوشتینو نوشتم کار میکرد(Tanx alot) ولی وقتی کد زیر رو تویه تابع OnPaint() مینویسم همشه داخل if میشه


POINT coor;
GetCursorPos(&coor);
UpdateData(true);

if(WM_MOUSEMOVE){
if(WM_RBUTTONDOWN){
m_picCtrl.SetWindowPos(NULL,40,40,30,82,SWP_NOZORD ER);
}
}
InvalidateRect(NULL,1);


لطفا کمک کنید.
با تشکر

Nima_NF
سه شنبه 12 مرداد 1389, 17:38 عصر
این طرز نوشتن کد در MFC صحیح نیست.
شما باید برای پیام های موس و کیبرد از طریق پنجره event یک تابع بنویسید تا هر وقت اعمال شدند فورا آن توابع (مربوط به پیام) اجرا شوند، با if فقط در همان لحظه داخل OnPaint اگر رخ دهد اعمال می شود که صحصیح نیست.

در پست آخر تاپیک زیر به همراه عکس توضیح دادم که چطور مثلا پیام BN_CLICKED را برای یک Button بسازید، شما کافیست دیالوگ را انتخاب کنید و سپس از همان پنجره برای پیام WM_MOUSEMOVE یک تابع بنویسید که خودکار کدها را تولید می کند.
سپس شما فقط متغیر ها را از آن بگیرید و در تابع Onpaint از آن ها استفاده کنید.
http://barnamenevis.org/forum/showthread.php?t=166559

if را کنار بگذارید و داخل توابع تولید شده فوق با متغیر های bool بررسی کنید که هر دو فعال هستند با خیر (یعنی اگر move متغیر true دارید و down هنوز false هست شما همچنان دارید موس را حرکت می دهید )


تذکر: مجددا پست قبلی بنده را مطالعه کنید، اگر از picture control استفاده کرده اید اصلا نیازی به OnPaint ندارید، OnPaint زمانی هست که خودتان با توابع می خواهید یک عکس را در background دیالوگ نمایش دهید، نه برای کنترل ها.

BeginnerProgrammer
سه شنبه 12 مرداد 1389, 23:49 عصر
با تشکر از جوابهای قبلیتان، اما متأسفانه من هنوز نتوانستم یک عکس قابل درگ کردن را ایجاد کنم اگر امکان دارد یک نمونه از کدی که شما در این باره نوشتید را نشان دهید
با تشکر فراوان :لبخندساده:

Nima_NF
چهارشنبه 13 مرداد 1389, 03:00 صبح
قطعه کدهای زیر سه پیام ذکر شده هست که باید از قسمت Messages برای هر کدام یک تابع تولید کنید و سپس کدهای داخل آن را بنویسید.

3 متغیر اول را ها نیز داخل کلاس به شکل private تعریف کنید.



BOOL isSelected;
BOOL isMoving;
CPoint currentPt;


پیام ها (توابع) موس در دیالوگ:



void CMFC_activex1Dlg::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default

CRect rc, rc2;
m_pic1.GetWindowRect(&rc);
ScreenToClient(&rc);

currentPt.SetPoint( rc.left - point.x, rc.top - point.y );
isSelected = rc.PtInRect(point);

CDialogEx::OnLButtonDown(nFlags, point);
}


void CMFC_activex1Dlg::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if(isSelected)
m_pic1.SetWindowPos(NULL, currentPt.x + point.x, currentPt.y + point.y, 0, 0, SWP_NOZORDER | SWP_NOSIZE);

CDialogEx::OnMouseMove(nFlags, point);
}


void CMFC_activex1Dlg::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
isSelected = FALSE;

CDialogEx::OnLButtonUp(nFlags, point);
}