PDA

View Full Version : آموزش: نحوه حرکت دارن فرمهای ویندوزی بدون Titlebar



alireza_s_84
یک شنبه 05 مهر 1388, 22:35 عصر
سلام دوستان:
یکی از کاربران این سوال رو مطرح کرده بودن دیدم تاپیک جداگانه بزنم بهتره . ضمنا در تمامی زبانهایی که از توابع API پشتیبانی میکنن این مساله که در زیر مطرح میکنم صدق میکنه (فقط در پیاده سازی یه خورده متفاوته)
وقتی که فرم برنامه شما رویدادهای موس رو هندل میکنه (کلا فرمهای تحت ویندوز) از یکسری پیغامهایی برای ردو بدل کردن این اطلاعات استفاده میشه.
برای مثال وقتی شما هر کدون از رویداد های موس رو که در نظر بگیرید رخ میده ویندوز یک پیغام WM_NCHITTEST رو به فرم میفرسته تا معین بکنه که رویداد موس کجا اتفاق افتاده است.
حالا این پیغام ها یک سری مقادیر دارن که معین میکنن قسمتی از فرم که کلیک شده کجاست. مثلا Titlebar فرم HTCAPTION رو برمیگردونه.(که نشون میده کاربر Titlebar رو کلیک کرده) حالا وقتی شما روی قسمتی از فرم که محل قرار دادن کنترلهاست کلیک میکنید (به این ناحیه Client Area گفته میشه یعنی ناحیه کاربری) مقدار HTCLIENT به فرم پاس داده میشه که نشون میده کاربر ناحیه کاربری فرم رو کلیک کرده.
حالا با دونستن مطالب فوق میتونیم کاری کنیم که هرجای فرم رو که کلیک کردیم بتونیم اونو حرکت بدیم(بدون نیاز به هیچ کامپوننت و یا چیز دیگری فقط با دو خط کد)
هر فر ویندوزی یک رویداد WndProc داره که تمامی پیغامهای ارسالی به فرم رو هندل میکنه. با Override کردن این متد میتونیم منطق خودمون رو به فرم تحمیل کنیم.
در این متد باید چک بکنیم که اگه پیغام WM_NCHITTEST بود (پیغام مربوط به رویدادهای موس) مقدار ارسالی رو لغو کنیم و مقدار مورد نظر خودمون رو جایگزین کنیم ( در اینکار مقدار ارسالی HTCAPTION هست که باید با مقدار مورد نظرمون یعنی HTCLIENT جایگزین بشه)
حالا تمامی دونستنی هامون رو کنار هم میذاریم و کد رو مینویسیم




private const int WM_NCHITTEST = 0x84;

private const int HTCLIENT = 0x1;

private const int HTCAPTION = 0x2;

protected override void WndProc(ref Message m)

{

switch(m.Msg)

{

case WM_NCHITTEST:

base.WndProc(ref m;)

if ((int)m.Result == HTCLIENT)

m.Result = (IntPtr)HTCAPTION;

return;

break;

{

base.WndProc (ref );

{


موفق باشید

ali_autumnal
یک شنبه 05 مهر 1388, 23:37 عصر
من که نفهمیدم این کد رو باید تو کدوم رویداد بنویسم تا فرم حرکت کنه.:ناراحت::افسرده:

Saeed.Masoumi
یک شنبه 05 مهر 1388, 23:49 عصر
در کل جالب بود
اما فرض کن قرار روی فرم یک سری اتفاقات توسط موس اجرا بشه مثه کلیک کردن و...
این روش شما مشکلی ایجاد نمی کنه؟

alireza_s_84
دوشنبه 06 مهر 1388, 00:35 صبح
من که نفهمیدم این کد رو باید تو کدوم رویداد بنویسم تا فرم حرکت کنه.:ناراحت::افسرده:
دوست عزیز همین کد رو توی کلاس فرمتون کپی کنید ضمنا اگه خوب بخونید گفتم که توی کدوم رویداد اینکار انجام میشه

alireza_s_84
دوشنبه 06 مهر 1388, 00:39 صبح
در کل جالب بود
اما فرض کن قرار روی فرم یک سری اتفاقات توسط موس اجرا بشه مثه کلیک کردن و...
این روش شما مشکلی ایجاد نمی کنه؟
کارهایی عادی که همه برنامه نویس ها انجام میدن نه مشکلی بوجود نمیاد اما در یه سطح پیشرفته تر برای هندل کردن رویدادهای موس باید بصورت دستی عمل کنید
در کل مشکلی در پروژه هایی که من و شما مینویسیم بوجود نمیاره
ضمنا این روش رو از خود MSDN پیدا کردم و MediaPlayer هم از اونو استفاده میکنه

ali_autumnal
جمعه 24 مهر 1388, 09:11 صبح
لطفا در مورد استفاده از این تابع بیشتر توضیح بدید.

هرجایی که میخوام فراخونی کنمش ایراد میگیره!!!!!!

alireza_s_84
جمعه 24 مهر 1388, 09:41 صبح
لطفا در مورد استفاده از این تابع بیشتر توضیح بدید.

هرجایی که میخوام فراخونی کنمش ایراد میگیره!!!!!!
سلام دوست عزیز :
این یک متد نیست که شما اونو فراخونی کنید بلکه یکی از event های فرم است(ایونت WndProc) که باید OverRide کنید
موفق باشید

ali_autumnal
جمعه 24 مهر 1388, 10:05 صبح
خوب حالا چطور OverRide کنم؟
بابا کمی توضیح بدید. نمیشه؟ سخته؟:چشمک:

alireza_s_84
جمعه 24 مهر 1388, 10:46 صبح
خوب حالا چطور OverRide کنم؟
بابا کمی توضیح بدید. نمیشه؟ سخته؟:چشمک:
دوست گرامی در همون تاپیک اول به خوبی و سادگی توضیح دادم . ساده تر از این نمیشه نمیشه توضیح داد. شما ابتدا با اصول اولیه برنامه نویسی آشنا بشید بعد سراغ این جور مسائل برید چون اگه بخواید بدون شناخت (لازم نیست این شناخت عمیق باشه سطحی هم کافیه) اینکارها رو بکنید به نتیجه مطلوب نمیرسید.
ضمنا اگه با #C مینویسید لازمه کل کد رو توی کلاس کپی کنید. دیگه لازم نیست کاری انجام بدید.
موفق باشید

saeeedft
جمعه 24 مهر 1388, 11:02 صبح
اقا ممنون،خیلی کامل و جالب بود، بازم از این چیزا برامون بذار

alireza_s_84
جمعه 24 مهر 1388, 12:21 عصر
اقا ممنون،خیلی کامل و جالب بود، بازم از این چیزا برامون بذار
خواهش میکنم دوست عزیز چیز ناقابلی بود
شما بپرس بلد باشم در خدمتم حتما جواب میدم.
موفق باشی

saeeedft
جمعه 24 مهر 1388, 12:41 عصر
در مورد API چیزهای دیگه ای هم دارید که جالب باشه و کاربرد داشته باشه

seven7777777
سه شنبه 25 اسفند 1388, 09:26 صبح
دوست عزیز سلام
چند مورد :
1. این base.wndproc چکار می کنه ؟
2. کلا اگه بتونی یه آموزش کامل برای کار با توابع API به زبان ساده و از مبتدی بزاری ممنون میشم .
3. این ارتباط با API میتونه برای تاثیر گذاری روی برنامه های دیگه خارج برنامه خودمون استفاده کنیم یا نه ؟

alireza_s_84
سه شنبه 25 اسفند 1388, 10:03 صبح
دوست عزیز سلام
چند مورد :
1. این base.wndproc چکار می کنه ؟
2. کلا اگه بتونی یه آموزش کامل برای کار با توابع API به زبان ساده و از مبتدی بزاری ممنون میشم .
3. این ارتباط با API میتونه برای تاثیر گذاری روی برنامه های دیگه خارج برنامه خودمون استفاده کنیم یا نه ؟
سلام دوست عزیز:
سوال اولتون رو توی تاپیک زیر جواب دادم
http://barnamenevis.org/forum/showthread.php?t=210549
کلا توی تاپیک بالا قصد دارم در اینمورد کاملا توضیح بدم
آموزش توابع API لزومی نداره چون دات نت خیلی منسجمتر عملکرده و همه رو یکجا و منطقی کنار هم چیده.
با استفاده از توابع API شما به هر پنجره و فرمی که دوست دارید میتونید از برنامه خودتون با خارج ارتباط برقرار کنید
موفق باشید

Himalaya
سه شنبه 25 اسفند 1388, 10:19 صبح
جابجا کردن فرم با کلیک بر روی هر قسمت از آن - با استفاده از توابع API
http://barnamenevis.org/forum/showpost.php?p=468975&postcount=40


using System.Runtime.InteropServices;

[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;

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


جابجا کردن فرم با کلیک بر روی هر قسمت از آن - بدون استفاده از توابع API
http://barnamenevis.org/forum/showpost.php?p=469375&postcount=52


private bool dragging;
private Point pointClicked;
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
// Turn drag mode on and store the point clicked.
dragging = true;
pointClicked = new Point(e.X, e.Y);
}
else
{
dragging = false;
}
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (dragging)
{
Point pointMoveTo;
// Find the current mouse position in screen coordinates.
pointMoveTo = this.PointToScreen(new Point(e.X, e.Y));
// Compensate for the position the control was clicked.
pointMoveTo.Offset(-pointClicked.X, -pointClicked.Y);
// Move the form.
this.Location = pointMoveTo;
}
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
dragging = false;
}

teardrop
سه شنبه 25 اسفند 1388, 11:03 صبح
این کدها رو نگاه کن:

Merila_Rad
دوشنبه 17 خرداد 1389, 16:40 عصر
ممنون از alireza_s_84 (http://barnamenevis.org/forum/member.php?u=35861) به خاطر مطلب مفیدشون
من کد بالا را اجرا کردم جواب هم داد فقط یک خطا گرفت که اون هم با تغییر خط زیر به صورت خط زیرش درست شد
if ((int)m.Result == HTCLIENT)
if ((int)m.Result == 5)

Merila_Rad
دوشنبه 17 خرداد 1389, 16:54 عصر
درباره سوال ali_autumnal (http://barnamenevis.org/forum/member.php?u=65365) در مورد محل کپی کردن این کدها، کدهای بالا را به همراه قسمتی از سایر کدهای فرم قرار میدم مطمئنا محلش قابل درک میشه

public partial class Form1 : Form
{


public Form1()
{
InitializeComponent();

}


private const int WM_NCHITTEST = 0x84;
private const int HTCLIENT = 0x1;
private const int HTCAPTION = 0x2;
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case WM_NCHITTEST:
base.WndProc(ref m);
if ((int)m.Result == 5)
m.Result = (IntPtr)HTCAPTION;
return;
break;
}
base.WndProc(ref m);
}using System.Runtime.InteropServices;




.
.
.

mojdeh6583
دوشنبه 15 شهریور 1389, 11:43 صبح
این کدها رو نگاه کن:

نمونه برنامه ای که شما قرار دادید شایسته ی تقدیره

اَرژنگ
چهارشنبه 17 شهریور 1389, 09:07 صبح
نمونه برنامه ای که شما قرار دادید شایسته ی تقدیره
خیر مثالی که karaji333 فرستادند تمیزتره،
استفاده بیجهت از استاتیک نه تنها تمیز نیست بلکه اشتباه هم هست.

mahboube
یک شنبه 18 مهر 1389, 16:47 عصر
با اين كداساده تر ميشه فرم رو جابجا كرد!!!!!



private void Form2_MouseDown(object sender, MouseEventArgs e)
{
x = e.Location.X;
y = e.Location.Y;
}
private void Form2_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
this.Left += e.X - x;
this.Top += e.Y - y;
}
}