28-09-2012, 02:36 PM
السلام عليكم و رحمة الله وبركاته
سنتكلم في هذا الموضوع حول دعم ال Menu Icon ل VCL Style .
ال Menu Icon هي تلك القائمة المنبثقة التي تظهر بمجرد النقر على الأيقونة في أعلى الفورم
![[صورة: iconmenu0.png]](http://img196.imageshack.us/img196/618/iconmenu0.png)
لكن للأسف فكما تلاحظ فهو لا يدعم مكتبة ال VCL Style و لا يتوافق معها ,وهذا شيئ يؤثر على UI , سنرى في هذا الدرس الطريقة الملائمة لعمل التوافقية
قد تبدوا الفكرة من الوهلة الأولى صعبة لكنها جد سهلة و لم تأخذ من وقتي سوى نصف ساعة على انجازها
نبدأ على بركة الله
أولا عليك أن تفهم آلية العمل أو بالأحرى كيف يظهر ال Menu Icon ؟
يظهر بطريقتين : الأولى التوجه الى الأيقونة و الضغط بالزر الأيسر للماوس على الأيقونة
أما الثانية عن طريق الضغط بالزر الأيمن على ال Caption Bar
أي كلا الطريقتين تعتمد على النقر على ال Caption Bar
أضف PopupActionBar الى الفورم و أضف له 7 Items
![[صورة: items7o.png]](http://img195.imageshack.us/img195/2851/items7o.png)
نقوم باضافة هذه الاجراءات
و لا تنسى ارفاق المكتبة Vcl.Themes الى المشروع
الاجراء TWMNCLBUTTONDOWN ينفذ عند النقر بالزر الأيسر على ال Non Client Area
الاجراء TWMNCRBUTTONDOWN ينفذ عند النقر بالزر الأيمن على ال Non Client Area
الفكرة تعتمد على معرفة مكان الماوس , اذا المستخدم ضغط على ال Caption Bar يتم التحقق ما اذا كان موقع الماوس على الأيقونة الخاصة بالفورم , اذا تحقق الشرط يتم اظهار ال Menu
أما اذا لم يتحقق فيتم الخروج من الاجراء و اكمال السير العادي للبرنامج .
الآن شغل البرنامج و جرب , أكيد لقد تم تغيير الستايل و أصبح متوافق مع ال Vcl Style , لكن ال Menu يحتةي على أسماء بعنواين Items 1..Items7
تستطيع تغيير هذه الاسماء , كما تستطيع أن تستخدم الاعدادت الخاصة بالجهاز
تابع معي
أضف هذه الاجراءات الى القسم Private
الاجراء EnumMenus
يقوم هذا الاجراء بأخذ أسماء ال Menu Item الافتراضية الخاصة بالجهاز و استخدامها
الحدث ItemClick ينفذ عند الضغط على ال Menu
النتيجة
![[صورة: iconmenu1.png]](http://img443.imageshack.us/img443/5885/iconmenu1.png)
كما يمكنك أن تتجاهل الحدث EnumMenus و تصمم ال Menu الخاص بك
سنتكلم في هذا الموضوع حول دعم ال Menu Icon ل VCL Style .
ال Menu Icon هي تلك القائمة المنبثقة التي تظهر بمجرد النقر على الأيقونة في أعلى الفورم
لكن للأسف فكما تلاحظ فهو لا يدعم مكتبة ال VCL Style و لا يتوافق معها ,وهذا شيئ يؤثر على UI , سنرى في هذا الدرس الطريقة الملائمة لعمل التوافقية
قد تبدوا الفكرة من الوهلة الأولى صعبة لكنها جد سهلة و لم تأخذ من وقتي سوى نصف ساعة على انجازها
نبدأ على بركة الله
أولا عليك أن تفهم آلية العمل أو بالأحرى كيف يظهر ال Menu Icon ؟
يظهر بطريقتين : الأولى التوجه الى الأيقونة و الضغط بالزر الأيسر للماوس على الأيقونة
أما الثانية عن طريق الضغط بالزر الأيمن على ال Caption Bar
أي كلا الطريقتين تعتمد على النقر على ال Caption Bar
أضف PopupActionBar الى الفورم و أضف له 7 Items
![[صورة: items7o.png]](http://img195.imageshack.us/img195/2851/items7o.png)
نقوم باضافة هذه الاجراءات
PHP كود :
procedure TWMNCRBUTTONDOWN(var Msg: TWMNCRBUTTONDOWN ); message WM_NCRBUTTONDOWN ;
procedure TWMNCLBUTTONDOWN(var Msg: TWMNCLBUTTONDOWN ); message WM_NCLBUTTONDOWN ;
PHP كود :
uses Vcl.Themes;
الاجراء TWMNCRBUTTONDOWN ينفذ عند النقر بالزر الأيمن على ال Non Client Area
PHP كود :
procedure TMain.TWMNCLBUTTONDOWN(var Msg: TWMNCLBUTTONDOWN );
var rPos:Tpoint;
WinRect:Trect;
ThemeDetails :TThemedElementDetails ;
sSizeFrameRight,sSizeCaptionBar:TSize;
sStyle:TStyleManager;
IconRect:TRECt;
begin
sStyle:=TStyleManager.Create ;
// Check if Style is not Windows system style
if sStyle.ActiveStyle.IsSystemStyle then begin
sStyle.Free ;
inherited;
exit;
end;
GetWindowRect(handle,WinRect);
WinApi.Windows.GetCursorPos(rPos); // Find cursor position on screen
ThemeDetails:=sStyle.ActiveStyle.GetElementDetails
( vcl.Themes.TThemedWindow.twFrameRightActive );// Get some information about window frame .
sStyle.ActiveStyle.GetElementSize
(0,ThemeDetails,TElementSize.esActual ,sSizeFrameRight);//Get Size of Window Frame
ThemeDetails:=sStyle.ActiveStyle.GetElementDetails ( vcl.Themes.TThemedWindow.twCaptionActive );
sStyle.ActiveStyle.GetElementSize(0,ThemeDetails,TElementSize.esActual ,sSizeCaptionBar);
IconRect := Rect(0, 0, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON)); // Get Icon Rectangle on window
sStyle.Free ;
// Check if cursor position
if (rPos.X-WinRect.Location.X )< sSizeFrameRight.Width then begin
inherited;
exit;
end;
// Check is cursor is on window icon
if (rPos.X-WinRect.Location.X )< IconRect.Width*2 then
self.PopupActionBar1.Popup(left+sSizeFrameRight.Width,top+sSizeCaptionBar.Height )else
inherited;
Msg.Result :=1;
end;
أما اذا لم يتحقق فيتم الخروج من الاجراء و اكمال السير العادي للبرنامج .
PHP كود :
procedure TMain.TWMNCRBUTTONDOWN(var Msg: TWMNCRBUTTONDOWN );
var rPos:Tpoint;
ThemeDetails :TThemedElementDetails ;
sSize:TSize;
sStyle:TStyleManager;
WinRect:Trect;
begin
WinApi.Windows.GetCursorPos(rPos);
sStyle:=TStyleManager.Create ;
if sStyle.ActiveStyle.IsSystemStyle then begin
sStyle.Free ;
inherited;
exit;
end;
ThemeDetails:=sStyle.ActiveStyle.GetElementDetails ( vcl.Themes.TThemedWindow.twCaptionActive );
sStyle.ActiveStyle.GetElementSize(0,ThemeDetails,TElementSize.esActual ,sSize);
sStyle.Free ;
GetWindowRect(handle,WinRect);
// Check if cursor is on Caption bar
if rPos.Y -WinRect.Location.Y <sSize.Height then
self.PopupActionBar1 .Popup(rPos.x,rPos.Y )else
inherited;
end;
تستطيع تغيير هذه الاسماء , كما تستطيع أن تستخدم الاعدادت الخاصة بالجهاز
تابع معي
أضف هذه الاجراءات الى القسم Private
PHP كود :
procedure EnumMenus;
procedure ItemClick(Sender: TObject);
الاجراء EnumMenus
PHP كود :
procedure TMain.EnumMenus;
var SysMenu:HMenu;
s:PAnsiChar;
icount:integer;
i: Integer;
rPos:TPoint;
begin
SysMenu := GetSystemMenu(Handle, FALSE) ; // get handle to Menu Icon
icount:=WinApi.Windows.GetMenuItemCount(SysMenu);// Get Menu Count
for I := 0 to icount-1 do begin
GetMem(s,256);
GetMenuStringA(SysMenu,i,s,-1,MF_BYPOSITION );// Get MenuItem Name
self.PopupActionBar1.Items[i].Caption :=s;
Self.PopupActionBar1.Items [i].OnClick :=ItemClick;
if s='' then
self.PopupActionBar1.Items[i].Caption :='-';// Add Separator
FreeMem(s,256);
end;
end;
PHP كود :
procedure TMain.ItemClick(Sender: TObject);
var SysMenu:HMenu;
MenuID:DWORD;
begin
SysMenu := GetSystemMenu(Handle, FALSE) ;
MenuID:=WinApi.Windows.GetMenuItemID(SysMenu,TMenuItem(sender).MenuIndex) ;//Get ID
SendMessage(Handle,Winapi.Messages.WM_SYSCOMMAND ,MenuID ,0);//click MenuItem
end;
النتيجة
كما يمكنك أن تتجاهل الحدث EnumMenus و تصمم ال Menu الخاص بك

