PDA

View Full Version : تغییر مکان کنترل ها با موس در زمان اجرا



ali_autumnal
دوشنبه 23 اسفند 1389, 10:34 صبح
با سلام و خسته نباشید،

میخوام در زمان اجرا کاربر با انتخاب کنترل (شئ) مورد نظر بتونه مکان یا موقعیت اون رو تغییر بده.

برای اینکار من از کد زیر استفاده کردم:




using System.Runtime.InteropServices;

متغیرهای مورد نیاز:




private Control ctrl;
[DllImport("user32.dll")]
static extern int ReleaseCapture();
[DllImport("user32.dll", EntryPoint = "SendMessageA")]
static extern int SendMessage(int hwnd, int wMsg, int wParam, object lParam);
private const int WM_NCLBUTTONDOWN = 161;



تابع مورد نظر در رویداد Form MouseDown


private void Form1_MouseDown(object sender, MouseEventArgs e)
{
ReleaseCapture();
SendMessage(ctrl.Handle.ToInt32(), WM_NCLBUTTONDOWN, 2, 0);
}


یه مثال گذاشتم اگه امکانش هست دانلود کنید و تست کنید.

با کلیک روی هر کنترل میتونید مکان اون کنترل رو تغییر بدهید.

اینم تابع ارسال کنترل که تو رویداد کیلک کنترل ها این تابع انتخاب شده است:




private void SelectControl(object sender, System.EventArgs e)
{
ctrl = ((Control)sender);
}


همه کنترل ها با کد فوق قابل تغییر هستن بجز label و linklabel

از قرار معلوم کنترل های مورد نظر Handle نمیکنند!

چیکار کنم که این کنترل ها هم با این روش تغییر مکان بدهند؟

با تشکر
علی پاییزی

ali_autumnal
دوشنبه 23 اسفند 1389, 21:55 عصر
کسی از دوستان اطلاعاتی در این باره نداره؟

ali_autumnal
چهارشنبه 25 اسفند 1389, 12:17 عصر
کسی از دوستان اطلاعاتی در این باره نداره؟

من همچنان منتظرم

خودمم اگه پیدا کردم حتما تو اینجا اطلاع میدم.

ali_autumnal
جمعه 27 اسفند 1389, 12:38 عصر
کسی از دوستان اطلاعاتی در این باره نداره؟

shadi khanum
شنبه 28 اسفند 1389, 11:53 صبح
من یه Sample نوشتم واستون ولی نشد uploadesh کنم. مجبور شدم کداشو واستون بذارم. اینجوری هر کنترلی رو میتونین حرکت بدین label و linklabel و هر چی دیگه فرقی نداره
فرض کنین یه label دارین ، سه تا رویداد mouseDown و mouseMove و MouseUp رو براش ایجاد کنید و کدای زیر رو واسه هرکدوم از رویدادها بنویسین
private void Lbl_Test_MouseDown(System.Object sender, System.Windows.Forms.MouseEventArgs e)
{
try
{
Lbl_Test.BringToFront();
if (e.Button == MouseButtons.Left)
{
Dragging = true;
Mouse_x = -e.X;
Mouse_y = -e.Y;
int clipleft = this.PointToClient(MousePosition).X - Lbl_Test.Location.X;
int cliptop = this.PointToClient(MousePosition).Y - Lbl_Test.Location.Y;
int clipwidth = this.ClientSize.Width - (Lbl_Test.Width - clipleft);
int clipheight = this.ClientSize.Height - (Lbl_Test.Height - cliptop);
Cursor.Clip = this.RectangleToScreen(new Rectangle(clipleft, cliptop, clipwidth, clipheight));
Lbl_Test.Invalidate();
}
}
catch (Exception ex)
{
MessageBox.Show (ex.ToString());
}
}

private void Lbl_Test_MouseMoveEvent(System.Object sender, System.Windows.Forms.MouseEventArgs e)
{
try
{
if (Dragging)
{
Point MPosition = new Point();
MPosition = this.PointToClient(MousePosition);
MPosition.Offset(Mouse_x, Mouse_y);
Lbl_Test.Location = MPosition;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}


private void Lbl_Test_MouseUpEvent(System.Object sender, System.Windows.Forms.MouseEventArgs e)
{
try
{
if (Dragging)
{
Dragging = false;
Cursor.Clip = new Rectangle();

Lbl_Test.Invalidate();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}


ضمنا این سه تا متغیر رو هم بصورت سراسری تو فرمتون تعریف کنید
bool Dragging = false;
int Mouse_x = 0;
int Mouse_y = 0;
موفق باشید

ali_autumnal
یک شنبه 29 اسفند 1389, 13:34 عصر
من یه Sample نوشتم واستون ولی نشد uploadesh کنم. مجبور شدم کداشو واستون بذارم. اینجوری هر کنترلی رو میتونین حرکت بدین label و linklabel و هر چی دیگه فرقی نداره
فرض کنین یه label دارین ، سه تا رویداد mouseDown و mouseMove و MouseUp رو براش ایجاد کنید و کدای زیر رو واسه هرکدوم از رویدادها بنویسین
private void Lbl_Test_MouseDown(System.Object sender, System.Windows.Forms.MouseEventArgs e)
{
try
{
Lbl_Test.BringToFront();
if (e.Button == MouseButtons.Left)
{
Dragging = true;
Mouse_x = -e.X;
Mouse_y = -e.Y;
int clipleft = this.PointToClient(MousePosition).X - Lbl_Test.Location.X;
int cliptop = this.PointToClient(MousePosition).Y - Lbl_Test.Location.Y;
int clipwidth = this.ClientSize.Width - (Lbl_Test.Width - clipleft);
int clipheight = this.ClientSize.Height - (Lbl_Test.Height - cliptop);
Cursor.Clip = this.RectangleToScreen(new Rectangle(clipleft, cliptop, clipwidth, clipheight));
Lbl_Test.Invalidate();
}
}
catch (Exception ex)
{
MessageBox.Show (ex.ToString());
}
}

private void Lbl_Test_MouseMoveEvent(System.Object sender, System.Windows.Forms.MouseEventArgs e)
{
try
{
if (Dragging)
{
Point MPosition = new Point();
MPosition = this.PointToClient(MousePosition);
MPosition.Offset(Mouse_x, Mouse_y);
Lbl_Test.Location = MPosition;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}


private void Lbl_Test_MouseUpEvent(System.Object sender, System.Windows.Forms.MouseEventArgs e)
{
try
{
if (Dragging)
{
Dragging = false;
Cursor.Clip = new Rectangle();

Lbl_Test.Invalidate();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}


ضمنا این سه تا متغیر رو هم بصورت سراسری تو فرمتون تعریف کنید
bool Dragging = false;
int Mouse_x = 0;
int Mouse_y = 0;
موفق باشید


با سلام و خسته نباشید:

دوست عزیز واقعا متشکرم که پاسخ دادی.
کدی مه ارائه دادی دقت حرکت کنترل ها خیلی پایین هست.
کدی که من گذاشتم دقت فوق العاده ای داره.

ali_autumnal
سه شنبه 02 فروردین 1390, 01:33 صبح
با سلام

با کد زیر لیبل یا هر کنترل دیگه ای قابل حرکت دادنه اما کمی ایراد داره و کنترل روان و با دقت 100% تغییر مکان نمیده. اما بهتر از کد قبلیه

متغیر های مورد استفاده:

private Control ctrl;
bool Dragging = false;
Point NewLocation = new Point();


و توابع مورد استفاده:

نکته: کلیه کنترل ها را انتخاب کرده و توابع زیر را در رویدادهای مورد نیاز با توجه به نام توابع انتحاب کنید.


private void ControlClick(object sender, System.EventArgs e)
{
ctrl = ((Control)sender);
}
//////================================================== =================================================
private void ControlMouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
Dragging = true;
NewLocation = new Point(e.X, e.Y);
}
}
//////================================================== =================================================
private void ControlMouseMove(System.Object sender, System.Windows.Forms.MouseEventArgs e)
{
if (Dragging)
{
ctrl.Left += e.X - NewLocation.X / 2;
ctrl.Top += e.Y - NewLocation.Y / 2;
NewLocation = new Point(e.X, e.Y);

}
}
//////================================================== =================================================
private void ControlMouseUp(System.Object sender, System.Windows.Forms.MouseEventArgs e)
{
Dragging = false;
}


کاش میشد کد بی نقصی رو یکی از دوستان ارائه میداند.