تبلیغات
برنامه نویسی و الکترونیک - ساخت یک Message Handler در دلفی 7
 
منوی اصلی


--------------------------

--------------------------

--------------------------

--------------------------


سفارش پروژه

E-Mail :
Mahmood_Mehri@Hotmail.com

سایت برنامه نویس :  Mahmood_M


موضوعات

دانلود نرم افزار
 
تخصصی برنامه نویسی
  تخصصی برق ( الکترونیک )
  کامپوننت ها و ابزارها
  نرم افزارهای متفرقه
برنامه نویسی
  مباحث عمومی
  آموزش Delphi

  آموزش زبان C++ / C
 
آموزش Matlab

  آموزش زبان Assembly
  آموزش DataBase

الکترونیک
  مباحث عمومی
  مباحث عمومی الکترونیک
  معرفی قطعات الکترونیکی
  کار با مولتی متر
  مدارات الکترونیک
  میکروکنترلر
  میکروکنترلرهای AVR
  پروژه ها
مباحث متفرقه
  آموزشهای متفرقه
  معرفی سایت
  معرفی کتاب
  پاسخ به سئوالات
  مطالب عمومی


لینك دوستان
:: جک :: اس ام اس :: عکس
:: الکترونیک 89 گیلان
:: سورسهای نرم افزاری
:: اینترنت بدون تحریم
:: علمی.کتاب.مجله.نرم افزار.مقاله
:: مبارزات آزاد
:: برنامه نویسی از اهل زمین
:: :: جزیره ی دانلود ::
:: :: کامپیوتر و IT ::
:: بزرگترین پایگاه مدل لباس اینترنتی
:: مرکز دانلود ایرانیان
:: پایگاه علمی مهندسی تراشه
:: تمامی راهکارهای کامپیوتری
:: برنامه نویسی و طراحی وب
:: خرید ساعت دیواری
:: :: فناوری روز ::
:: :: همه چیز واسه موبایل ::
:: آموزش تخصصی کامپیوتر
:: * پیاز داغ اینترنت ! *
:: جدیدترین موزیکها و نرم افزارها
:: دانلود سورس ویژوال بیسیک
:: امپراطور دانلود و آموزش
:: موبایل و کامپیوتر
:: جدیدترین آهنگهای هفته
:: درباره ی دلفی !
:: برنامه نویس
:: پروژه های رایگان و آموزش ++C
:: ابراهیم آنلاین

 : " ساخت یک Message Handler در دلفی 7 " :
 
با سلام ...
در این پست درباره ی نحوه ی ارسال و دریافت پیغام بین دو برنامه بحث می کنیم ، البته بحث که نیست فقط من سخن در می کنم
خوب ، می خواهیم بین دو برنامه ارتباط برقرار کنیم با ارسال و دریافت پیغام ...
سطح این توضیحات متوسط هست ، یعنی برای کسانی به درد می خوره که در حد متوسط با دلفی آشنایی دارن ، مثل من ! 
کمی در مورد توابع مورد استفاده توضیح داده می شود و بعد به سراغ ایجاد یک برنامه ی نمونه خواهیم رفت ...

ارسال پیغام
:
برای ارسال پیغام از تابع SendMessage یا PostMessage می توانیم استفاده نماییم :

function SendMessage(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT;
function PostMessage(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): BOOL;

این توابع هردو دارای پارامترهای یکسان هستند که در زیر توضیح داده شده اند :
  • hWnd : این پارامتر مقدار هندل پنجره ای که پیغام باید به آن ارسال شود را دریافت میکند
  • Msg : این پارامتر مقدار پیغام را دریافت میکند ( در ادامه لیست مقدارهای این پارامتر را خواهیم دید )
  • wParam و lParam : این دو پارامتر درواقع دو پارامتر اضافی هستند می توان به وسیله ی آنها اطلاعاتی همراه پیغام ارسال کرد ( در ادامه توضیح داده خواهند شد )
این دو تابع کاملا شبیه به هم عمل میکنند ، اما تفاوتی دارند که بهتر اس از زبان Windows SDK بشنویم ! :
--------------------------------------------------------------------
When SendMessage() is used to send a broadcast message (hwnd = 0xFFFF or hwnd = -1), the message is sent to all top-level windows. A message broadcast by PostMessage() is only sent to top-level windows that are visible, enabled, and have no owner.
--------------------------------------------------------------------
تابع دیگه ای که در ارسال پیغام می توانیم  استفادهنماییم ، تابع FindWindow است ، این تابع نام کلاس یک پنجره ( مثلا TForm1 ) یا عنوان یک پنجره یا هر دو را دریافت کرده و Handle پنجره را برگشت می دهد ، در ادامه با این تابع بیشتر آشنا خواهیم شد ...

دریافت پیغام
:
برای دریافت پیغام دو راه را بررسی میکنیم :
  1. استفاده از رویداد OnMessage مربوط به کامپوننت ApplicationEvents ( که البته فقط برای پیغامهای ویندوز کاربرد دارد )
  2. ایجاد یک Message Handler برای یک پیغام خاص
ساخت یک برنامه ی نمونه :
بهتره یک برنامه ی ساده برای تمرین ایجاد کنیم ...
درواقع باید دو تا برنامه درست کنیم ، یکی برای فرستادن پیغام و یکی هم برای دریافت پیغام ...

ابتدا ارسال کننده ی پیغام :
نکته ی مهم : در یونیت Messages از یونیتهای دلفی تعداد زیادی Message مربوط به ویندوز قرار دارد که میتنوانیم آنها را ارسال نماییم ، اما قصد داریم در این برنامه یک پیغام اختصاصی بسازیم و آن را ارسال نماییم ...
پروژه ی جدیدی ایجاد کنید ، و کنترلهای زیر را روی ان قرار دهید :
--------------------------------------------------------------------
--------------------------------------------------------------------
  • یک TEdit با نام ClassEdit برای دریافت نام کلاس
  • یک TEdit با نام CaptionEdit برای دریافت عنوان پنجره
  • یک CheckBox با نام ClNilChBox برای مشخص کردن مقدار nil برای نام کلاس
  • یک TCheckBox با نام CaNilChBox برای مشخص کردن مقدار nil برای عنوان پنجره
  • یک BitBtn ( یا Button ) با نام SendBtn برای ارسال پیغام
مراحل انجام کار :
ابتدا باید یک Message اختصاصی بسازیم ...
Message ها درواقع مقادیری عددی هستند که برای برنامه ارسال می شوند و برنامه با توجه به آن مقادیر عددی که در ویندوز برای وظایف خاصی مشخص شده اند ، عکس العمل نشان می دهد ...
ما هم باید یک مقدار عددی را به پیغام خود نسبت دهیم ، اما چه عددی ، چه عددی قرار دهیم که قبلا در ویندوز برای پیغام خاصی در نظر گرفته نشده باشد ؟!
در یونیت Messages مقداری به نام WM_USER قرار دارد ، این مقدار که به یک عدد اشاره می کند اولین عددی است که می توانیم برای پیغام خود در نظر بگیریم ، منظور از اولین عدد این است که می توان اعدادی مثل " WM_USER + 1 " و ... را نیز برای مقدار عددی پیغام در نظر گرفت ...
خوب ، تعریف یک Message هم کار بسیار ساده ایست ، به سادگی تعریف یک ثابت !
در زیر یک پیغام جدید با عنوان MY_MESSAGE تعریف شده است :
MY_MESSAGE = WM_USER + 1

برای ادامه ی کار پروژه ، این پیغام را در یونیت اصلی تعریف کنید :
var
 SenderFrm: TSenderFrm; ( نام و نام کلاس پنجره ی اصلی برنامه )

const
 MY_MESSAGE = WM_USER + 1;

خوب ، حال کافی است که پنجره ی مورد نظر را پیدا کرده و به پیغام خود را به آن ارسال نماییم ...
ابتدا باید با توجه به اطلاعات وارد شده در Edit ها به عنوان نام کلاس و عنوان پنجره ، با استفاده از تابع FindWindow هندل پنجره ی مورد نظر را بدست آوریم ...
در این مرحله یک نکته ی مهم را باید رعایت کنیم ، برای هر کدام از پارامترهای تابع FindWindow یعنی ClassName و WindowName ( عنوان پنجره ) سه حالت وجود دارد ، یا یک مقدار وارد می شود ( مثلا MyClass ) یا اینکه خالی خواهد بود و یا مقدار nil خواهد داشت ، مقدار nil برای این پارامترها به تابع FindWindow اعلام می کند که پارامتر عنوان پنجره را مد نظر قرار ندهد ، توجه کنید که مقدار nil با قرار دادن مقدار خالی ( ' ' ) در پارامتر های این تابع تفاوت دارد ، اگر مقدار رشته ی خالی قرار دهیم ، تابع به دنبال پنجره های بدون عنوان ( عنوان خالی ) می گردد ولی اگر مقدار nil در قسمت عنوان پنجره قرار دهیم ، تابع بدون توجه به عنوان پنجره ، مقدار نام کلاس وارد شده را برای پنجره ی مورد نظر چک می کند ...
ما در برنامه ی خود در زیر هر Edit یک CheckBox هم گذاشته ایم که در صورت تیک زدن آن مقدار Nil در قسمت مورد نظر قرار گیرد ...
پس از پیدا کردن هندل پنجره  می توانیم به راحتی به آن پیغام بفرستیم ...
در نهایت کد مربوط به رویداد OnClick دکمه ی ارسال به صورت زیر خواهد بود :

procedure TSenderFrm.SendBtnClick(Sender: TObject);
var
 H : THandle;
begin
 if CaNilChBox.Checked and ClNilChBox.Checked then
  begin
   MessageBox(Handle, 'Both two Parameters are sets to Nil !', '', MB_OK+MB_ICONEXCLAMATION);
   Exit;
  end
 else
  begin
   if CaNilChBox.Checked or ClNilChBox.Checked then
    begin
     if CaNilChBox.Checked then
      H := FindWindow(Pchar(ClassEdit.Text), nil);
     if ClNilChBox.Checked then
      H := FindWindow(nil, Pchar(CaptionEdit.Text));
    end
   else
    H := FindWindow(Pchar(ClassEdit.Text), Pchar(CaptionEdit.Text));
  end;
 SendMessage(H, MY_MESSAGE, 0, 0);
end;
در کد بالا ابتدا چک می شود که آیا هر دو چک باکس تیک خورده اند یا نه که در صورت تیک خوردن دو چک باکس ، هر دو پارامتر تابع FindWindow مقدار nil می گیرند ، که در این صورت جستجو برای پیدا کردن هندل پنجره ، حرکتی بی ثمر خواهد بود ... ! ، پس بهتر است پیغامی بدین منظور نمایش داده شود ، در ادامه برای هر دو حالت که نام کلاس یا عنوان پنجره Nil باشد هندل بدست می آید و اگر هیچ کدام از چک باکس ها تیک خورده نبودند ، برای هر دو پارامتر تابع مقدار وارد شده در Edit ها را قرا می دهیم ...
به عنوان یک نکته توجه کنید که مقادیر پارامترهای تابع FindWindow باید از نوع Char باشد ، پس با تابع Pchar مقدار Edit ها را به Char تبدیل میکنیم ...
در بالا ما از SendMessage استفاده کردیم ، ولی می توانیم از PostMessage هم استفاده نماییم ( تفاوت این دو تابع در بالا ذکر شد )

خوب ، حال به سراغ برنامه ی دریافت کننده ی پیغام می رویم ...
پروژه ی جدیدی ایجاد کنید و کنترلهای زیر را بر روی آن قرار دهید :
--------------------------------------------------------------------
--------------------------------------------------------------------
  • یک TMemo با نام MsgList برای نمایش مشخصات پیغام دریافت شده
  • یک کامپوننت TApplicationEvents با نام AppEvents برای تشخیص پیغام دریافت شده
برای دریافت پیغام دو راه داریم ...
راه اول ، ساخت یک Message Handler :
یک Message Handler درواقع یک Procedure است که در با رسیدن یک پیغام خاص اجرا می شود ، یک Message Handler به صورت زیر تعریف می شود :
procedure OnMyMessage(var Msg : TMessage); message MY_MESSAGE;
در اینجا MY_MESSAGE همان پیغام خاص است که برای آن Message Handler می سازیم ...
این Procedure را در قسمت Type تعریف نمایید ، توجه کنید که در اینجا چون MY_MESSAGE در این Procedure به عنوان یک ثابت تعریف شده ، پس کامپایلر دلفی قبل از رسیدن به این خط از کد باید مقدار MY_MESSAGE را دریافت کند تا با رسیدن به Procedure ما مقدار MY_MESSAGE را اختصاص دهد !
یعنی باید به صورت زیر این ثابت را تعریف نمایید ( باید قبل از تعریف Procedure باشد ) :

 uses
    ...

const
 MY_MESSAGE = WM_USER + 1;

type
  ...
    procedure OnMyMessage(var Msg : TMessage); message MY_MESSAGE;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  RecieverFrm: TRecieverFrm;

implementation
  ...

حال نوبت نوشتن کد برای این رویداد است ، می خواهیم در این رویداد در داخل Memo ای که روی فرم گذاشته ایم مقداری را نمایش دهیم تا رسیدن پیغام اطلاع داده شود ، پس به صورت زیر عمل می کنیم :

procedure TRecieverFrm.OnMessage(var Msg : TMessage);
begin
 MsgList.Lines.Add('M H : New Message Arrived ! , Time : '+TimeToStr(Now));
end;
در کد بالا با رسیدن این پیغام ، در MsgList یک خط اضافه شده و رسیدن پیغام را همراه با زمان رسیدن آن نمایش می دهد ...
خوب ، ساخت Message Handler هم به پایان رسید ...

راه دوم برای دریافت پیغام ( فقط پیغامهای ویندوز یا پیغامهای رجیستر شده ) ، استفاده از رویداد OnMessage کامپوننت AppEvents است ...
این رویداد زمانی فراخوانی می شود که پیغامی به برنامه ارسال شود :

procedure TRecieverFrm.AppEventsMessage(var Msg: tagMSG; var Handled: Boolean);
begin

end;
نکته ی مهم : این روش تنها برای دریافت پیغامهای استاندارد ویندوز و پیغامهایی که در ویندوز به عنوان یک Message معرفی شده اند کاربرد دارد و در اینجا با دریافت پیغام MY_MESSAGE که یک مقدار عددی ساده است اجرا نخواهد شد ...
این رویداد دو متغیر در خود دارد به نامهای Msg و Handled ...
متغیر Msg مشخصات پیغام را در خود نگهداری می کند ، اما وظیفه ی Handled نیاز به کمی توضیح دارد ...
اگر Handled را در این رویداد True کنیم به برنامه می گوییم که کار ما با این پیغام به پایان رسیده است و پیغام Handle شده و دیگر عکس العملی از طرف برنامه انجام نخواهد شد ...
به عنوان مثال یکی از پیغامهای ویندوز پیغام WM_CLOSE است که وظیفه ی بستن برنامه ای که به آن ارسال می شود را دارد ، اگر این پیغام به برنامه ارسال شود رویداد OnMessage کامپوننت AppEvents اجرا خواهد شد ، حال اگر در این رویداد ما چک کنیم که اگر پیغام رسیده WM_CLOSE بود ، آن را Handle کنیم ، دیگر برنامه به پیغام رسیده عکس العمل نشان نخواهد داد و بسته نخواهد شد ، توجه کنید که در حالت عادی اگر پیغام Handle نشود برنامه بسته می شود چون وظیفه ی پیغام WM_CLOSE بستن پنجره ی مقصد پیغام است ...
برای رویداد OnMessage کامپوننت AppEvents به صورت زیر کد نویسی می کنیم :

procedure TRecieverFrm.AppEventsMessage(var Msg: tagMSG; var Handled: Boolean);
begin
 if Msg.message =  WM_MESSAGE then
  begin
   MsgList.Lines.Add('(( Message Name ))  Message Arrived ! , Time : '+TimeToStr(Now));
   Handled := True;
  end;
end;
در مثال بالا منظور از WM_MESSAGE یک پیغام ویندوزی است و خود WM_MESSAGE مقدار قابل قبولی نیست ...
...........................
در مورد wParam و lParam ان شاالله در یک پست جدا و با بررسی یک سورس مربوط به ارسال اطلاعات بین دو برنامه توضیح داده خواهد شد ...

درضمن ، قبلا آموزشی در مورد نحوه ی هندل کردن پیغامهای ارسال شده به برنامه توسط کامپوننت TApplicationEvents در وبلاگ گذاشته شد که خوندن اون هم می تونه در ادامه ی این آموزش مفید باشه ...

امیدوارم مفید بوده باشه ...

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


عاجزانه خواستار رعایت کپی رایت هستیم ... ، خوب بابا بی خیال ... ، رعایت نکنید ...

امیدوارم مفید بوده باشه ...

موفق باشید ...  

 

 :: لینك ثابت نویسنده : محمود مهری نظرات Comment

مطالب اخیر

معرفی کانال و گروه های تلگرام
استفاده از Component Template ها در دلفی
مقاله : نحوه ی استفاده از پنل پیامک در نرم افزار
E-Book :: راه اندازی موتورهای DC و پله ای با استفاده از میکرو کنترلر AVR
آشنایی با عملگرهای بیتی ( Bitwise Operators )
تست دیود و ترانزیستور با مولتی متر
دلفی :: ارسال آرایه به حافظه ی Clipboard
یک سایت فوق العاده برای علاقه مندان به علم فیزیک
مداری برای نمایش عبور جریان برق از بدن !!
سال نو مبارک ...
آدرس وبلاگ !
ساخت یک LED فلاشر با میکروکنترلر AVR ATMega16A
آشنایی با کاربرد " رله " ( Relay ) در مدار
کار با ماتریسها در Matlab
SQL :: آشنایی با دستور شرطی WHERE


صفحات وبلاگ :