الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

رفع حدث بكلاس موديول من خلال موديول !

مغلق
بدأه msayed2004 في 8 مايو 2007 · 22 رد · 1,617 مشاهدة · في لغة Ms Visual Basic 6 وما قبلها من إصدارات
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم و رحمة الله و بركاته

النهاردة معايا لكم سؤال غريب :wacko: و عجيب :blink: و غبى :s و أتمنى انى الاقيله حل

لو عندى Class Module بها حدث ما و عايز اطلق الحدث ده (RaiseEvent) لكن المشكلة ان الكود بتاعى فيه AddressOf و بالتالى محتاج لـ Module فالسؤال أزاى من خلال الـ Module أقدر أوصل للحدث ؟

منطقيا هنعمل كده :

فى الـ Class :

Option Explicit
Public Event DestroyMyPC()

Friend Sub RaiseMyEvent()
RaiseEvent DestroyMyPC
End Sub

و بالـ Module :

Option Explicit

Public Sub Gooo()

Dim myMind As Class1
myMind.RaiseMyEvent

End Sub

نرجع للـ Class و نحط :

Private Sub Class_Initialize()
Gooo
End Sub

و فى Form :

Option Explicit
Private WithEvents Blah As Class1

Private Sub Form_Load()
Set Blah = New Class1
End Sub

Private Sub Blah_DestroyMyPC()
MsgBox "Done"
End Sub

هيطلع Error رقم 91 , Object variable or With block variable not set

عملت بحث بالنت و وصلت للكلمة دى :

اقتباس
The error 'Object variable or With block variable not set' is occured where you are using an object without allocating memory for it.

بس أزاى أعمل كده ؟

و لو فيه طريقة تانية فياريت حد يقولها , ده لو حد فهم منى حاجة أساسا :P !

تعديل : و لا تنسوا شوية فزعة يا رجال :lol: .

و عليكم السلام و رحمة الله و بركاته

تم تعديل هذه المشاركة بواسطة msayed2004 في 8 مايو 2007 في 18:01

#2

هو صحيح انا مفهمتش منك حاجة لكن باين من الحدث DestroyMyPc انه مهم جدا

لكن انا لسة جاى هقيل ساعتين وابحث القضية مع الوزراء بتوعى

سلاااااااااااااااااااااااااااااااااااااااااام

موقع البرنامج

مبارك لشعب تونس photo-thumb-42837.png

#3

يا راجل قول كلام غير ده عايز تدمر الجهاز :s

علي العموم جاري البحث و التدقيق

سبحان الله وبحمده عدد خلقه ورضا نفسه وزنة عرشه ومداد كلماته

#4

الأخ الفاضل ...

هناك مشكلتين ، الاولى هى أنك نسيت New فى تعريف myMindفى الـ Module لذا أستخدم

	Dim myMind As New Class1

أو

	Dim myMind As Class1

	myMind = New Class1

بدلاً من

	Dim myMind As Class1

الثانية وهى خطأ منطقى ، الدخول فى حلقة تكرارية، وتحدث كالتالى عند تحميل الـ Form فيتم تنفيذ الحدث Form_Load وبالتالى تعريف Class جديده بالكود

	Set Blah = New Class1

مما سيؤدى إلى تنفيذ Initialize فى الـ Class الذى سيستدعى Gooo فى الـ Module والذى بدوره سينفذ New Class1 فيتم استدعاء Initialize فى الـ Class و..... هكذا إلى أن تمتلئ الـ Stack ويعطى رسالة خطأ.

لذا جرب أستخدام التالى ، أتمنى أن يفيدك

فى الـ Class

Option Explicit

Public Event DestroyMyPC()

Friend Sub RaiseMyEvent()
	RaiseEvent DestroyMyPC
End Sub

فى الـ Module

Option Explicit

Public Sub Gooo(myMind As Class1)
	myMind.RaiseMyEvent
End Sub

فى الـForm

Option Explicit

Private WithEvents Blah As Class1

Private Sub Form_Load()
	Set Blah = New Class1
	Call Gooo(Blah)
End Sub

Private Sub Blah_DestroyMyPC()
	MsgBox "Done"
End Sub

شكراً

Eng. Usama El-Mokadem

Nothing is impossible, the word impossible itself says that: I M - Possible

#5

السلام عليكم و رحمة الله و بركاته

أشكرك جدا لكن أنا بصدد عمل DLL و الموديول ستكون جزء منه و هو اللى بيتعامل معاها فقط و فى الفورم ( بمشروع آخر مضاف ايه الـ DLL ) سأتعامل فقط مع الكلاس الأساسية لكن بالطريقة دى ( مع العلم أنها نجحت ) سيكون وجود الكلاس لا معنى له و بالتالى لا DLL

#6

محمد انا حليت المشكلة بطريقة مختلفة ارجوا انها تنفع

فى الموديول

Option Explicit
Public Cancel As Boolean

Public Sub Gooo()
If Not Cancel Then

	Dim myMind As New Class1
	myMind.RaiseMyEvent
End If
End Sub

والجديد انه تم تعريف متغير بولينى Cancel اذا كانت قيمته True لن يتم تنفيذ الاجراء Gooo

Option Explicit
Public Event DestroyMyPC()

Friend Sub RaiseMyEvent()
RaiseEvent DestroyMyPC
End Sub
Private Sub Class_Initialize()
 Cancel = True
Gooo
End Sub

تانى حاجة فى الكلاس Class_inialize بعد التنفيذ يتم جعل قيمة ال Cancel = true وبذالك نضمن تنفيذ ال Gooo مرة واحدة ولن يحدث الخطا الذى قال عليه المهندس اسامة

اما الفورم كما هى

Option Explicit
Private WithEvents Blah As Class1

Private Sub Form_Load()
Set Blah = New Class1
End Sub

Private Sub Blah_DestroyMyPC()
MsgBox "Done"
End Sub

ارجوا ان ينفعك وربنا معاك فى الى بتعمله مش عارف مش مطمن ليه

والسلام عليكم ورحمة الله وبركاته

موقع البرنامج

مبارك لشعب تونس photo-thumb-42837.png

#7

شكرا بس هيحصل نفس اللى قال عليه المهندس أسامة :

اقتباس
مما سيؤدى إلى تنفيذ Initialize فى الـ Class الذى سيستدعى Gooo فى الـ Module والذى بدوره سينفذ New Class1 فيتم استدعاء Initialize فى الـ Class و..... هكذا إلى أن تمتلئ الـ Stack ويعطى رسالة خطأ.
#8

انت بترد من غير ما تجرب :angry:

المشكلة مش فى الخطا out of stack لكن ان الحدث لا يتم استدعائمة على الرغم من استدعائ الاجراء myMind.RaiseMyEvent

فهحاول اشوف ليه

موقع البرنامج

مبارك لشعب تونس photo-thumb-42837.png

#9

يا سيدى أنا جربت على العموم أنا هحاول أستخدم الـ zAddressOf اللى فى الـ Self Sub على أساسا أنها بتنفع من أى حته ( Module أو Class أو Form أو Usercontrol )

و شكرا ليكم على المحاولة.

تم تعديل هذه المشاركة بواسطة msayed2004 في 8 مايو 2007 في 22:22

#10

فى حاجة مهمه

الخطا out of stack تم التغلب عليه

لكن حتى لو وضعت raisemyevent مباشرا فى ال Class_Inialize لن يتم عرض الرساله الموجودة بالحدث فى الفورم والسبب ان اكلاس ما هى الا نسخة من الاوامر يتم بناء كائن عليها وياخذ كل الاجرائات وكل شئ بداخلها لذلك يجب على ال Object فى حالتنا Blah(مش عارف معناها ايه) انه هو من يعمل Firing لل Event وليس الكلاس بوجه عام

وانا حاولت ان اعمل شئ غبى

وضعت هذا فى الكلاس

Public Sub f(s As Variant)
	s.RaiseMyEvent
End Sub

وهو اجراء ياخذ برامتر من النوع Vaiant ليقوم باطلاق الحدث

وفى الفورم لود

اقتباس
Set Blah = New Class1

Blah.f (Blah)

وامرر لهذا الاجراء الاوبجكت Blah

يقوم بجعله هو من يعمل اطلاق للحدث

ولكن كالعاده(الفشل) ظهرت الرسالة

'438' Run time error

object doesn't support this property or method

موقع البرنامج

مبارك لشعب تونس photo-thumb-42837.png

#11

مشكلتك طبيعية اخي العزيز لماذا ؟

في ال OOP كل كائن نقوم بانشاءه فهو كائن قائم بذاته يعني انت انشأت كائنين Mymind و Blah و اردت من خلال الأول ان تطلق الحدث لينفذ من طرف الثاني ؟؟؟؟ و هذا غير ممكن

لذا فلا يمكنك المرور من موديل من اجل تنفيذ حدث لكائن آخر عن طريق انشاء كائن جديد (كأنك تقول لأحمد ان يركض و تنتظر من خليل ان يفعل ذلك ايضا!)

و لأني لا اعرف مشكلتك بالتفصيل و لما بالتحديد تريد المرور من موديل (أتمنى ان توضح الامر اكثر او ترفق مثال) فالحل يا أخي يبقى ان تضع الحدث داخل Sub او Function او Property و من ثم مناداتها لاطلاق الحدث او اطلاق الحدث مباشرة عبر المناداة عليه

---------

تم تعديل هذه المشاركة بواسطة Ayoub JAMAL EL IDRISSI في 9 مايو 2007 في 00:32

#12
اقتباس
مشكلتك طبيعية اخي العزيز لماذا ؟
أعلم و أبحث عن حل للألتفاف حولها.
اقتباس
لذا فلا يمكنك المرور من موديل من اجل تنفيذ حدث لكائن آخر
أكيد ربنا يخليلنا MS
اقتباس
لما بالتحديد تريد المرور من موديل
كما ذكرت أنا أستعمل AddressOf و بالتالى يجب أن أستعمل Module ( مع الأسف )
اقتباس
فالحل يا أخي يبقى ان تضع الحدث داخل Sub
حاولت راجع الـ Sub المسمى RaiseMyEvent
اقتباس
او اطلاق الحدث مباشرة عبر المناداة عليه
مش ممكن بسبب
اقتباس
لذا فلا يمكنك المرور من موديل من اجل تنفيذ حدث لكائن آخر

أنا أحاول بطريقة أخرى الآن.

شكرا لك أخى الكريم.

تم تعديل هذه المشاركة بواسطة msayed2004 في 9 مايو 2007 في 00:39

#13

و هل ال AddressOf في ال VB6 لا تقبل الى ال Modules ؟؟

و ياريت لو تقول لنا اين و كيف تستعمل ال AdrdressOf حتى نحاول ايجاد الحل او الالتفاف عليها ذاتها لعدم استعمالها :)

#14

انظر اخ ايوب انا حاولت فى المشاركة اسابقة بعمل تمرير للكائن الموجود فى الفورم Blah الى الكائن الاخر الموجود فى الموديول لعمل اجراء يجعل الكائن Blah يستدعى الحدث عن طريق اى اجراء اخر

لكن ظهرت رسالة خطا كتبتها فى المشاركة السابقة

موقع البرنامج

مبارك لشعب تونس photo-thumb-42837.png

#15

أخى أيوب نعم فى الـ VB 6 الوظيفة المشار أليها بـ AddressOf يجب أن تكون بـ Module و ألا سنحصل على خطأ ( Invalid use of AddressOf operator ) راجع مثلا : SetTimer = Invalid use of AddressOf operator

#16
اقتباس
و هل ال AddressOf في ال VB6 لا تقبل الى ال Modules ؟؟

و ياريت لو تقول لنا اين و كيف تستعمل ال AdrdressOf حتى نحاول ايجاد الحل او الالتفاف عليها ذاتها لعدم استعمالها

للاسف فعلا ال Addressof فى الفى بى 6 لا تقبل الا بالاجرائات الموجودة فى الموديول لماذا الله اعلم

وكان البرانج الفرعية ال Private ليس لها عنوان!!!!!!!!!!!!!!!

موقع البرنامج

مبارك لشعب تونس photo-thumb-42837.png

#17

حتى لو اشتغل هذا الكود :

Blah.f (Blah)

و لن يشتغل لأنه لا يمكنك في الفيجوال 6 تمرير كائن Class كبارامتر

فسيكون مساويا لهذا :

Blah.RaiseMyEvent

لأنك كما ذكرت حتى لو نجح الامر فلا تفعل سوى تمرير الكائن نفسه لنفسه ثم تطلق الحدث !!

#18
اقتباس
و لن يشتغل لأنه لا يمكنك في الفيجوال 6 تمرير كائن Class كبارامتر

فى الفيجوال بيسك 6 يمكن تمريمر كائن كبرامتر ساضع مثال

هذا المثال نقوم بتمرير الكائن فورم الى الاجراء ليقوم بتغيير خاصية الكابشن له

Object___parameters.zip

موقع البرنامج

مبارك لشعب تونس photo-thumb-42837.png

#19

شباب أعتقد أنها معمولة فعلا بـ APIs_Timer لكن مش فاهمها , ممكن حد فايق و مركز يشوفها لى ؟!

و أكون شاكر.

تم تعديل هذه المشاركة بواسطة msayed2004 في 9 مايو 2007 في 01:06

#20

أخ حريف برمجة

معك حق و مثالك الذي ذكرت سابقا يمكن ان يشتغل غير فقط ال Friend الى الPublic لل Sub المسماة RaiseMyEvent

#21

حتى هذه الطريقة اخ ايوب لن تنفع

انا ابحث الان عن طريقة اجد بها الكائن الذى بنى على هذا ال Class

موقع البرنامج

مبارك لشعب تونس photo-thumb-42837.png

#22

على العموم يا جماعة زى ما قلتلكم هى عمليه بحث عن كائن

فى المثال الى بعثه محمد بتاع التيمر

فى اوله تم تعريف كائن على الكلاس collection وقد استنتجت انه خاص بالفى بى 6 يحمل بيانات جميع الكائنات المعرفه فى البرنامج

Private mcolItems As Collection

وكما قلت سابقا فالمفتاح ياتى عندما نجد الكائن المستهدف الذى بنى على الكلاس ويجب تنفيز الحدث عنده

ففى الاجراء التالى فى المثال

Public Sub Timer_CBK(ByVal hWnd As Long, ByVal uMsg As Long, ByVal idEvent As Long, ByVal SysTime As Long)
Dim lngPointer  As Long
Dim objTimer	As APITimer
On Error GoTo ErrHandler
	lngPointer = mcolItems.Item(idEvent & "K")
	Set objTimer = PtrObj(lngPointer)
	objTimer.RaiseTimerEvent
	Set objTimer = Nothing
	Exit Sub
ErrHandler:

End Sub

قد استخد الكائن الذى عرفناه فى الاول وحصل منه على pointer من الواضح ان له علاقة بالكائن المراد البحث عنه

وقد استخدم دالة PtrObj هى تقوم بارجاع الكائن باعطائها المؤشر وينفذ هذا فى الكود

 Set objTimer = PtrObj(lngPointer)

اما عن البقي فسهل لانه وجد الكائن وبذلك يستطيع ان يلعب به كما يشاء

ناتى لدالة PtrObj

هذة الداله غير موجودة مع ال فى بى

وهذه هى

Private Function PtrObj(ByVal Pointer As Long) As Object
Dim objObject   As Object
	CopyMemory objObject, Pointer, 4&
	Set PtrObj = objObject
	CopyMemory objObject, 0&, 4&
End Function

بتمرير المؤشر لها تقوم بنسخ الذاكرة عند هذا المؤشر ووضعه فى ال ObjObject ثم ارجاعه فى الداله

اما النسخ الثانى فيبدو كانه تصفير

انا حتى الان لم اجرب بيدى ما هى الا استنتاجات ومن الارجح ان انا مش هجرب لان فاضل 2 اسبوع على امتحاناتى

الكلام ده منفد على تجميع شويه

محمد والاخ ايوب والمهندس اسامه اكيد هيوصلولها

سلام بقى عشان انا رايح انااااااااااااااااااااااااااااام

موقع البرنامج

مبارك لشعب تونس photo-thumb-42837.png

#23

شكرا يا أحمد بس أنا لسه مش فاهم الطريقة دى قوى , أتمنى حد يبسطها شوية , شكرا.

هذا الموضوع مغلق.

مواضيع مشابهة