السلام عليكم.
تجربة اليوم هي كيف نظهر رسوم ضمن شريط الحالة StatusBar و ذلك عن طريق استخدام CImageList .
أولا هذه صورة من البرنامج :

كما نعرف أن شريط الحالة يستخدم تابعين من أجل إظهار النص و هما SetText و SetPaneInfo و لكن لا يوجد تابع للرسم بشكل مباشر و لذلك علينا توريث Class من CStatusbarCtrl و من ثم نضع الخاصية SBT_OWNERDRAW للقسم Pane المراد وضع الرسوم فيه و من ثم معالجة عملية الاظهار في التابع DrawItem وهو virtual .
نبدأ الآن في شرح طريقة عمل البرنامج :
أولا نقوم باضافة شريط أدوات جديد و نحدد عرض الأزرار فيه 32 Pixels لأن هذا العرض مناسب و من ثم نضيف الرسوم التي نريد عرضها في شريط الحالةو قد رسمت قطع ناقص بلونين اخضر و احمر.
الآن نضيف Class جديد إلى المشروع بحيث نشتقه ( نورثه ) من CStatusbarCtrl و قد أسميته CBmpStatusbarCtrl و نضيف متحولا من نوع CImageList من أجل تحميل الصور.
و كون شريط الحالة مرتبط بال Frame لذلك نقوم بتعريف متحول من نوع CBmpStatusbarCtrl ضمن CMainFrame ثم نقوم بانشائه في التابع OnCreate كما يلي :
m_wndStatusBar.Create(WS_CHILD|WS_BORDER|WS_VISIBLE|CCS_BOTTOM|SBARS_SIZEGRIP,CRect(0,0,0,0),this,AFX_IDW_STATUS_BAR);
int aWidths[2] = {0,0};
m_wndStatusBar.SetParts( 2 , aWidths ) ;
m_wndStatusBar.SetText("Click to change the Bitmap",0,0 );
m_wndStatusBar.SetText((LPCSTR)(DWORD)0 , 1 , SBT_OWNERDRAW );السطر الأول يقوم بانشاء شريط الحالة و تحديد خصائصه.
السطرين الثاني و الثالث يحددان عدد المناطق Panes ضمن شريط الحالة و عرض كل منطقة.
السطر الرابع يقوم باظهار نص في المنطقة الأولى.
السطر الخامس يقوم باعطاء الخاصية SBT_OWNERDRAW للمنطقة الثانية و هو الذي هذه المنطقة قابلة للرسم.
يجب أيضا كتابة شيفرة في التابع OnSize ضمن CMainFrame و ذلك من أجل تغيير حجم و مكان شريط الحالة عندما يتغير حجم النافذة وهذه هي الشيفرة:
int aWidths[2] = {cx/2,-1};
m_wndStatusBar.SetParts( 2 , aWidths ) ;
m_wndStatusBar.MoveWindow( 0 , cy , cx , cy );و بعد ذلك نصل إلى الجزء المهم في البرنامج و هو عملية إظهار الرسوم في شريط الحالة و هو يتم في التابع DrawItem و شيفرته :
void CBmpStatusbarCtrl::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct)
{
if ( m_pList == NULL )
return;
int nIndex = lpDrawItemStruct->itemData ;
CDC *pdcDest = CDC::FromHandle(lpDrawItemStruct->hDC);
CPoint pt(lpDrawItemStruct->rcItem.left,lpDrawItemStruct->rcItem.top);
m_pList->Draw( pdcDest , nIndex , pt , ILD_TRANSPARENT);
}كما ترون فإن التابع يتلقى بارامتر واحد من نوع LPDRAWITEMSTRUCT و هو يحتوي على معلومات يحتاجها شريط التمرير من أجل إتمام عملية الرسم حيث تم استخدام itemData من أجل تحديد رقم الصورة التي نريد عرضها و أيضا تم استخدام hDC من أجل تحديد المنطقة التي سيتم الرسم فيها و أيضا تم استخدام rcItem.left و rcItem.top من أجل تحديد مكان الرسم و أخيرا تم استخدام التابع Draw من CImageList من أجل تنفيذ عملية الرسم على المنطقة المحددة.
يمكنكم الحصول على الشيفرة من الوصلة التالية :
http://arabteam.nicmatic.com/adel/BMPStatusbar.zip
مع التحيات.