العودة إلى  مدرسة الكمبيوتر   قسم البرمجة    الصفحة الأولى

المثال التطبيقي


سنشرح برمجة برنامج بسيط باستخدام لغة فيجوال سي يوفر للمستخدم إمكانية البحث عن اسم كتاب في قاعدة بيانات، وسنستخدم تقنية ADO في التعامل مع قاعدة البيانات.


الخطوة الأولى هي تكوين الهيكل الرئيسي للبرنامج، ولعمل ذلك استخدم المعالج MFC AppWizard (exe)، الذي يمكنك الوصول إليه بالنقر على القائمة File، ثم اختيار البند New...، واختيار البند MFC AppWizard (exe) من الشريط Projects، ثم كتابة اسم المشروع، ولنطلق على مشروعنا هذا اسم Library، ثم ننقر على الزر OK.


اختر بعد ذلك البندDialog based ، ثم انقر على الزر Finish. فتظهر نافذة تحتوي على معلومات عن المشروع الذي أنشأناه. انقر على الزر OK، فيفتح الإطار IDD_LIBRARY_DIALOG جاهزاً للتحرير. امسح الزر Cancel، والنص TODO: Place dialog controls here، وغيّر نص الزر OK إلى Close، وذلك بالنقر عليه بالزر الأيمن للماوس، ثم اختيار البند Properties...، وتغيير النص في مربع التحرير Caption إلى Close.
أضف عناصرتحكم إلى هذا الإطار، ثم رتبها بطريقة مشابهة للشكل 1.
www.tartoos.com

تلاحظ أن الحقل Extended Styles يحتوي أحياناً على القيمة "Static edge"، ويعني هذا أن عليك النقر على الشريط Extended Styles في الإطار Text Properties، وتعيين المربع Static edge.
وربما يتبادر السؤال التالي إلى أذهان بعض القراء: لماذا أعطينا بعض عناصر التحكمات النصية Static Texts أرقام تعريف ID خاصة بها، مثل ID_PUBLISHER_STATIC، بينما اكتفينا في مرات آخرى برقم التعريف IDC_STATIC؟


تستخدم عناصر التحكم النصية الساكنة بشكل رئيس لكتابة النصوص في النوافذ أثناء مرحلة التصميم، كما استخدمناها في كتابة النص "Publisher:" مثلاً، وفي هذه الحالة، لسنا بحاجة لتغيير هذا النص برمجياً، ما يعني أننا لسنا بحاجة إلى إعطاء عنصر التحكم هذا رقماً تعريفياً خاصاً. أما في حالة عنصر التحكم ID_PUBLISHER_STATIC وغيره من العناصر، فإننا نريد أن نضع فيه اسم دار النشر التي نشرت الكتاب الذي يبحث عنه المستخدم، وقيمة هذا التحكم غير معروفة أثناء فترة التصميم، وعلينا أن نضعها فيه برمجياً ، لذا فنحن بحاجة إلى تغيير قيمة عنصر التحكم برمجياً، أي أننا بحاجة إلى ربط متغيّر بهذا التحكم، كي نستطيع من خلال هذا المتغيّر، تغيير قيمة عنصر التحكم.
www.tartoos.com
 

وخلاصة القول: إذا كنت لا تعتزم ربط متغير بتحكم نصي لتغيير قيمته مثلاً، فأبقِ قيمة رقمه التعريفي: IDC_STATIC، وإلا عليك تغيير قيمة الرقم التعريفي.
علينا الآن أن نُضيف الوظائف البرمجية إلى هذا الإطار، والخطوة الأولى هي ربط بعض المتغيرات بعناصر التحكم الموجودة في هذا الإطار، ولعمل ذلك اختر البند ClassWizard... من القائمة View. انقر بعد ذلك على الشريط Member Variables، ثم اختر البند CLibraryDlg من القائمة المنسدلة Class name:. يمكنك الآن النقر على كل من عناصر التحكم التي تجد رقمها التعريفي في الجدول 2، والنقر على الزر Add Variable...، وتعبئة حقول هذا الإطار.www.tartoos.com
 

علينا الآن تنفيذ بعدة خطوات، كي نتمكن من استخدام تعليمات ADO في برنامجنا من أجل التخاطب مع قاعدة البيانات. والحقيقة أنه توجد عدة طرق لعمل ذلك، وأسهلها هو استخدام تعليمة #import، وهي الطريقة التي تنصح بها شركة مايكروسوفت. ولعمل ذلك، افتح الملف "StdAfx.h"، وأضف إلى نهايته، وقبل تعليمة #endif الأخيرة، السطرين:www.tartoos.com


#include
#import "C:\program files\common files\system\ado\msado15.dll" no_namespace rename( "EOF", "adoEOF" )

وعندما تنفذ يعد ذلك عملية ربط البرنامج، فإنَّ يكون آلياً عدة ملفات رأسية (Header Files) يمكن أن نستخدمها لاحقاً.
تعتمد تقنية ADO على تقنية COM، وعليك لهذا أن تخبر البرنامج بالحاجة إلى مكتبات COM، ولعمل ذلك افتح الملف Library.cpp، ثم ابحث عن الوظيفة InitInstance، وأضف السطر التالي إلى بداية تلك الوظيفة:
AfxOleInit ( );
علينا الآن أن نضيف متغيّرين إلى الصنف CLibraryDlg، ولعمل ذلك، افتح الملف LibraryDlg.h، ثم أضف السطرين التاليين تحت التعليمة "protected:":


BOOL m_bIsConnectionOpen;
_ConnectionPtr m_pConnection;


بعد ذلك افتح الملف LibraryDlg.cpp، ثم اذهب إلى المنشئ "Constructor" الخاص بهذا الصنف، أي
CLibraryDlg::CLibraryDlg(CWnd* pParent /*=NULL*/)
وأضف إليه السطر التالي:
m_bIsConnectionOpen = FALSE;

وسنستخدم هذا المتغير للإشارة إلى إذا كان الاتصال مع قاعدة البيانات مفتوحاً أو مغلقاً.
أضف بعد ذلك السطور التالية إلى الوظيفة OnInitDialog، تحت السطر //TODO…:-


HRESULT hResult;

hResult = m_pConnection.CreateInstance (__uuidof(Connection));

if (SUCCEEDED(hResult))
{
hResult = m_pConnection->Open (bstr_t(L"Provider=Microsoft.Jet.OLEDB.3.51;Data Source=c:\\Library\\Library97.mdb;"),
_bstr_t(L""), _bstr_t(L""), adModeUnknown);

if (SUCCEEDED(hResult))
m_bIsConnectionOpen = TRUE;
}


ع
رفنا في البداية متغير من نوع HRESULT، وذلك كي نخزّن فيه النتيجة التي ترجعها بعض الوظائف. واستخدمنا المتغيّر "m_pConnection"، الذي عرّفناه سابقاً، لتكوين كائن للاتصال بقاعدة بيانات. ثم تأكدنا من أنَّ النتيجة التي أرجعتها الوظيفة "CreateInstance" إيجابية، فإذا كانت كذلك فإننا نفتح قاعدة البيانات التي صممتها في الجزء الأول من هذه المقالة، باستخدام الأمر Open. وتذكر أن تغيير المسار المذكور في القيمة:
Data Source=c:\\Library\\Library97.mdb
إلى المسار الذي توجد فيه قاعدة البيانات على قرصك الصلب.
نفحص بعد ذلك القيمة التي أرجعتها التعليمة Open، فإذا كانت إيجابية، فإن ذلك يعني أننا تمكّنا من فتح الاتصال مع قاعدة البيانات، ونقوم عندها بوضع القيمة TRUE في المتغيّر m_bIsConnectionOpen.
علينا أن نضيف وظيفةً تُنفذ عندما ينقر المستخدم على الزر Find it!، لتتم عملية البحث عن اسم الكتاب الذي أدخله المستخدم. ولعمل ذلك شغّل المعالج ClassWizard... من القائمة View، ثم انقر على الشريط Message Maps، وتأكد من أن الصنف المحدد ضمن القائمة Class name: هو CLibraryDlg. انقر على البند IDC_FIND_BUTTON ضمن القائمة Objects IDs:، ثم انقر على البند BN_CLICKED ضمن القائمة Messages، وانقر على الزر Add Function...، فتظهر نافذة تقترح عليك الاسم OnFindButton للوظيفة الجديدة. اقبل هذا الاسم، وانقر على الزر OK. انقر على الزر Edit Code ليتم فتح هذه الوظيفة للتحرير، وأضف الأسطر التالية إلى هذه الوظيفة:

if (!m_bIsConnectionOpen)
return;

UpdateData ( );

_RecordsetPtr pRecordSet;

CString str;
str.Format ("SELECT * FROM Books WHERE Book = '%s'", m_strEditBook);
_bstr_t bstrQuery (str);
_variant_t vRecsAffected (0L);

try
{
pRecordSet = m_pConnection->Execute (bstrQuery, &vRecsAffected, adOptionUnspecified);

if (!pRecordSet->GetadoEOF())
{
_variant_t vBook, vISBN, vAuthor, vPublisher, vPages;

vBook = pRecordSet->GetCollect (L"Book");
vISBN = pRecordSet->GetCollect (L"ISBN");
vAuthor = pRecordSet->GetCollect (L"Author");
vPublisher = pRecordSet->GetCollect (L"Publisher");
vPages = pRecordSet->GetCollect (L"Pages");

m_strBook = (BSTR)(_bstr_t)vBook;
m_strISBN = (BSTR)(_bstr_t)vISBN;
m_strAuthor = (BSTR)(_bstr_t)vAuthor;
m_strPublisher = (BSTR)(_bstr_t)vPublisher;
m_strPages = (BSTR)(_bstr_t)vPages;
}
else
AfxMessageBox ("Can't find this book!");

pRecordSet->Close ( );
}

catch( _com_error &e )
{
_bstr_t bstrSource(e.Source());
_bstr_t bstrDescription(e.Description());

CString strError;
strError.Format ("Source = %s\nDescription = %s\n", bstrSource, bstrDescription);
AfxMessageBox (strError);
}

UpdateData (FALSE);

تأكدنا في البداية من أنَّ الاتصال مع قاعدة البيانات مفتوح، ثم نقلنا محتويات عناصر التحكم إلى المتغيرات المرتبطة بها عن طريق الأمر UpdateData (FALSE)، ثم عرّفنا متغيّر من نوع _RecordsetPtr، لتخزين الحقول التي سنطلبها من قاعدة البيانات. عرّفنا متغيّر نصي، ووضعنا فيه سطر برمجي مكتوب بلغة SQL، يطلب تحديد جميع الحقول في الجدول Books، التي فيها قيمة الحقل Book مطابقة لاسم الكتاب الذي أدخله المستخدم في مستطيل التحرير، والذي خزّناه في المتغيّر m_strEditBook. عرّفنا بعد ذلك متغيّر من نوع _bstr_t، وهو نوع يسّهل علينا التعامل مع النوع BSTR، ووضعنا في هذا المتغيّر قيمة المتغيّر str. ثم عرّفنا متغيّر من نوع _variant_t، سنستخدمه فيما بعد.
حصرنا التعليمات الخاصة بطلب الحقول الخاصة باسم الكتاب الذي أدخله المستخدم بين قوسي تعليمة try، وهي تعليمة خاصة بالاستثناءات، فإذا حصل أي خطأ أثناء عملية طلب الحقول من قاعدة البيانات، فإنها ترسل استثناء إلى تعليمة catch التي تقوم بمعالجته.
www.tartoos.com
 

تنفذ التعليمة الأولى ضمن قوسي تعليمة try، الأمر Execute عن طريق المتغيّر m_pConnection، والنتيجة الراجعة ستكون إما الحقول التي تحتوي على المعلومات الخاصة باسم الكتاب الذي أدخله المستخدم في حال وجود اسمه في قاعدة البيانات، أو لا شيء. www.tartoos.com
فحصنا بعد ذلك وجود أي حقول راجعة، فإذا وجدت، يعرّف البرنامج عدة متغيّرات من نوع _variant_t لنخزّن فيها قيم الحقول الراجعة، وذلك عن طريق استخدام الأمر GetCollect. بعد ذلك، وضعنا قيم هذه المتغيّرات في المتغيرات المرتبطة بعناصر التحكم. ثم أغلقنا الاتصال مع المتغيّر pRecordSet.
يتم تنفيذ التعليمات الخاصة بالتعليمة catch، في حالة وجود خطأ، فقط، وهي تعرض رسالة خطأ تخبرك عن سببه. وأنبه إلى إنَّ استخدام تعليمتي catch و try ضروري جداً، فإذا حصل خطأ، ولم تكن هاتان التعليمتان مستخدمتان، فإنَّ البرنامج سينهار بدون أن تعرف سبب ذلك.www.tartoos.com
شغّل المعالج ClassWizard...، وأضف وظيفة إلى البند IDOK، ثم انقر على الزر Edit Code، ففتح الوظيفة OnOK جاهزةً للتحرير. أضف الأسطر التالية تحت عبارة //TODO…:-

if (m_bIsConnectionOpen)
{
m_pConnection->Close ( );
m_bIsConnectionOpen = FALSE;
}

والغرض من إضافة هذه السطور، هو إغلاق الاتصال مع قاعدة البيانات، إذا كان مفتوحاً، عند إغلاق البرنامج. يظهر الشكل 2 النتائج التي حصلت عليها بعد أن أدخلت الاسم "Wallenstein".
ونكون بذلك قد أنهينا الجزء الثاني والأخير من هذه المقالة التعليمية، وآمل بأني قدمت فائدة مهمة لك.

 

 

 
 طباعة المقال العودة إلى  مدرسة الكمبيوتر   قسم البرمجة    الصفحة الأولى
Syria
سورية
Amrit
عمريت
أرواد
طرطوس
صور من طرطوس
صور من سورية
للسيدات فقط
معجم الكمبيوتر
أدب وفكر
المجلة الطبية
المعلومات العامة
لمحة عن طرطوس
الموضة النسائية
مدرسة الكمبيوتر
 © 2002-2012 LBCInformation Corporation. All rights reserved م حنا عطا لحود.