delphi4arab منتديات دلفي للعرب

نسخة كاملة : خطوة خطوة لإنشاء TNA (إيقونة بجنب الساعة) مع إضافة قائمة PopupMenu وتلميح منطادي
أنت حالياً تتصفح نسخة خفيفة من المنتدى . مشاهدة نسخة كاملة مع جميع الأشكال الجمالية .
الصفحات : 1 2 3
بسم الله الرحمن الرحيم
بارك الله فيك عمل في منتهى الروعة كنت ابحث عن هذا منذ بعيد
السلام عليكم
يمكن تعويض الأمرين:
PHP كود :
ShowWindow(Application.Handle, SW_HIDE);
      
ShowWindow(Handle, SW_HIDE); 

مباشرة بالأمر:
PHP كود :
Visible := False; 

وكذلك فيما يخص لـ:
PHP كود :
ShowWindow(Application.Handle, SW_SHOW);
      
ShowWindow(Handle, SW_SHOW); 

تعوض بـ:
PHP كود :
Visible := True; 
والنتيجة هي نفسها.
هناك طريقة أخرى في أنشاء أيقونة بجانب الساعة بأستخدام المكتبة [COLOR="Red"]CoolTrayIcon.pas
وهو موضح في السورس كود الموجود في المرفقات[/COLOR]
شكرا كثيرا أخي ThePrince على المشاركة.
في الحقيقة هناك مكونات (أو مكتبات pas) كثيرة مجانية تقدم هذه الخدمة وبعضها يختلف عن بعض الآخر.
أما هذه التي قدمتها فهي حقيقة مميزة باحتوائها على المكون TBalloonHintIcon والعديد من الخصائص.
لكننا نريد أن نتعلم كيف ننشئ أيقونة بجنب الساعة برمجيا دون الاستعانة بمكونات أو مكتبات خارجية، وقد نبهنا لذلك في بداية الشرح.
ذلك لكي يتحكم المبرمج في استخدام هذا المكون بالشكل الذي يناسبه، إضافة إلى أن استعمال مكتبات خارجية يثقل البرنامج ونحن نريد أن نجعله أخف ما يمكن.
شرح تركيب المكون BalloonHint واستعمال مكون PopupMenu غدا إن شاء الله.
عموما شكرا على المكتبة كنت سأضع واحدة في ختام الموضوع.
kachwahed كتب :نحن نستعمل Delphi 7 وليس فيه مكون BalloonTip الذي يوجد في Delphi 2009

يوجد في نسخة Delphi 10 lite هذا المكون ايضا ً ( تستطيع تحميل البرنامج لأن حجمه 59 ميقا فقط ) وأنه افضل من الدلفي 7 في نضري
بسم الله الرحمن الرحيم
السلام عليكم ورحمة الله

اليوم إن شاء الله نواصل ما بدأنا به، نبدأ بإنشاء مكون قائمة منسدلة (TPopupMenu) ونحملها على الأيقونة TNA، ثم نكتب الإجراءات اللازمة لإنشاء التلميح المنطادي TBalloonHint.

الخطوة الأولى إضافة مكون من النوع TPopupMenu:
إنطلاقا من المثال السابق: نضيف ما يلي:

من قائمة المكونات Standard نضع مكون من النوع TPopupMenu على النموذج Form1، وننشئ فيه ثلاث عناصر: عرض، إخفاء، إنهاء.
سنأتي إليه بعد قليل.

بعد أن استبدلنا الأمرين:
PHP كود :
begin
ShowWindow
(Application.Handle, SW_HIDE);
ShowWindow(Handle, SW_HIDE);
end; 
مباشرة بالأمر: Visible := False
و:
PHP كود :
begin
ShowWindow
(Application.Handle, SW_SHOW);
ShowWindow(Handle, SW_SHOW);
end; 
بالأمر: Visible := True
يصبح الإجراء TForm1.WMTaskMsg، بهذا الشكل:
PHP كود :
procedure TForm1.WMTaskMsg(var Msg: TMessage);
begin
  
if Msg.LParam = WM_LBUTTONDOWN then
      Visible 
:= False;

  if 
Msg.LParam = WM_RBUTTONDOWN then
      Visible 
:= True;
end; 
الآن نغير في الإجراء بحيث إذا نقرنا على الأيقونة يظهر البرنامج وإذا نقرنا عليها مرة أخرى يختفي، ونستعمل هنا case...of:
(للتنبيه فقط: case of تستعمل في حالة تعدد الشروط لنفس المتغير، فمثلا عوض أن نقول "إذا كان متغير x يساوي 1 إذا إفعل a، وإذا كان المتغير x يساوي 2 إذا إفعل b...". نقول مباشرة: "من أجل x يساوي 1: إفعل a، 2: إفعل b...).
PHP كود :
procedure TForm1.WMTaskMsg(var Msg: TMessage);
begin
  
case Msg.LParam of
  WM_LBUTTONDOWN
: Visible := not Visible;
  
WM_RBUTTONDOWN:;
  
end;
end; 
يمكن تشغيل البرنامج على هذا الشكل وملاحظة النتيجة.

الآن نربط مكون TPopupMenu مع حدث النقر بالزر الأيمن WM_RBUTTONDOWN، ونستعمل لذلك متغير من النوع TPoint (أي إحداثيات (x,y)على سطح مكتب الويندوز).
نعرف هذا المتغير في هذا الإجراء (مباشرة قبل begin) كما يلي: var Pnt: TPoint
ثم نعطي هذا المتغير قيمة إحداثيي مؤشر الماوس باستعمال GetCursorPos.
وأخيرا نعرض القائمة المنسدلة PopupMenu1 في حدث النقر بالزر الأيمن باستعمال خاصية Popup(x,y)، فيصبح الإجراء كما يلي:

PHP كود :
procedure TForm1.WMTaskMsg(var Msg: TMessage);
  var 
Pnt: TPoint;//نعرف متغير من النوع إحداثيات
begin
//نجعل هذا المتغير يأخذ قيمة إحداثيات مؤشر الماوس
  
GetCursorPos(Pnt);

  case 
Msg.LParam of
    WM_LBUTTONDOWN
: Visible := not Visible;
//نعرض القائمة المنسدلة في موضع المؤشر عندما ينقر بالزر الأيمن
    
WM_RBUTTONDOWN: PopupMenu1.Popup(Pnt.X, Pnt.Y);
  
end;

end; 
الآن عند النقر على الأيقونة بالزر الأيمن تظهر القائمة المنسدلة PopupMenu1 بالعناصر التي شكلناها سابقا (عرض، إخفاء، إنهاء).
والآن سنضيف أحداث هذه العناصر (كل عنصر كلمة واحدة فقط !!!؟) كما التالي:

PHP كود :
procedure TForm1.N1Click(Sender: TObject);
begin
//للعرض:
  
Show
end
;
//للإخفاء:
procedure TForm1.N2Click(Sender: TObject);
begin
  Hide
end
;
//للانهاء:
procedure TForm1.N4Click(Sender: TObject);
begin
  Close
end
; 
وانتهينا...

الخطوة الثانية: إضافة التمليح المنطادي BalloonHint
(هذه الخطوة تتطلب شيئا من التركيز)

أولا: لا بد من التنبيه كما أشرنا أن المكون BalloonHint هو إحدى المكونات الحديثة لويندوز xp (وكذلك ويندوز 2000 NT، وويندوز Me) أي أنها لا تعمل في نظام ويندوز 98، وكذلك لا بد من توفر Internet Explorer بإصدار 5.0 على الأقل.

ثانيا: لن نستعمل النوع TNotifyIconData لأنه لا يحتوي على مكون BallonHint بل سننشئ بأنفسنا نوع جديد سنسميه: TNewNotifyIconData ثم نضيف إليه التمليح المنطادي.

بدايةً نعرف في الحقل Interface بعد تعريف الأنواع type، التسجيل TTimeoutVersion الذي يخزن مدة ظهور التمليح (سنشرح ذلك لاحقا)، مباشرة بعده نعرف النوع الجديد TNewNotifyIconData له نفس معالم (البارامترات) النوع السابق TNotifyIconData، إضافة إلى ستة أخرى جديدة (وهي التي تتطلب الإصدار 5.0 لـ IE) هي كالآتي:
كود :
dwState: DWORD; dwStateMask: DWORD; szInfo: array [0..255] of Char; TTimeoutVersion: TTimeoutVersion; szInfoTitle: array [0..63] of Char; dwInfoFlags: DWORD;
نشرح أهم الخصائص:
szInfo: متغير حرفي لتخزين رسالة لا تفوق 256 حرف للنص الذي سيظهر في التمليح.
TTimeoutVersion: هذا متغير من نوع تسجيل (record) الذي عرفناه من قبل ويحفظ إصدار التلميح، ومدة ظهور التمليح حسب الويندوز xp لا تقل عن 10 ثوان ولا تزيد عن 60 ثانية.
szInfoTitle: عنوان التمليح وحجمه 64 حرف.
dwInfoFlags: رمز التمليح (الأيقونة المستعملة (أو الشكل) في التلميح)، ويتخذ عدة أنواع (مثل أشكال MessageDlg).
في النهاية يظهر تعريف النوع كما يلي:
كود :
interface ... type TForm1 = class(TForm) ... end; TTimeoutVersion = record case Integer of 0: (uTimeout: UINT);//إصدارات أقدم من ويندوز 2000 1: (uVersion: UINT);//إصدار ويندوز 2000 فما فوق end; TNewNotifyIconData = record cbSize: DWORD; Wnd: HWND; uID: UINT; uFlags: UINT; uCallbackMessage: UINT; hIcon: HICON; szTip: array [0..127] of Char; dwState: DWORD; dwStateMask: DWORD; szInfo: array [0..255] of Char; TTimeoutVersion: TTimeoutVersion; szInfoTitle: array [0..63] of Char; dwInfoFlags: DWORD; end; var //ولا ننسى أن نعرف أيقونتنا من هذا النوع الجديد (طبعا نحذف تعريف النوع القديم): Form1: TForm1; MyTNA: TNewNotifyIconData;


والآن لم يبق لنا سوى كتابة الإجراء الذي يعرض التلميح المنطادي، نبدأ بتعريف الإجراء في الحقل
PHP كود :
Private:

    
procedure ShowBalloonTips(TipInfo, TipTitle: string); 
ثم نضغط على Ctrl+Alt+C ونكتب أوامر الإجراء على النحو التالي:
(يتلقى هذا الإجراء قيمتين نصيتين تمثلان عنوان التلميح ومضمونه)
PHP كود :
procedure TForm1.ShowBalloonTips(TipInfo, TipTitle: string);
begin
  with MyTNA 
do begin//إنشاء أيقونة 
    
cbSize := SizeOf(MyTNA);//حجز حجم الأيقونة
    
uFlags := $10;//تعني كل الأحداث NIF_MESSAGE + NIF_ICON + NIF_TIP 
    
StrPLCopy(szInfo, TipInfo, SizeOf(szInfo) - 1);//كتابة نص التلميح
    
MyTNA.TTimeoutVersion.uTimeout := 1000;//المدة أكتب أي قيمة فلن يؤثر ذلك، لأن الويندوز من يتحكم بوقتها
    
strPLCopy(szInfoTitle, TipTitle, SizeOf(szInfoTitle) - 1);//كتابة عنوان التلميح
    
dwInfoFlags := $00000001; //الشكل الذي سيأخذه التلميح شكل إعلام
   
end;
  
Shell_NotifyIcon(NIM_MODIFY, @MyTNA);//دالة تغيير الإيقونة إلى أيقونة ذات تلميح منطادي
end; 

ملاحظات:
1- كتبنا هنا إجراء يقوم يتلقى نص رسالة التلميح وعنونها المكتوب فيها، ويعيد تغيير الأيقونة إلى أيقونة تحمل تليمح منطادي BalloonHint.
2- فيما يخص المتغير dwInfoFlags يمكنه أن يأخذ عدة قيم (مثل قيم mtWarning, mtError, mtInformation للرسائل MessageDlg) يمكن تخزينها في ثوابت معلن عنها مسبقا بحيث:
كود :
NIIF_INFO = $00000001; //تلميح إعلام NIIF_WARNING = $00000002;//تلميح إنذار NIIF_ERROR = $00000003;//تلميح خطأ
3- أما TTimeoutVersion يمكن إهماله تماما لأن قيمته يحددها الويندوز تلقائيا.

الخطوة الثالثة: نضع زر TButton ونكتب في حدث النقر عليه:
PHP كود :
procedure TForm1.BtnShowHintClick(Sender: TObject);
begin
  ShowBalloonTips
('محتوى التلميح', عنوان التلميح');
end; 
الخطوة الرابعة: التحكم في الأحداث التي يتلقاها التلميح
نريد أن نجعل البرنامج يعرض رسالة (ShowMessage) عند عرض التلميح، ورسالة أخرى عند النقر عليه ورسالة ثالثة عند انتهاء مدة التلميح.
نضيف إلى الإجراء الذي يتلقى الأحداث (الذي عرفناه سابقا) الأحداث التالية: ظهور التلميح، اختفاء التلميح، النقر على التلميح، كما يلي:
PHP كود :
procedure TForm1.WMTaskMsg(var Msg: TMessage);
  var 
Pnt: TPoint;
begin
  GetCursorPos
(Pnt);

  case 
Msg.LParam of
    WM_LBUTTONDOWN
: Visible := not Visible;
    
WM_RBUTTONDOWN: PopupMenu1.Popup(Pnt.X, Pnt.Y);

    
WM_USER + 2: ShowMessage('ظهور التلميح');//تحدث عندما يظهر التلميح
    
WM_USER + 3: ShowMessage('اختفاء التلميح');//تحدث أيضا عند اختفاء الأيقونة لأن التلميح يختفي معها
    
WM_USER + 4: ShowMessage('انتهاء مدة التلميح');//تحدث عندما يرسل الويندوز حدث انتهاء مدة التلميح
    
WM_USER + 5: ShowMessage('النقر على التلميح');//تحدث عندما ينقر المستخدم على التلميح
  
end;

end; 
ملاحظات:
1- WM_USER + i هي قيم معرفة لدى الدلفي في الوحدة Messages.pas.
2- عند النقر على الزر الذي يغلق التلميح (في أعلى يمين التلميح) يرسل الويندوز حدث انتهاء مدة التلميح WM_USER + 4 تذكر ذلك.
3- يمكن تخزين القيم WM_USER + i في ثوابت (باستعمال const) باستعمال أسماء مناسبة تدل عليها، مثل:
PHP كود :
const
BALLOONSHOW = WM_USER + 2;
BALLOONHIDE = WM_USER + 3;
BALLOONTIMEOUT = WM_USER + 4;
BALLOONUSERCLICK = WM_USER + 5; 
جرب الآن تشغيل البرنامج وانظر للنتيجة.
إلى هنا نكون قد أنشأنا برنامج يعرض أيقونة بقائمة منسدلة يمكنها تلقي أحداث المستعمل، وتعرض تلميح منطادي يتلقى هو الآخر أحداث المستعمل ويرد عليها.
وللحديث بقية سنأتي عليها إن شاء الله...
نواصل...
خطوات إضافية: البرنامج مكتمل ويمكن إضافة خيارات أخرى، مثل جعل البرنامج يظهر في أحد المنطقتين دون الأخرى، عرض خيار للمستخدم فيما إذا كان يرغب بتصغير البرنامج عند غلقه...
الخطوة الأولى: يمكن أن نجعل البرنامج يظهر في أحد المكانين، إما في علبة شريط المهام أو في شريط المهام نفسه، ولأجل ذلك نقوم بما يلي:
أولا: من الأحسن أن نجعل إجراء منفرد يعرض الأيقونة، ثم نضيفه إلى FormCreate أو نترك هذا الأخير فارغا:
PHP كود :
private
    
procedure ShowMyTNA; 
نستعمل Ctrl+Alt+C ونكتب:
PHP كود :
procedure TForm1.ShowMyTNA;
begin
  with MyTNA 
do
    
begin
      cbSize 
:= SizeOf(TNotifyIconData);
      
MyTNA.uID := 0;
      
uFlags := NIF_MESSAGE + NIF_ICON + NIF_TIP;
      
Wnd := Handle;//
      
uCallbackMessage := WM_APP +1;
      
hIcon := Application.Icon.Handle;
      
szTip := 'Delphi 4 arab';
    
end;
  
Shell_NotifyIcon(NIM_ADD, @MyTNA);
end; 
* يمكن إضافة زر يعرض الأيقونة إلى جنب ساعة الويندوز، ويخفيها من شريط المهام، ونجعله غير مفعل إذا كانت الأيقونة تظهر، ويفعل هو الآخر زر عرض التلميح، فنضع زر ونكتب في حدث النقر عليه:
PHP كود :
procedure TForm1.BtnShowTNAClick(Sender: TObject);
begin
  ShowMyTNA
;//عرض الأيقونة
  
BtnShowTNA.Enabled := False;//تعطيل زر عرض الأيقونة
  
BtnShowHint.Enabled := True;//تفعيل زر عرض الأيقونة
  
ShowWindow(Application.Handle, SW_HIDE) //إخفاء البرنامج من شريط  المهام
end; 

ويلزم لأجل هذا التغيير، تغيير زر عرض النموذج الذي وضعناه في القائمة المنسدلة، بالشكل التالي:
PHP كود :
procedure TForm1.N1Click(Sender: TObject);
begin
  Show
;//عرض النموذج
  
FormDestroy(Sender);//إخفاء الأيقونة، وذلك باستدعاء الأوامر التي تحدث عند إعدام النموذج
  
BtnShowTNA.Enabled := True;//تفعيل زر عرض الأيقونة
  
BtnShowHint.Enabled := False;//تعطيل زر عرض التلميح مرة أخرى
  
ShowWindow(Application.Handle, SW_SHOW)//عرض اسم البرنامج في شريط المهام
end; 
الخطوة الثانية: إضافة مكون من النوع TCheckBox ثم نعدل في الإجراء الذي يتلقى الأحداث بإضافة حدث غلق النموذج ونغير فيه بما يلي:
PHP كود :
procedure TForm1.WMSyscommand(var msg: TWmSysCommand);
begin
  
if msg.CmdType and $FFF0 = SC_MINIMIZE then
    begin
      Hide
;
      
BtnShowTNA.Click;
    
end else
    
begin
      
if msg.CmdType and $FFF0 = SC_CLOSE then// إذا تلقى حدث غلق النموذج
        
if ChkBxCloseOnExit.Checked then//التحقق من أن الخيار "إخفاء عند الغلق" مفعل 
          
begin
            ShowMyTNA
;//عرض الأيقونة
            
Hide;//إخفاء النموذج
          
end else Close//وإن لم يكن مفعل ...فيقوم الإجراء بغلق النموذج
        
else inherited;//وإن لم يتلقى الإجراء حدث تصغير ولا حدث الغلق...فسيرث الأحداث الأخرى 
    
end
end
; 
آخر إضافة: يمكن إضافة تلميح منطادي عند محاولة غلق النموذج (في حين خيار "تصغير عند الغلق" مفعل) ينبه المستعمل على أن البرنامج لم يغلق، ولا يزال يشتغل (يضاف هذا الأمر في الإجراء الذي يتقلى أحداث التلميح):
PHP كود :
...
      if 
msg.CmdType and $FFF0 = SC_CLOSE then
        
if ChkBxCloseOnExit.Checked then
          begin
            ShowMyTNA
;
            
ShowBalloonTips('لا يزال البرنامج مفتوحا', 'تنبيه');
            
Hide;
... 
ملاحظات:
- inherited ترث الأحداث الأصلية، وفي حالتنا هذه غيرنا في حدث التصغير وفي حدث الغلق وبقي حدث تكبير النموذج وحدث تغيير حجم النموذج.
- أحيانا يفقد البرنامج التركيز (Focus) ولا يتلقى حينها أوامر لوحة المفاتيح (يحدث ذلك أحيانا عند تكبير النموذج) لاسترجاع التركير على البرنامج نستعمل الأمر BringToFront وأحيانا لا تنفعل فنستخدم:
SetForegroundWindow(Handle);

أتمنى أن يكون الموضوع نال إعجابكم وأشبع حاجتكم
وكما ذكرنا سابقا أنه توجد مكونات كثيرة تقوم بهذا العمل (كما أشار إلى ذلك بعض الأعضاء)، وأن الإصدارات الحديثة للدلفي تأتي معها مثل هذه المكونات، لكننا كما بينا أننا نريد أن نقوم بذلك بأنفسنا برمجيا لعدة أسباب منها: أن نتعلم كيفية التعامل دوال Api، والتحكم فيها وعرضها بالشكل الذي نريد، جعل البرنامج أكثر خفة بإضافة العناصر التي نحتاجها فقط (وهذا مهم بالنسبة لأي مبرمج محترف لأنه يعتبر 10 Kb إضافية لوزن البرنامج شيء ثقيل)...

المثال النهائي مع الكود سورس في المرفقات.

هذا والله سبحانه وتعالى أعلم، وصلى الله على سيدنا محمد.
والسلام عليكم ورحمة الله.
مشكووور أخي على المجهود المثمر و الجميل .... بارك الله فيك
جزاك الله ألف خير ... درسك جميل وبصراحة أستفدت منة أشياء كثيرة بارك الله فيك أخي.
[color="red"]السلام عليكم ورحمة الله وبركاته
--------------------------------
جزاكم الله خيرا أخوتي الكرام على هذه المعلومات

شكرا بكل معنى الكلمة[/color]
الصفحات : 1 2 3