اذهب الي المحتوي
أوفيسنا
بحث مخصص من جوجل فى أوفيسنا
Custom Search

اجعل برنامجك يعمل على النواتين 32بت و 64بت _ طريقة ثانية


jjafferr

الردود الموصى بها

السلام عليكم 🙂

 

لتعم الفائدة ، رجاء قراءة الطريقة السابقة ، والتي يمكن قراءتها من هنا :

https://www.officena.net/ib/topic/107637-اجعل-برنامجك-يعمل-على-النواتين-32بت-و-64بت/

 

------------------------------------------------------------------------------------------------------------------

 

اذا عملنا برنامج على الاكسس 32بت ، وفيه مكتبات الوندوز الـ 32بت (لاحظ الرقم 32 في اسم المكتبة: comdlg32.dll) ، ثم شغلنا البرنامج على اكسس 64بت ، فنحصل على هذا الخطأ :

image.png.6ad6f86e167bc26b72b08be4dc18c070.png

.

 

للعمل بهذه الطريقة محتاجين الى:

1. ملف في موقع مايكروسوف (مرفق نسخة Win32API_PtrSafe.zip) ، وفيه طريقة عمل مناداة النواتين :

https://www.microsoft.com/en-us/download/details.aspx?id=9970

وعند فك الملف ، سنستعين بالملف Win32API_PtrSafe.TXT ،

2. البرنامج Notepad++ المجاني ، ويمكن انزاله من هنا https://notepad-plus-plus.org

بعد تنصيب البرنامج ++Notepad ، يمكننا فتح الملف Win32API_PtrSafe.TXT به :

 

هذا البرنامج يفهم تنسيق وعمل الكثير من لغات البرمجة ، ومنها VB ، ونستفيد منه حتى في برمجة كود VBE لأنه يفهم تنسيقها:

image.png.5269fd532acf908328522e8b064df467.png

.

 

------------------------------------------------------------------------------------------------------------------

 

سنستخدم المرفق في هذ الرابط لنجعله يعمل على النواتين 32بت و 64بت:

https://www.officena.net/ib/topic/61106-هدية-من-اليمين-الى-اليسار،-مربع-القائمة-listbox-والشجرة-treeview/

 

هذه هي مكتبات 32بت الوندوز المستعمله في المرفق:


Public Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Declare Function InvalidateRect Lib "user32" (ByVal hwnd As Long, lpRect As Long, ByVal bErase As Long) As Long
Public Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
Public Declare Function GetFocus Lib "user32" () As Long

Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long

.

 

خطوات العمل:

A. ننسخ اسم المكتبة GetWindowLong من برنامج الاكسس ،

B. ثم في برنامج ++Notepad ، نبحث عن هذه الكلمة عن طريق Ctrl+F ،

C. فنضع الكلمة مكان البحث ، وننقر على المربع: Find All in Current Document 

image.png.17a8403edcc3bc210f88f34f29378e43.png

.

D. نرى هذ النافذة تُفتح في اسفل البرنامج ،

اهم شيء في هذه النافذه هو ان نفرق بين كلمة البحث التي نريدها ، ونفرقها عن كلمات البحث المشابهه والتي لا علاقة لنا بها

(يجب ملاحظة ان بعض البرامج/الامثلة التي ننزلها من الانترنت ، يكون صاحبها عمل تغيير في اسم المكتبة ، مثلا: بدل GetWindowLong يكون apiGetWindowLong ، فيجب ان نعرف انه نفس الاسم ، ونبحث عن الكلمة الاصل ، كما نلاحظ ان تعديل الاسم يتم من بدايته وليس من نهايته)

image.png.22d5d4de4dde43bdbb732335cb544faa.png

.

E. اذن نرى هنا ان آخر سطرين فيهما طلبنا ،

F. ندقق في السطر ، ونبحث عن اي كلمة تنتهي بـ Ptr ، مثل LongPtr ، CLngPtr ، VarPtr ، ObjPtr ، StrPtr ،

او الكلمات التالية LongLong ، CLngLng ،

فاذا وجدناها ، اذن يجب التصريح لهذه المكتبة في الكود في برنامجنا على سطرين مختلفين ،

السطر الاول للنواة 64 بت ، ونأخذه من برنرنامج ++Notepad ، 

والسطر الثاني للنواة 32 بت ، ونأخذه من برنامجنا الاصل ، هكذا :

#If VBA7 And Win64 Then
	'64 bits
  Public Declare PtrSafe Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As LongPtr, ByVal nIndex As Long) As Long

#Else
	'32 bits
  Public Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long

#End If

.

*** الخطوة الاولى والاهم هي اضافة كلمة PtrSafe بعد كلمة Declare ، للنواة 64بت.

*** لاحظ اننا اضفنا كلمة Public في اول السطر للنواتين ،

*** وبعد كل خطوة نعملها ، يجب ان نعمل Compile :على الاكسس 32 بت والاكسس 64 بت :حتى نتأكد انه لا توجد اخطاء

 image.png.bae9e55307fea507b0138a3998624a3f.png

 

 

 

ونتبع نفس الخطوات اعلاه لبقية المكتبات ،

المكتبة التاليه: SetWindowLong ، والنتيجة نفسها مثل المكتبة السابقة ، اذن الكود اصبح

#If VBA7 And Win64 Then
	'64 bits
  Public Declare PtrSafe Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As LongPtr, ByVal nIndex As Long) As Long
  Public Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long

#Else
	'32 bits
  Public Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
  Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long

#End If

.

 

وهكذا مع بقية المكتبات ، فيكون الكود النهائي:

#If VBA7 And Win64 Then
	'64 bits
  Public Declare PtrSafe Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As LongPtr, ByVal nIndex As Long) As Long
  Public Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
  Public Declare PtrSafe Function InvalidateRect Lib "user32" Alias "InvalidateRect" (ByVal hwnd As LongPtr, lpRect As Long, ByVal bErase As Long) As Long
  Public Declare PtrSafe Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As LongPtr, ByVal hWnd2 As LongPtr, ByVal lpsz1 As String, ByVal lpsz2 As String) As LongPtr
  Public Declare PtrSafe Function GetFocus Lib "user32" Alias "GetFocus" () As LongPtr
  Public Declare PtrSafe Function GetWindow Lib "user32" Alias "GetWindow" (ByVal hwnd As LongPtr, ByVal wCmd As Long) As LongPtr
#Else
	'32 bits
  Public Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
  Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
  Public Declare Function InvalidateRect Lib "user32" (ByVal hwnd As Long, lpRect As Long, ByVal bErase As Long) As Long
  Public Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
  Public Declare Function GetFocus Lib "user32" () As Long
  Public Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long
#End If

.

 

 

 

الآن لنفترض ان لدينا هذه المكتبة كذلك:

Public Declare Sub Sleep Lib "kernel32" (ByVal lngMilliSeconds As Long)

.

نلاحظ في البحث انه لا توجد لدينا اي من كلمات التي ذكرناها في #F اعلاه

image.png.8277fba6cb9de22d4a6324bb8dc13fa1.png

.

اذن نكتب السطر (من برنامجنا ذو 32 بت) نفسه مرتين ، مرة للنواة 64 بت ، ومرة للنواة 32 بت ، فيصبح الكود (الفرق بين السطرين هي كلمة PtrSafe) :

#If VBA7 And Win64 Then
	'64 bits
  Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal lngMilliSeconds As Long)
#Else
	'32 bits
  Public Declare Sub Sleep Lib "kernel32" (ByVal lngMilliSeconds As Long)
#End If

  
او

#If VBA7 And Win64 Then
	'64 bits
  Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal lngMilliSeconds As Long)
#Else
	'32 bits
  Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal lngMilliSeconds As Long)
#End If
  
  
او سطر واحد مستقلا
  Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal lngMilliSeconds As Long)

 

------------------------------------------------------------------------------------------------------------------

 

2021-11-20 :

اخوي @عبدالله المجرب نبهني عند استخدام الاكسس 64بت ، يظهور خطأ في مرفق الرابط:

https://www.officena.net/ib/topic/64989-هدية-برنامج-تصدير-بيانات-من-جداولاستعلامات-اكسس-الى-اكسل-،-32بت-و-64بت/

 

لما نعمل Compile للبرنامج على كمبيوتر به اكسس 64بت ، تظهر هذه الرسالة ، واللي معناها مافي توافق في تعريف المتغير (يعني جزء من سطر الكود تم تعريفه بطريقة ، وجزء آخر من سطر الكود تم تعريفه بطريقة لا تتلائم مع المتغير السابق ، وابسط مثال: متغير تم تعريفه كنص ، ثم تعطي قيمته الى متغير آخر تم تعريفه كرقم) :

7.Clipboard01.jpg.09d12ee4f50507af994370135decfe85.jpg

.

من الملاحظة ، نرى انه بما اننا نستخدم اكسس 64بت ، فتعريف المكتبة ShellExecute يكون عن طريق (VB7) ، وتعريفها انها LongPtr ،

بينما في الكود ، اعطينا قيمة ShellExecute الى المتغير lRet والذي تم تعريفه على انه Long ، لهذا السبب لا يوجد توافق بين المتغيرين ، وعليه نحصل على الخطأ !!

هناك حلين للموضوع:

إما ان نعمل if VBA7 then# خاص للمتغير lRet لحالتي 32بت و 64بت ،

او نحذف تعريف المتغير lRet من الكود ، ونضعه في الاعلى ، مع تعريف المكتبة ShellExecute ، وهذا ما قمت به:

7.Clipboard02.jpg.1640119074df05a83928f56b35e5187a.jpg

.

 

وبعد عمل Comiple مرة اخرى ، نحصل على خطأ مشابه للخطأ اعلاه ، ولكن لمكتبة اخرى :

7.Clipboard03.jpg.17f7ee87c90260ed834ad044c8af8cb7.jpg

.

والحل ، كما عملته للمشكلة السابقة ، فيصبح الكود :

7.Clipboard04.jpg.7b045ec2ab80403f7545a8b4b827e69c.jpg

.

وبعد عمل Compile مرة اخرى ، نجد ان الكود يعمل بدون اخطاء 🙂

------------------------------------------------------------------------------------------------------------------

2021-11-23:

اخوي @ابا جودى طلب مساعدة في برنامجه ، ليعمل على النواتين:

https://www.officena.net/ib/topic/111963-سؤال-بخصوص-التعديل-على-قاعدة-بيانات-لتعمل-على-32-64-bit/

 

والشيء الجديد فيه والذي لم يتم شرحه سابقا هو:

المتغير hIcon (باللون الاصفر) ، تعريفه يعتمد على النواة :

image.png.99155b7948b07e9bbe4c289c714a7415.png

.

وعندنا هذه الدالة fSetIcon ومعرفها Long ،

وفي الدالة ، نعطي نتيجة hIcon الى fSetIcon 

image.png.56feff9a6cceb47a4dd2a9901c9f0ff9.png

.

المشكلة لما نواة البرنامج تكون 64بت ، فحينها يكون معرف الحقل hIcon هو LongPtr ، بينما الدالة fSetIcon لا يزال معرفها Long ، وهنا نحصل على رسالة خطأ بعدم تطابق معرف الحقلين !!

 

والطريقة التي استعملتها هي:

استعمال الدالة مرتين ، مرة بمعرف LongPtr اذا كانت النواة 64بت ، ومرة بمعرف Long اذا لم تكن النواة 64بت :

image.png.16b2294d7802cc5790eb7ee2406672b0.png

.

وعلشان نعرف ان البرنامج تقبل هذا التغيير ، يجب ان نعمل Compile 🙂
 

جعفر

 

Win32API_PtrSafe (2).zip

  • Like 7
  • Thanks 2
رابط هذا التعليق
شارك

استاذ جعفر شكرا على عرض هذا الموضوع الهام 

تواجهنا عند التطبيق عدد من المشكلات في جعل البرنامج يعمل على النواتين وخصوصا اذا كان البرنامج مليء بالاكواد 

 

مثال على ذلك 

استخدمت ملفك (تصدير الجداول والاستعلامات الى اكسل )

 

في الموضوع الخاص بك  لا استطيع تحميل المرفق كونك ذاكر انه يعمل على النواتين

 

-------------------------------------------------------------------------------------------------------

 

 

فيه فورم للتصدير الى الاكسل بعدد من الخيارات ((طبعا انا استخدمت ملف من مشاركة ابو الا 

 

 

استخدمت الطريقة المذكورة في المشاركة في التعديل لكن لم يعمل الكود الخاص بتحديد مسار ملف الاكسل

ولكن بحثت ووجدت دالة تقوم بالعمل المطلوب ولكن ٦٤ بت 

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

طبعا ان

 

رابط هذا التعليق
شارك

سلمت استاذي الغالي 

تمت التجربة على النواتين وعمل الملف بشكل صحيح 

 

 

ملاحظة في نسخة ٦٤ يعطي لون احمر على جزئية الكود الخاص ب ٣٢ فهل ذلك يسبب مشكلة 

رابط هذا التعليق
شارك

أستاذي الجليل ومعلمي القديـر و والدى الحبيب أستاذ @jjafferr :fff:

تحية طيبة ..

جزاكم الله خيرا على الشرح الوافي الكافي والمفصل وشكر الله لكم على تقديم العون والجهد المبذول في  هذا الموضوع المهم 

رجاء تثبيت الموضوع لأهميته..

الشرح به تفاصيل كثيرة ولن يتم فهمها وحفظها والتعامل معها كما ينبغي من المرة الأولى

وأعتقد سوف يكون الموضوع مرجع مهم باستمرار لمن يريد التعامل مع دوال الـ API  لتعمل عي كلتا النواتين الـ 23 , 64 

رابط هذا التعليق
شارك

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

زائر
اضف رد علي هذا الموضوع....

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • تصفح هذا الموضوع مؤخراً   0 اعضاء متواجدين الان

    • لايوجد اعضاء مسجلون يتصفحون هذه الصفحه
×
×
  • اضف...

Important Information