كما يقال دائما كثرة كتابة الأكواد تؤهلك لإحتراف لغة البرمجة
ومن هذا المنطلق سنبدأ إن شاء الله بكتابة مجموعة من الأكواد وفهم دوال الربط البينية API
ملاحظة مهمة: الأكواد كتبت بواسطة فجول سي بالكود القياسي 32 بت إذا كنت
تستخدم مكاتب MFC قد تواجهة بعض الأخطاء ولذلك قبل كل دالة ضع هذة العلامة ::
مثال الدالة MessageBox إكتبها بهذة الطريقة
MessageBox::
وبسم الله نبدأ
يجب فهم أهم الدوال وأكثرها إستخدام
أولا: دوال الملفات
CreateFile
دالة إنشاء ملف جديد أوفتح ملف أو إنشاء مقبض لجهاز مثل السواقة أو المنافذ
البارمترات:
1- مسار الملف وقد يكون إسم جهاز مثل COM1,COM2 أو A: أو C: أو إسم أي معرف جهاز
في الذاكرة
2- خصائص الوصول إما للكتابة في الملف أو للقرائة أو للكتابة والقرائة
3- خصائص الوصول للمشاركة بمعنى أن تسمح لأي برنامج غير برنامجك من القرائة والكتابة
أو الحذف من الملف
4- خصائص الأمن للملف وهذة الشغلة نأجلها لبعدين
5- طريقة إنشاء الملف وتأخذ القيم التالية
CREATE_NEW = إنشاء ملف جديد وإذا كان موجود إنهي العملية
CREATE_ALWAYS= إنشاء ملف جديد وإذا كان موجود إحذفة وأنشأ ملف جديد فارغ
OPEN_EXISTING = إفتح ملف موجود وإذا كان غير موجود إنهي العملية وهذا المتغير دائما يوضع
عندما تريد إنشاء مقبض لجهاز أو سواقة
OPEN_ALWAYS =إفتح ملف موجود وإذا كان غير موجود إنشأ جديد
TRUNCATE_EXISTING = فتح ملف موجود فارغ وإذا كان غير موجود أو حجمة أكبر من صفر إنهي العملية
6- خصائص الملف مثل إرشيف أو مخفي أو للنظام أو مؤقت
FILE_ATTRIBUTE_ARCHIVE
FILE_ATTRIBUTE_HIDDEN
FILE_ATTRIBUTE_NORMAL
FILE_ATTRIBUTE_OFFLINE
FILE_ATTRIBUTE_READONLY
FILE_ATTRIBUTE_SYSTEM
FILE_ATTRIBUTE_TEMPORARY
7- مقبض لملف مؤقت وهذا يستخدم مثلا في برامج تحرير النصوص وللملفات التي يتم فيها التغيير مستمر.
هذة الدالة تعيد مقبض الملف الذي ستستخدمة للكتابة والقرائة
-----------------
ReadFile
WriteFile
دالتين القرائة والكتابة ولهم نفس البارمترات
1- مقبض الملف العائد من دالة إنشاء ملف
2- مخزن البيانات إذا كانت الدالة قرائة تخزن البيانات المقروئة
في هذا البارمتر وإذا كانت دالة كتابة سيكتب في الملف البيانات المخزنة هنا
3- عدد البايتات التي تريد كتابتها أو قرائتها
4- مؤشر إلى عدد البايتات التي قرأت أو كتبت للملف هذا البارمتر
لمعرفة إذا حدث أي خطأ في الدالة إذا كانت هذة القيمة مساوية للصفر
فهنالك خطأ
5- هذا البارمتر لة علاقة بالأجهزة والمنافذ مثل المودم وأجهزة الإدخال والإخراج
حيث إنة يعمل كمؤشر للمخزن التي تستخدمة هذة الأجهزة كما لة علاقة بالأحداث
----------------
أمثلة على كل ماسبق
إليك مثال يقوم بإنشاء ملف نصي جديد وإذا كان موجود يحذفة وينشأ ملف جديد
وبعد إنشاء الملف يقوم بكتابة عبارة داخلة ويغلق الملف
HANDLE hFile;
DWORD nbyte;
hFile=CreateFile ("D:\\file.txt",GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE
,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
if(hFile!=INVALID_HANDLE_VALUE)
WriteFile (hFile,(LPCVOID)"Arab-team",9,&nbyte,NULL);
CloseHandle (hFile);في ملاحظة على الكود لاحظ هذا السطر
f(hFile!=INVALID_HANDLE_VALUE)
إذا حدث خطأ في دالة إنشاء الملف فإن الدالة ترجع القيمة
INVALID_HANDLE_VALUE
ونلاحظ في الكود أنة مكتوب إذا كان المقبض لا يساوي هذة القيمة
أي أن المقبض صحيح نفذ دالة كتابة إلى الملف
يمكن أحد الأعضاء يسأل لماذا الشرط if لم يحدد لة بلوك كمايلي
if(hFile!=INVALID_HANDLE_VALUE){
WriteFile (hFile,(LPCVOID)"Arab-team",9,&nbyte,NULL);
}طبعا كلامة صحيح مئة بالمئة ولكن إذا كان بعد الشرط سطر واحد ينفذ
تستطيع أن لا تكتب البلوك بمعنى أن كل الطرق صحيحة
مثال ثاني مع دالة القرائة
بعد تنفيذ الكود الأول إكتب هذا الكود ونفذة وهو عبارة عن برنامج
يقوم بفتح الملف الذي أنشأناه في الكود السابق ويقرأ محتوياتة
ويظهرة في مسج لا حظ التغيرات في دالة إنشاء الملف
HANDLE hFile;
DWORD nbyte;
char buff[10];
ZeroMemory(buff,10); //تصفير مصفوفة حروف
hFile=CreateFile ("D:\\file.txt",GENERIC_READ,0
,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if(hFile==INVALID_HANDLE_VALUE) //إذا كان المقبض خطأ
strcpy(buff,"Error"); //نفذ الكود وهو نقل كلمة خطأ لمصفوفة الحروف
else // وإذا كان غير ذلك نفذ دالة القرائة
ReadFile (hFile,buff,9,&nbyte,NULL);
MessageBox (NULL,buff,NULL,NULL); // إظهار نتيجة القرائة
CloseHandle (hFile);-----------------
تكملة دوال الملفات
SetFilePointer
هذة الدالة تغير مكان مؤشر القرائة أو الكتابة
فمثلا عند فتح ملف يكون المؤشر يساوي 0 أي بداية الملف
لاحظ في مثالنا السابق في القرائة من الملف
غير في الكود بهذة الطريقة بعد دالة إنشاء
الملف وقبل جملة الشرط if ضع هذا الكود
SetFilePointer(hFile,4,NULL,FILE_BEGIN);
وجرب البرنامج بتلاحظ إن البرنامج قرأ من بعد رابع
حرف من البداية وهذا بالظبط فكرة الدالة غير الرقم
4 مثلا إكتب 6 أو 3 وشوف النتيجة
بالنسبة للمتغير FILE_BEGIN
معناة الإزاحة تبدأ من البداية ولها قيم أخرى
FILE_END = الإزاحة تبدأ من نهاية الملف
FILE_CURRENT = الإزاحة تبدأ من الموقع الحالي للمؤشر
في ملاحظة هنا وهي
أن المؤشر يتغير بشكل ذاتي فمثلا لو أنشأنا ملف جديد
وكتبنا عبارة من خمس أحرف فإن المؤشر بشكل ذاتي يتحول إلى
رقم 5 ولو نفذنا تعليمة قرائة في هذة اللحظة فإن النتيجة ستكون خطأ
وهنا تأتي أهمية هذة الدالة يجب أن ننقل المؤشر إلى رقم 0 وثم نقرأ من الملف
وفي شيء آخر إذا أوغلق المقبض تختفي قيمة المؤشر
وفي دوال لها علاقة بهذة الدالة
SetEndOfFile
وهي تنقل المؤشر إلى نهاية الملف
وتستخدم لإكمال كتابة ملف تم غلقة وهي مثل الدالة السابقة
بهذا الشكل
SetFilePointer(hFile,0,NULL,FILE_END);
بمعنى آخر أغلب الدوال لها نفس الطريقة
----------
حذف الملف في نهاية الكود إكتب
DeleteFile("D:\\file.txt");مع ملاحظة أنك قد أغلقت مقبض الملف
---------
معرفة حجم الملف
DWORD size=GetFileSize(hFile,NULL);
إذا كان خطأ ترجع القيمة
0xFFFFFFFF
----------
معرفة أو تغيير خصائص الملف
SetFileAttributes
GetFileAttributes
أكيد البارمتر واحد مسار الملف والخصائص تم ذكرها في أول دالة
------------------
نقل الملفات وهي الدوال التي تقوم بنقل الملف ومحتواة كامل لدليل آخر
CopyFile
MoveFile
مثال لنقل الملف من سواقة لأخرى
CopyFile ("d:\\file.txt","c:\\NewFileB.txt",FALSE);أكيد البارمتر الأول والثاني واضحين أما الثالث
إذا كان صح TRUE
فإن النظام إذا وجد ملف بنفس إسمة في نفس الدليل الذي سينقل لة
ينهي العملية
أما إذا كان FALSE
فإنة يحذف الملف القديم ويحل محلة الملف الجديد
معلومة : أغلب الفايروسات تستخدم هذة الطريقة لنقل
نفسة إلى دليل النظام بهذة الطريقة
char AppPhat[MAX_PATH]; ZeroMemory(AppPhat,MAX_PATH); GetModuleFileName (NULL,AppPhat,MAX_PATH); CopyFile (AppPhat,"c:\\My.exe",FALSE);
--------------
البحث والعرض
FindFirstFile
FindNextFile
FindClose
لعرض محتويات مسار معين أو للبحث عن ملف معين
وتعيد إسم الملف نوعة وقت الإنشاء والتعديل
مثال عن عرض الملفات
HANDLE hFind;
WIN32_FIND_DATA cbFind;
hFind=FindFirstFile ("d:\\*.*",&cbFind);
if(hFind!=INVALID_HANDLE_VALUE){
do{
MessageBox (NULL,cbFind.cFileName,NULL,MB_OK);
}while(FindNextFile (hFind,&cbFind)!=0);
}
FindClose (hFind);هذا الكود يعرض كل الملفات والمجلدات في دليل معين
--------------
أكيد لم ننهي كل دوال الملفات ولكن إستعرضنا أهمها وسيتم
إستكمالها فيما بعد وأكيد بمشاركت الأعضاء
--------------
دوال السلاسل النصية والحروف
lstrcpy
نقل نص إلى مخزن أحرف
lstrcat
إضافة نص إلى المخزن
lstrcmp
مقارنة نصيين مع مراعاة الأحرف الصغيرة والكبيرة
مثال للثلاث دوال
سنعرف مصفوفة أحرف ونضيف لها بداية الأحرف ABCDEFG
ثما نقارن النصين معا
char buff[MAX_PATH]; ZeroMemory(buff,MAX_PATH); lstrcpy(buff,"ABC"); MessageBox (NULL,buff,"1",NULL); lstrcat(buff,"DE"); MessageBox (NULL,buff,"2",NULL); lstrcat(buff,"FG"); MessageBox (NULL,buff,"3",NULL); if(lstrcmp(buff,"ABCDEFG")==0) MessageBox (NULL,"النص مساوي ",NULL,NULL); else MessageBox (NULL,"النص لا يساوي",NULL,NULL);
lstrcmpi
هذة الدالة تقارن نصين ولا تراعي الأعرف الصغيرة والكبيرة
lstrlen
هذا الدالة تعيد عدد الحروف في المصفوفة
---في ملاحظة هنا
هذة الدوال للسلاسل النصية عبارة عن دوال API
أما strcpy,strcmp,strlen بدون حرف l في البداية فهي مايكرو
والفرق بينهم أن الدالة تتصل بمكتبة ربط وينفذ فيها الكود
أما المايكرو فهو عبارة عن نص من الكود يضاف إلى البرنامج
في كثير من المايكروات مفيدة جدا مثل
strstr هذا المايكرو يبحث عن كلمة أو حرف داخل نص
---نكمل دوال النصوص
CharLower
تحول نص من الأحرف الكبيرة إلى الصغيرة
CharUpper
تحول من الأحرف الصغيرة إلى الكبيرة
الدالتين
MultiByteToWideChar
WideCharToMultiByte
هذة الدالتين مستواهم متقدم ولكن قررت أشرحها في هذا
الدرس لسبب أنها دوال مهمة خاصة للعرب ؟؟ وأهل
اللغات المتطورة ومن المهم فهمها لإستمرار تطور البرمجة بالغة العربية
ما الفرق بين اللغة الإنجليزية والعربية بالنسبة للكمبيوتر
بكل بساطة كل حرف أجنبي = واحد بايت كل حرف عربي = 2 بايت
وهو ما يعرف بترميز آسكي وترميز اليونيكود
واليونكود ليست فقط اللغة العربية
بل أكثر من لغة مثل اليابانية الروسية ...أكثر لغات العالم
المهم لا نريد الخروج عن الموضوع
الحين النظام يعرف أي حرف يونيكود أو آسكي على أنة بايت
واحد فقط وهذا للتوافقية بين الإتصالات وغيرة
والفرق بينهم أن بايت اليونيكود يسمى بايت موسع
ولو ترجع للدالتين وتقرأ أسمائها
الأولى = تحويل أكثر من بايت لحرف موسع 2بايت= 1 بايت
الثانية = تحويل حرف موسع لأكثر من بايت 1بايت = 2 بايت
والمقصود أن الدالة الأولى تحول البايت من صيغتة الأصلية إلى حرف موسع للتوافقية
والثانية تعيد البايت من الحالة التوافقية إلى صيغتة الأصلية
هل تريد أمثلة على أهميت هذة الدالة
حاول نسخ أي نص عربي إلى الحافظة في نظام وندوز NT بدون إستخدام هذة الدالة
حاول نقل حرف واحد عبر منفذ دون إستخدام هذة الدالة
وكل ما بدأت تكتب برامج أكثر تحتاجها أكثر
لاحظ هذا الكود
هذا الكود عبارة عن دالة تقوم بنسخ السطر المختار من قائمةListBox
ونقلة إلى الحافظة ليتم نسخة بواسطة لصق أكيد يعمل مع كل اللغات
الأسكي واليونيكود ومع إصدارت وندوز المختلفة
BOOL ListBoxGetTextn(HWND MainsPH)
{
char Aiitem[MAX_PATH];
HWND listHwn;
int MarDx=0;
void *clipBuf=NULL;
void *addrStr=NULL;
listHwn=GetDlgItem (MainsPH,IDC_ListChReg);
MarDx=ListView_GetSelectionMark(listHwn);
if(MarDx==-1)
return 1;
ListView_GetItemText(listHwn,MarDx,0,Aiitem,MAX_PATH);
if(OpenClipboard (MainsPH))
{
if(GetVersion()<0x80000000) //Win NT
{
WCHAR Uditem[MAX_PATH*2];
clipBuf=GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE|GMEM_ZEROINIT,lstrlen(Aiitem)*2+2);
if(clipBuf==NULL)
return 1;
// لاحظ الدالة
MultiByteToWideChar (CP_ACP,MB_PRECOMPOSED,Aiitem,lstrlen(Aiitem),Uditem,sizeof(Uditem));
addrStr=GlobalLock(clipBuf);
if(addrStr==NULL)
{
GlobalFree (clipBuf);
return 1;
}
memcpy(addrStr,Uditem,lstrlen(Aiitem)*2+2);
GlobalUnlock (clipBuf);
if(!EmptyClipboard())
{
GlobalFree (clipBuf);
return 1;
}
if(!SetClipboardData (CF_UNICODETEXT,clipBuf))
{
GlobalFree (clipBuf);
return 1;
}
}
else //Win 9x
{
clipBuf=GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE|GMEM_ZEROINIT,lstrlen(Aiitem)+1);
if(clipBuf==NULL)
return 1;
addrStr=GlobalLock(clipBuf);
if(addrStr==NULL)
{
GlobalFree (clipBuf);
return 1;
}
memcpy(addrStr,Aiitem,lstrlen(Aiitem)+1);
GlobalUnlock (clipBuf);
if(!EmptyClipboard())
{
GlobalFree (clipBuf);
return 1;
}
if(!SetClipboardData (CF_TEXT,clipBuf))
{
GlobalFree (clipBuf);
return 1;
}
}
CloseClipboard ();
}
return 0;
}================
هذا والله أعلم
ترقبوا دوال الذاكرة و دوال النظام في الدرس القادم
أتمنى من الأعضاء طرح ما عندهم من دوال قد تفيد الأعضاء
بمعنى أن كل مشاركة لها فائدة لكل مبتدأ وخبير
وبالتوفيق


