‏إظهار الرسائل ذات التسميات Delphi. إظهار كافة الرسائل
‏إظهار الرسائل ذات التسميات Delphi. إظهار كافة الرسائل

١١‏/٤‏/٢٠٠٧

مشكلة الخمسة والعشرون يوماً



عجيباً أمر البرمجة. والأعجب أن تكون مهووس وتبحث عن المثالية في البرمجة.
بعد أن صممت البرنامج وقمت بفحصه وتأكدت أن كل شي يعمل كما هو مصمم عليه....يجب ألا يكون هناك أي شي للصدفة .
99.9% فكرت بكل شيء. ودرست الاحتمالات الممكن حدوثها بالبرنامج واحتطت .
وتلافيت استعمال أي مكون مالم أكون صممته إلا (واحد) ، لان لن أقوم باكتشاف العجلة من جديد،البرنامج صمم على ان يعمل اربع وعشرون ساعة في سبعة ايام ، يعني لاشي أن يوقفه.

وضعت تحت الفحص لمده 14 يوما واكتشفت خطأ ما. ليس من البرنامج ولكن بسبب احد دوال الويندوز. وتلافيت استعمال هذه الدالة.
واستعمال البرنامج بأقصى إمكانياته بتفعيل جميع الخيارات وضعت البرنامج تحت مراقبه برنامج perform اللذي يأتي مع الويندوز لمراقبة أداء الكومبيوتر وموارده. ومراقبة private bytes لبرنامج لاكتشاف أذا كان هناك أي تسرب بالذاكرة memory leak.

جميل ......كل شي يعمل كالساعة. تك تك تك .
وضعته تحت التشغيل الفعلي بعد التأكد من أن كل شيء يعمل كما هو مصمم عليه.

وفي يوم من الأيام اتصل على (احد مستخدمين البرنامج) يخبرني أن البرنامج عمل خروج فجأة. فسألته إذا عمل شي معين قبل أن يتوقف البرنامج. فقال انه لم يكن امامه وإنما اكتشف إن البرنامج لم يكن شغال.
ذهبت الى الموقع. وقمت اولاً بفحص الكومبيوتر. فلم احصل على شيء. لان كل شيء سليم ولا يوجد هناك أي شيء بالنظام نفسه. وفحصت Event Viewer ووجدت رسالة الخطأ رقم 4009 ثم فحصت اللوق ووجدت رساله الخطأ لبرنامج drwtsn وهي C0000025 ، وبدراسه رسالة الخطأ هذه عرفت ان معنها unrecoverable error يعني حتى الويندوز لا تحددها بالشكل السليم. !!
طيب.
قمت بتشغيل البرنامج ورجعت لمكتبي وقمت بتشغيل البرنامج أيضا على احد الكومبيوترات لفحص، وتركته يعمل، يوم، يومان........ثلاثة........25 يوم ، وفجأة اتصل علي المستخدم وقال لي نفس الشيء قد حدث؟ وقمت فألقيت نظره على الكومبيوتر الذي عندي في المكتب حيث وضعت كومبيوتر لفحص البرنامج وقد تفاجأ ت إذا رأيته هو أيضا قد عمل خروج .اممممم اذا ليس السبب من نظام التشغيل. لان النظامان يختلفان (win2000,winXP) ولكن المشترك بينهم هو البرنامج والمدة.!! امممم لماذا 25 يوم بالضبط تقريبا؟!!!!!!
فبحثت بالانترنت إلى أي شي قريب من هذا؟ وهل هذه المشكلة أوالظاهرة لها علاقة بال memory fragmentation . ولكن لا شي أبداً قريب من هذا.
ولكنى متاكد انها ليس من الذاكرة لأني اتخذت احتياطاتي لدرجه لا تتصورون . والمشكلة الأخرى أنها تحتاج 25 يوم لفحص، أي إذا غيرت شي بالبرنامج لفحصه أنت تحتاج إلى 25 يوم لترى النتيجة.
لقد جلست أيام احك راسي واكلم نفسي. كيف يكون الحل، وأين تكمن المشكلة . أريد بداية الخيط .وأنا متأكد إني لا استعمل أي كائن لم اصنعه، إلا واحد وهذا open source كما ذكرت سابقا.
وبدأت احسب 25 يوم ماذا يساوي بالساعات 600 ساعة.
طيب 25 يوم * 24 ساعة *60 دقيقه =36000 دقيقه .
وبالثواني 2160000 ثانيه
ألم تلاحظون شيء غريب؟
أن الأرقام سحريه؟ أي أنها كلها تنتهي بصفر(وانها ارقام معروفه؟ او قد مرت عليك من قبل)
اممممم على ماذا يدل هذا؟ وبدأ المشوار..........قليلا قليلا والتفكير يتصاعد الى القمة وعملية شحذ المخ في اقصاها. وأنا في قمة التركيز تذكرت شيء؟ رقم سحري أخر وهو 49.7 يوم لويندوز؟
نعمممممممممممم.................49.7 / 2= 24.85 وصرخت بقوه اهااااااااااااااااااا
الرقم السحري الاول:
اتعرفون ماهو 49.7 يوم لوندوز.؟ اقول لكم القصة من البداية.
هناك دالة اسمها GetTickCount

وهذه الدالة عندما تناديها ترجع لك رقم (32 بت) يمثل بالملى ثانيه وهو زمن تشغيل الويندوز (او الكومبيوتر بالأحرى) وهذا الرقم يبدأ بالصفر عند تشغيل الويندوز (او الكومبيوتر) وهو يمثل عداد داخل الكومبيوتر(RTC) ، أي أن أقصى حد ممكن تمثله بالرقم 32 بت هو 4294967295
اي 4294967295 م ث وبتحويل هذا الرقم الى أيام يصبح 49.7 يوم وبعد أن يصل العداد إلى أقصى حد له يبدأ من الصفر مره اخرى (أي يصفرReset). ولكن........ما علاقة بين هذا و25 يوم.
كما بينت ان القيمه 25 يوم تمثل نصف العدد 49.7 تقريباً.

أذا هل انا استعمل الدالة هذه (GetTickCount) في البرنامج؟
والاجابة نعم استعملها في دالة تاخير Delay.

الرقم السحري الثاني:
هو 7FFFFFFF
نعم انه الرقم الذي يمثل longint او integer
2147483647..2147483648-
أو بالأحرى نصف الرقم (4294967295) وهو (2147483647)
الم تلاحظوا معي إن الرقم (2147483647) و (2160000)- انظر فوق كيف حصلنا عليه-قريبين من بعض.
عندما يصل العد الى أقصى حد ممكن تمثيله في integer بالموجب هو 2147483647 وهو ما يمثل 7FFFFFFF فأذا زدنا واحد يصبح الرقم 7FFFFFFF+1=80000000
80000000 هذا يمثل الرقم بالسالب =-1
لنفرض ان عندك هذا


Integer
x:=GetTickCount


إذا كانت الويندوز شغال اقل من 25 يوم هذا الرقم موجب!
وعندما تكون الويندوز شغال لمدة أكثر من 25 يوم هذا الرقم بالسالب. اكس سوف تصبح بالسالب.

عملية التنقيح والفحص:
بعد أن ذكرت سابقا من أن بداية حل المشكلة قد ظهر. ولكن حتى يكون الحل وتقديم تقرير عن المشكلة، الحدس لايكفي. ولا التفكير المنطقي يثبت شيء. لذالك وجب على أن اثبت المشكلة عن طريق المحاكاة (simulation ) أي أن اعمل المشكلة. لذالك انصب الحل الأول على أن أجعل البرنامج يتصرف كأنه قد مر على زمن التشغيل 25 يوماً.
وهنا السؤال كيف؟
الفكرة الأولى:
عملت دالة اسمها GetTickCountX وهذه الدالة تنادي الدالة الأصلية GetTickCount وتضيف على القيمة مقدار 25 يوم ناقص خمس دقائق. كما هو موضح بالصورة




ولكن لأسف لم تنجح؟ والسبب أن استدعاء دالة API ليس مثل استدعاء دالة من داخل برنامجك؟ هذا ما توصلت له. ثم قلت لنفسي سوف أستدعيها من DLL وعملت الدالة داخلDLL ولكن أيضا لم تحدث المشكلة والبرنامج استمر بالعمل طبيعي؟.
بداء الشك يدخل تفكيري.ربما اني أفكر بمشكلة ليست هي الأساس؟. ...والزمن يمر؟ والتقرير يجب أن يرفع بأقرب وقت. ولا أريد أن أضع التقرير بحل ليس أكيد. او ربما يكون خاطئ.
وقلت لنفسي يجب أن احصل على طريقة أخرى افحص بها . يجب ان انقح الويندوز!!! نعم يجب ان اتبع الدالة GetTickCount .
وهنا اعرف أن هناك منقح ويندوز من ماكروسوفت windbg وقمت بتنزيل أخر نسخه وقمت بتذكر كيف استخدمه لان النسخة القديمة command prompt وليس GUI عموما ما هي إلا سويعات والمنقح شغال.
قمت بتشغيل برنامجي تحت المنقح. ثم قمت بتنقيح Kernel32.dll والتي تحتوي على GetTickCount

u kernel32!GetTickCount

هذا الأمر unasm سوف يعرض الاسمبلي كود ومنها اعرف عنوان خروج الدالة وعندها سوف أضع نقطة التوقف
عنوان خروج الدالة هو 7c8092ba
نضع الأمر التالي نقطه توقف

"bp 7c8092ba "reax=@eax+0x7FFFFFF0;reax;g

و g في أخر الأمر هو معناها go أي اشتغل.




هذا الأمر يجعل القيمة المرجعة من الدالة في مسجل eax ما قيمته

Result= 2147483632 + current counter value

أي مجموع GetTickCount الفعلي مع القيمة المضافة.
وانتظرت قليلاً وإذا بالبرنامج يعمل خروج.
فارتسمت على محياي (حلوة هذه محياي) علامات الرضا. (أمس شاهدت فلم عنترة والظاهر انه اثرعلي)

وفحصت drwtsn لوق ووجدت نفس رقم الخطأ . هنا تأكدت من الحل ومن أسباب المشكلة.
فقمت بكتابة التقرير عن المشكلة وأسبابها. وذكرت اسباب المشكلة بالتفصيل مع ذكر ان سببها الرئيسي هو المبرمج بالأساس (أنا) flaw in programming ثم قمت بتصليح الخطأ وهو بسيط تغير قيمة integer إلى cardinal وقمت أيضا بتحسين عمل Delay بحيث لو وصل العد إلى 47.9 لا يدخل في لوب غير منتهي.
نلاحظ من حل المشكلة الأتي:
ليس أن يكون برنامج 100% شغال ولكن هناك ثغرات ربما تحدث بعد وقت معين. لذالك يجب أن تفحص برنامجك بتغير الوقت والتاريخ وكذالك بجعل البرنامج يشتغل أطول مدة ممكنة .
أيضا مهما يكون المبرمج متمكن هناك هفوات ربما يقع فيها اعتى المبرمجين (حلوة هذه أعتى أقولكم أن فلم عنترة اثر علي بجد).
كذالك لاحظت أن الويندوزتتعامل مع Kernel call بطريقة تختلف عن روتين داخل برنامج أو dll خاص.
ارجوا أن تكون هذه المقالة مفيدة.


xlogic

١‏/٢‏/٢٠٠٧

PeakMessages or not to PeakMessages ?

I 'm confused; some programmers say you should create message queue before you call GetMessage in thread.


But all my threads are using GetMessage without creating message queue, and they are working find. So should I use PeekMessages to force creating queue or shouldn’t?


I know that any VCL windows got its own message queue.

٢٧‏/١‏/٢٠٠٧

What is the relation between .NET & JAVA ماهي العلاقة بين دوت نت والجافا


طبعا انا من الكارهين لشيء اسمه دوت نت.لست انا الوحيد ولكن الكثيرين من مستخدمين البرمجيات يحاولون تجنب الدوت نت.وكمبرمج ومستخدم . اكرها لعدة اسباب. هي لا تقدم شيء جديد انما تكنلوجيا يريدونك ان تستخدمها. هم يقولون تطور؟ وانا أقول تسويق! نعم انها عملية تسويق واتفاق بين المصنع (Hardware) و مَصنع البرمجيات (Software).سوف يقول قائل كيف هذا؟.
قبل ان اكمل....السؤال المطروح ما هي دوت نت (Net.) بالاساس؟ تعريف ماكروسوفت هو :

Software that connects information, people, systems, and devices

هذا هو التعريف المذكور "برمجيات التى توصل بين المعلومات ،الناس، انظمة والاجهزة "
طبع اذا فهمت شي تعال قولي!!!.

وهذا يذكرني عندما كنت ادرس SAP ولغة ABAP .وعندما عرضوا علينا تعريف الساب قالوا:
System And People

طبعا التعريف اللذي ذكر لا يعرفها بشكل كامل. اذا اردت التعريف تستطيع ان تطلع عليه في هذا الموقع
نرجع لموضوع الدوت نت والتسويق.
عندما تركب Dot Net Frame ماذا تلاحظ؟ انها كبيره الحجم؟ صحيح . وليس هذا فقط ولكن تستهلك موارد الجهاز؟. بالمقابل ماذا تقدم لي كمستخدم؟ لاشيء جديد؟ يعني ركبتها او لم تركبها انت تستطيع ان تعمل بدونها.
وما قصة التسويق؟ نعم سوف اشرح لك القصة، عندما تركب دوت نت على جهازك وجهازك لنقول سرعته متوسطه وموارده متوسطة. انا اتكلم عندما أشتريت جهازك كانت المواصفات هى القمة. يعني قبل سنتين لنفرض كانت مواصافات جهازك هي top of art والان بعد انقضاء السنتين بالطبع نزلت بالسوق مواصفات اعلى. ولكن .......هل انت مجبر على شراء جهاز جديد. أذا ركبت نظام وندوز جديد ربما تحتاج ان تشتري مواصفات جديدة. او ركبت دوت نت فريم سوف تلاحظ بطىء بالجهاز. يعني لو لم تغير البرمجيات التى تستخدمها ربما تستطيع ان تستعمل جهازك لمدة اربع سنوات قادمه او اكثر.أذاً هي عملية تسويق كما هو واضح.يعني لنفرض اني مستخدم على قد حالي. يعني لست بخبير . يعني مستخدم يقرا ايميله. يكتب رسالة؟ يستخدم الاوفس . هل يخدمه windows98 واوفس 97نعم بكل تاكيد .
وهذه البرمجيات تعمل بكفائة عالية على اي جهاز سرعتة لنقول 800MZ و120MB
واذا كان جهازك اسرع سوف تحس ان جهازك طيارة.
ولكن السؤال هل هذا هو السبب الرئيسي لدوت نت(التسويق)؟ لا هناك اسباب اخرى لنرى..........أقولكم القصة الثانيه أو السبب الثاني؟ وهو مهم (طبعا وجهة نظر ربما اكون خاطىء ).
ماكروسوف اكتشفت ان أفكار منافسينها هي الصح؟ مثل ماذا؟ مثل فكرة ال Java ، الجافا تستطيع ان تعمل على اي منصة؟ وهي تستخدم نظام الInterpretation لكود. يعني عندما تعمل على منصه وندوز NT فهي تقوم بترجمه البرنامج الى هذه المنصة في وقت التشغيل. هي سيئة لانها تاخذ وقت بالترجمه. أي تحويل من كود الى كود. وهذا يعرف بال Portability
أذا تريد ان تقول دوت نت شبية بفكرة الجافا؟ نعم هذا صحيح. ماكروسوفت تريد ان تضع نظام داخل نظام التشغيل؟ يعني عندما تشتغل تحت دوت نت، البرمجيات المبرمجة بالدوت نت تقوم اول بالتحدث الى الدوت نت فريم ومن ثم يقوم الدوت نت فريم بالتحدث الى نظام الوندوز؟ أليس هذا تشبيه بما يحدث بالجافا؟ انظر الى

The “Framework” operates between business applications and the ًWindows operating system انظر لموضوع

مع ان البرمجيات التى تعمل بدون دوت نت فريم تتحدث مباشرة الى نظام الوندوز. لماذا احتاج ان اتكلم مع نظام ثم ينقلني الى النظام الاخر؟ مع ان التحدث مباشرة اسرع.
ولكن هم يقدمون شي جديد أيضاً .....

The framework also takes advantage of the latest programming techniques (object oriented development) which have been in use by other programming languages such as Java

أهااااا ..... أذا هم سوف يعتمدون بالبرمجه على OOP او ما يعرف ب "البرمجه بغرضيةالتوجية" والتى سبقتهم جافا و بورلاند منذ زمن بعيد.
الفكره الثانية. هي ان ماكروسوف تمشكلت بالDLL يعني برنامج قمت ببرمجتة في VB6 فرضا، انت تحتاج مكتبة VBRUN ليعمل.لو نلاحظ ان بورلاند Delphi ،عندما تقوم ببرمجة برنامج بالدلفي ،انت لا تحتاج اي مكتبة ليعمل برنامجك. كل شي داخل البرنامج.
أليس هذا تفوق لدلفي على vb.أذا مستقبلا عندما تعمل تحت الدوت نت (كمبرمج) لا تحتاج الا ان يكون دوت نت فريم ورك متواجد على جهاز الزبون ليعمل برنامجك.كل المكتبات سوف تكون متواجدة هناك. يعني احتجت لها او لم تحتاج لها كل شي موجود.
طبعا........مستقبلا......سوف تكون الدوت نت فريم ورك متضمن داخل نظام الوندوز. عجبك او لم يعجبك.


ولنا لقاء اخر.........مع السلامة
Xlogic

Delphinized Idea 1 أفكار دلفينية


كيف توقف قائمه النظام في النموذج Form's System menu

كنت افحص احد برامجي التي تعمل تحت multithreading حيث كان هناك عدة نماذج وفي احد النماذج يقوم thread بعرض بعض النتائج وحالة عمل لthread عن طريق دالة التزامن synchronize......كل شي يعمل كما صمم ...جميل ان ترى كل شي يعمل مثل الساعة, تك تك تك


وفجأة عندما ضغطتُ على اسم النموذج عن طريق الفارة يمين وظهرت قائمة النظام. يبداء تأثير أنعكاسي على الthread ويبدا بالتاخر بعرض النتائج وربما يتوقف بالكامل.


وهذا بسبب ان دالة التزامن synchronize تعتمد على عملها بمبداء (الرسائل) messages،وبما ان النموذج في حالة عرض قائمة النظام system menu اذا لوب الرسائل متوقف.


انها مشكلة لم انتبه لها الا من خلال الفحص.

أّذاً ما الحل؟

ربما احد سوف يقول بسيطة...... اوقف عرض القائمة عن طريق []=:borderIconsصحيح ...ولكني انا استعمل bsToolwindow مع زر أغلاق. اي اني اريد النموذج هكذا:

bsToolWindow
Close Button
وبدون biSystemMenu

التجميع او التركيبه هذه لا تعمل مع بعضها . اي لا تستطيع ان تعملها.

الحل الوحيد اللذي استطعت الوصول له هو اني استعمل winproc واعترض الرسالة التى ترسل عندما تضغط على اسم النموذج بزر الفارة يمين. وهي WM_MCRBUTTONDOWN

ومن ثم أقوم بتجاهل هذه الرسالة. حل جميل أليس كذالك؟

بس هناك مشكلة بسيطة؟.....أن جميع الرسائل ترسل الى هذا الروتين ومن ثم تذهب الى الروتين الاصلي اذا كانت الرسالة غير موجودة في winproc (ألاف الرسائل التى ترسلها الوندوز الى البرنامج مثل حركه الفارة على النموذج والضغط على الفارة و و و.............)

أذاً هذا الحل يعمل بس أنا في تصاميمي ابحث عن الاداء ايضاُ؟

ولكن بعد التفكير وجدت حل اخر اسهل . نعم الدلفي بأستطاعتة ان يرسل لك رسالة معينه انت تختارها. مثل WM_NCRBUTTONDOWN


Code








procedure TLogFrm.WMNCRBUTTONDOWN(var message:Tmessage);
begin
with message do
case Msg of
WM_NCRBUTTONDOWN:{Do Nothing};
end;
end;
end;







 
procedure TLogFrm.WMNCRBUTTONDOWN(var message:Tmessage);
begin
{keep this remark}
end;












procedure WMNCRBUTTONDOWN(var message:Tmessage); message WM_NCRBUTTONDOWN;