PDA

توجه ! این یک نسخه آرشیو شده می باشد و در این حالت شما عکسی را مشاهده نمی کنید برای مشاهده کامل متن و عکسها بر روی لینک مقابل کلیک کنید : نكاتي مهم براي كار با برنامه دلفي



Borna66
03-21-2009, 01:58 AM
دلفي و اسمبلي


برنامه نويسان دوران DOS با tasm.exe و tlink.exe آشنايي دارند.ايندو از ديرباز رقيبان masm.exe و link.exe بوده و هستند.بله tasm و برادركوچكش tlink از اولين ابزارهاي برنامه نويسان حرفه اي هستند.اما بعد از ظهور Turbo Pascal ، Turbo C/C++ و متعاقبا كامپايلر هاي تحت ويندوز ، كم كم محبوبيت خود را از دست دادند.هم اكنون كمتر صحبتي در مورد اين افسانه هاي قديمي پردازنده هاي x86 ميشود.

آيا اين نشانه مرگ tasm است؟

آيا ميدانيد هر بار كه Delphi يا C++Builder را نصب ميكنيد ، نمونه 32 بيتي اين اسمبلر باوفا نيز ميهمان ديسك سخت شما ميشود؟

آيا ميدانيد مهمترين بخشهاي VCL توسط اسمبلي و tasm32.exe نوشته شده است؟

آيا مي خواهيد روش استفاده از tasm در Delphi را ياد بگيريد؟

اگر جواب شما به سوال آخر بله است ، با من همراه شويد تا يك برنامه كاملا ابتدايي و آموزشي با تركيب قدرت tasm و Delphi بسازيم.اگر جواب شما به سوال آخر خير است لطفا موس خود را به سمت گوشه بالا و راست اين پنجره برده و روي آن دكمه ضربدري شكل كليك كنيد!

چه كساني ميتوانند از اين مقاله استفاده كنند؟
قبل از هر چيز خواننده بايد با دستورات اسمبلي آشنا باشد.با يك جستجوي ساده در اينترنت ميتوانيد به مقالات آموزشي زيادي دسترسي پيدا كنيد.
آشنايي با نحوه پياده سازي ويندوز نيز كمك زيادي بشما خواهد كرد اما براي استفاده اين مقاله لازم نيست.در اين مورد، شايد مقاله ديگر من بنام "اسمبلي تحت ويندوز" بتواند بشما كمك كند.

آستينها رابالا بزنيد!!
برنامه اي كه خواهيم ساخت كار بسيار ساده اي انجام ميدهد.
اين برنامه يك Message box را نمايش داده كه داراي دو كليد OK و Cancel است.هر كدام از اين كليد ها كه click شوند توسط يك Message box ديگر به كاربر گزارش داده ميشود.

براي شروع يك فايل با پسوند dpr ساخته و كد زير را در آن كپي كنيد:



program DelphiAsm;
uses windows;

var
Title :PChar = 'Inline assembly with Reza'#0;//bar hasbeh adat!!
Mes1 : PChar = 'Please press one of the following buttons!!'#0;
Mes2 : PChar = 'You pressed OK button!!'#0;
Mes3 : PChar = 'You pressed Cancel button!!'#0;

label
PRINTPROC;

begin
asm
push 1
push Title
push Mes1
push 0
call MessageBoxA
cmp eax , IDOK
je PRINTPROC
push Mes3
pop Mes2

PRINTPROC:
push 0
push Title
push Mes2
push 0
call MessageBoxA

mov eax,0
call ExitProcess
end;
end.


نكته:در دلفي براي نوشتن دستورات اسمبلي از بلوك asm … end; استفاده ميشود.

قبل از هر چيز به نحوه تعريف يك ليبل توسط كلمه كليديمLabel توجه كنيد.چه در tasm و چه در masm احتياجي به اعلان كردن ليبل ها نداريد ولي از آنجايي كه Delphi يك كامپايلر است و قوانين خواص خود را دارد ، قبل از استفاده از هر ليبل بايد آنرا اعلان كنيد.

نكته دوم مسئله calling convention است.بايد بدانيد كه Delphi از روش Fastcall براي فراخواني توابع خود استفاده ميكند ولي windows از روش stdcall بهره ميبرد.

Stdcall يعني آرگومانها را از چپ به راست در پشته قرار مي گيرند و callee (فراخوانده) مسئول pop كردن آرگومانها است.(براي اطلاعات بيشتر در مورد انواع calling convention ها به MSDN يا مقاله ديگر من بنام "اسمبلي تحت ويندوز" مراجعه كنيد.)

براي يافتن Prototype اولين تابع مورد استفاده نگاهي به MSDN بيندازيد و تابع MessageBox (و نه MessageBoxA يا MessageBoxW) را search كنيد :


int MessageBox(
HWND hWnd, // handle to owner window
LPCTSTR lpText, // text in message box
LPCTSTR lpCaption, // message box title
UINT uType // message box style
);

اكنون ميدانيد كه
1.Prototype تابع MessageBox چيست.
2.calling convention استاندارد يا stdcall چگونه عمل ميكند.

پس دست بكار شده و آرگومانها را از چپ به راست در stack بچپانيد!! سپس تابع MessageBox را فراخواني كنيد.

همانطور كه در Prototype تابع MessageBox ميبينيد مقدار بازگشتي آن يك Integer است كه نشان دهده دكمه كليك شده در Message box است.

نكته مهم:
توابع stdcall مقدار بازگشتي خود را در eax قرار ميدهند.

آقا يادم رفت بگم ، اسامي چون IDOK, IDCANCEL, MessageBox و... در يونيت windows اعلان شده اند.

پس تا اينجا موفق شديم يك MessageBox با متن
Please press one of the following buttons!! نمايش دهيم .بر اساس مقدار بازگشتي اين تابع تشخيص ميدهيم كه كدام دكمه(button) كليك شده است و با يك جابجايي ساده و بدون توليد كد اضافي پيام مناسب را توسط يك Message box ديگر به كاربر نمايش ميدهيم.حتما ميدانيد كه متغييري از نوع رشته در ويندوز ، يك اشاره گر به اولين كاراكتر آن رشته است.(علت اين است كه windows بوسيله زبان C پياده سازي شده است.)

در انتها نيز با فراخواني ExitProcess تمامي thread هاي فعال (كه در اين برنامه يكي بيشتر نيست!!) بسته ميشوند ، هر چند كه انجام اين كار ضروري نيست، دلفي كد لازم را توليد خواهد كرد.مي توانيد دو خط آخر را حذف كنيد و نتيجه كار را ببينيد.

در اين برنامه براي ساده كردن كار از VCL كه نقطه عطف Delphi است استفاده نكرديم اما شما ميتوانيد در برنامه هاي عادي خود VCL و اسمبلي را باهم بكار گرفته و برنامه هايي با بازدهي بسيار بالا بسازيد.از حالا به بعد اگر شنيديد كه :"آره بابا با دلفي نميشه فلان كارو انجام داد ، بايد با اسمبلي كد بنويسي" ميدانيد چه جوابي بدهيد.
:104::282::238::109::72:
گردآونده:طه-Borna66

Borna66
03-21-2009, 01:58 AM
محيط دلفي براي برنامه نويسي يكي از بهترين محيطهاي برنامه نويسي است گذشته از كاركرد داخلي و كمپايلر آن كه بسيار قوي و سريع است، محيط آن يعني IDE آنهم قدرت بسيار زيادي دارد كه باعث شده يكي از بهترين اديتورها باشد. در اين مقاله من سعي بر اين داشته ام تا با ارائه يك سري از نكات و كليدهاي ميانبر كه مي توانند براي كار در دلفي بسيار مفيد و كارا باشند، كمك كنم تا شما بتوانيد با قدرت بيشتر به برنامه نويسي و كار در اين محيط قدرتمند ادامه دهيد.
در قسمت اول مقاله كه در حال حاضر در مقابل شماست من يك سري از كليدهاي ميانبر و تركيبي مورد استفاده در IDE دلفي را بصورت ليست وار و همراه يك توضيح كوچك آورده ام. با توجه به اينكه اين مطالب حاصل تجربه هاي خودم در كار با دلفي (از 1 تا 7) بوده ممكنه كه يك سري موارد ديگري هم باشد كه من تا حالا برخورد نداشتم كه دوستان عزيز ميتونند به اين ليست اضافه كنند و نام خود را در انتهاي اين مقاله ذكر كنند و حتما يك نسخه از آن را براي من ارسال كنند.
اميدوارم كه اين سري مقالات با كمك شما در اثر مرور زمان بهتر و مفيد تر شود.
دوستان عزيز برنامه نويس ممكنه كه شما مدتها با دلفي مشغول برنامه نويسي بوده باشيد اما من يقين دارم كه در اين ليست نكات و روشهاي جديدي را خواهيد آموخت.

قسمت اول - كليدهاي ميانبر و تركيبي:

جستجو در متن بصورت مستقيم:
براي اينكار كليدهاي Ctrl+E را بفشاريد و بدنبال آن شروع به تايپ كلمه مورد نظر كنيد نتيجه آن را خود ببينيد. براي اينكه به كلمه بعدي برويد كافيست كليد F3 را بزنيد.

ايجاد فرورفتگي در كد:
بعضي اوقات - كه خيلي هم پيش مي‌آيد - لازم است كه يك مقداري از متن را بصورت بلوك شده به جلو و يا عقب ببريم. منظور دندانه دار كردن متن است كه به خوانايي برنامه كمك مي كند. براي اينكار مي تونيد از كليد Ctrl +Shift+I براي جلو بردن و Ctrl+Shift+U براي عقب برگرداندن متن بلوك شده استفاده كنيد.

پرش به قسمت تعريف يك شي (Object):
براي اينكه ببنيد شي مورد نظرتون (از قبيل VCL, Procedure, Function,...) در كجا و چطور تعريف شده مي توانيد كليد Crtl رو پايين نگه داشته و روي شي مورد نظر Click كنيد.

براي تغيير حالت كاراكترها:
شما مي توانيد يك قسمت از متن (كه ممكن است با حروف بزرگ و يا كوچك تايپ شده باشد) را انتخاب كنيد و با زدن كليدهاي Ctrl+o+u به ترتيب تمامي حروف كوچك آن قسمت از متن را به حروف بزرگ و تمامي حروف بزرگ آنرا به حروف كوچك تبديل كنيد.
براي تعيير حالت يك كلمه نيز ميتوانيد روي كلمه مورد نظر رفته و كليدهاي Ctrl+k+f براي بزرگ كردن و كليدهاي ctrl+k+e را براي كوچك كردن حروف آن كلمه بكار برد.

درست كردن ماكرو متني:
اين امكان بسيار مفيد است و مي توانيد بسياري از كارهاي نوشتاري را كاهش دهد با اينكار شما ميتوانيد يك سري از كارهاي تكراري كه روي متون انجام مي دهيد را بصورت ماكرو در آورده و از آنها به راحتي استفاده كنيد. براي شروع به ضبط ماكرو كليدهاي ctrl+shift+r را بفشاريد و آن سري كارهايي را كه مي خواهيد را انجام دهيد و سپس براي اينكه به كار ضبط ماكرو پايان دهيد كليدهاي ctrl+shift+r را دوباره بزنيد. حال براي استفاده از ماكرو كافيست در هر جا كه لازم بود كليدهاي Ctrl+Shift+P را بفشاريد.

انتخاب متن بصورت مربعي:
اگر شما از كهنه كارهاي كامپيوتر باشيد حتما از زمان داس يادتون هست كه برنامه اي بود به نام PE2 كه يكي از امكانات بسيار جالبش اين بود كه يك مربع از متن رو ميتوانستين انتخاب
كنيد و آنرا كپي يا حذف كنيد. بله درست متوجه شديد در محيط دلفي هم شما اينكار را ميتوانيد انجام دهيد اما نه به مشكلي PE2 بلكه اينكار را ميتوانيد فقط با گرفتن كليد Alt و كشيدن
موس روي متن انجام دهيد. هر چند ممكن است در نگاه اول زياد اين امكان مفيد به نظر نيايد ولي بعضي وقتهاي خيلي كار را راحت ميكنه، كه حتماً تجربه خواهيد كرد.


گذاشتن علامت روي متن:
اين كار كه به BookMark معروف است بسيار مفيد و كارا مي باشد. در هنگامي كه شما روي قسمتي از متن برنامه كار ميكنيد و مي خواهيد به يك قسمت ديگر برويد ممكن است براي برگشتن به مكان اول خود كمي مشكل پيدا كنيد. ولي شما ميتوانيد با زدن چند دكمه به محل مورد نظرتون باز گرديد. براي اينكار در خطي كه قصد داريد علامت بگذاريد كليدهاي Ctrl+Shift+0..9 را بفشاريد. منظور اينست كه كليدهاي ctrl+Shift را نگه داريد و يكي از اعداد 0 تا 9 را وارد كنيد تا آن خط به همان شماره علامت گذاري شود و سپس هر جا كه خواستيد برويد و سپس هر بار كه كليد Ctrl را نگه داريد و شماره مورد نظر را وارد كنيد به همان خط باز خواهيد گشت. البته توجه داشته باشيد كه فقط مي توانيد 10 خط را با اين روش علامت گذاري بكنيد و براي برداشتن علامت ها كافيست روي همان خط دوباره كليد Ctrl+shift و شماره‌اي كه براي آن خط وارد كرده ايد را بفشاريد با اينكار علامت آن خط برداشته مي شود.


ايجاد كلاس مورد نظر :
شما هنگامي كه در قسمت Private و يا Public يك type، روال يا تابع درست كرديد لازم داريد كه قسمتي را براي قرار دادن كدهاي مربوط به آن روال يا تابع را ايجاد كنيد. براي اينكار شما پس از اينكه نام تابع را تايپ كرديد مي توانيد كليدهاي Ctrl+Shift+C را فشار دهيد تا دلفي يك قسمت براي نوشتن كدهاي مورد نظرتان ايجاد كند.

ظاهر كردن پنجره Code insight :
شما حتما به اهميت و مفيد بودن اين قسمت دلفي واقفيد كه در هنگام كد نويسي تا چه حد مي تواند كارها را راحت كند. بله در هنگام وارد كردن كدها بعد از وارد كردن نام يك كلاس و يا Object با زدن يك نقطه (.) پنجره Code Insight‌ ظاهر مي شود. حال در بعضي وقتها شما ممكن است كه نقطه را قبلا وارد كرده باشيد و يا در مواقع ديگر اين پنجره ظاهر نشود. در
اين صورت براي اينكه پنجره را ظاهر كنيد بايد دوباره نقطه را وارد كنيد ولي راه اسانتري هم وجود دارد و آن اينست كه كليدهاي Ctrl+Speacebar را فشار دهيد.


ظاهر كردن پنجره Code Parameter:
همانند بالا در هنگام ظاهر شدن Hint مربوط به راهنماي توابع كه معمولاً بعد از گذاشتن پرانتز مربوط ظاهر ميشود و در مورد پارامترهاي لازم مي باشد نيز مي توانيد از كليدهاي Ctrl+Shift+SpaceBar استفاده كنيد.

رفتن از قسمت تعريف توابع و روالها به قسمت كد آنها:
هميشه اين نياز وجود خواهد داشت كه شما در هنگامي كه داريد به دنبال يك روال در قسمت type ميگرديد بعد از پيدا كردن نام آن مي خواهيد كه خود آن تابع يا روال را نيز ببنيد. براي اينكار خوب حتما نام آن را جستجو ميكنيد ولي يك راه آسانتر اينست كه شما روي نام آن تابع قرار گيريد و كليدهاي Ctrl+Shift+Up/Down را بزنيد. در اينحالت اگر روي كد تابع باشيد به قسمت تعريف آن خواهيد رفت.
__________________

Borna66
03-21-2009, 01:59 AM
براى نمايش يك alpha Bitmap كه Bitmapي است كه پيكسل هاي transparent (شفاف) يا semi-transparent (نيمه شفاف) دارد استفاده مي شود.


به اضافه كانالهاي رنگ قرمز، سبز و آبي، هر پيكسلي در يك alpha Bitmap يك موله شفافيت دارد كه از آن به عنوان كانال آلفا ياد مي شود. كانال آلفا حاوي همان تعداد بيت هايي است كه در كانال رنگ وجود دارد. به عنوان مثال يك كانال آلفاي 8 بيت مي تواند 256 مرحله يا Level از شفافيت را به نمايش بگذاريد. از 0 (تمام تصوير شفاف است) تا 256 (تمام تصوير مات است). مكانيسم AlphaBlending (يا تركيب كردن آلفا) بوسيله صدا كردن تابع AlphaBlend احضار مي شود. تابع AlphaBlend بيت‌مت‌هايي را كه پيكسل هاي شفاف يا نيمه شفاف دارند نمايش مي دهد. اين تابع در ويندوز 95 و حتي در ويندوزهاي NT قبل از ويندوز 2000 پشتيباني نمي شد.



كد زير يك پنجره را به سه قسمت افقي تقسيم مي كند. آنگاه يك Bitmap به صورت alpha-blend شده (تركيب آلفا شده) در هر يك از قسمتهاي پنجره نمايش مي دهد.






const

AC_SRC_ALPHA = $1;

procedure DrawAlphaBlend (hWnd : HWND; hdcwnd : HDC);
var
Ahdc : HDC; // handle of the DC we will create
bf : BLENDFUNCTION; // structure for alpha blending
Ahbitmap : HBITMAP; // bitmap handle
bmi : BITMAPINFO; // bitmap header
pvBits : pointer; // pointer to DIB section
ulWindowWidth,
ulWindowHeight : ULONG; // window width/height
ulBitmapWidth,
ulBitmapHeight : ULONG; // bitmap width/height
rt : TRect; // used for getting window dimensions
begin
// get window dimensions
GetClientRect(hWnd, rt);

// calculate window width/height
ulWindowWidth := rt.right - rt.left;
ulWindowHeight := rt.bottom - rt.top;

// make sure we have at least some window size
if ((ulWindowWidth = 0 ) and (ulWindowHeight=0)) then
exit;

// divide the window into 3 horizontal areas
ulWindowHeight := trunc(ulWindowHeight / 3);

// create a DC for our bitmap -- the source DC for AlphaBlend
Ahdc := CreateCompatibleDC(hdcwnd);

// zero the memory for the bitmap info
ZeroMemory(@bmi, sizeof(BITMAPINFO));

// setup bitmap info
bmi.bmiHeader.biSize := sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth := trunc(ulWindowWidth - (ulWindowWidth/5)*2);
ulBitmapWidth := trunc(ulWindowWidth - (ulWindowWidth/5)*2);
bmi.bmiHeader.biHeight := trunc(ulWindowHeight - (ulWindowHeight/5)*2);
ulBitmapHeight := trunc(ulWindowHeight - (ulWindowHeight/5)*2);
bmi.bmiHeader.biPlanes := 1;
bmi.bmiHeader.biBitCount := 32; // four 8-bit components
bmi.bmiHeader.biCompression := BI_RGB;
bmi.bmiHeader.biSizeImage := ulBitmapWidth * ulBitmapHeight * 4;

// create our DIB section and select the bitmap into the dc
Ahbitmap := CreateDIBSection(Ahdc, bmi, DIB_RGB_COLORS, pvBits, 0, 0);
SelectObject(Ahdc, Ahbitmap);

bf.BlendOp := AC_SRC_OVER;
bf.BlendFlags := 0;
bf.SourceConstantAlpha := $7f; // half of 0xff = 50% transparency
bf.AlphaFormat := 0; // ignore source alpha channel

AlphaBlend(hdcwnd, trunc(ulWindowWidth/5), trunc(ulWindowHeight/5),
ulBitmapWidth, ulBitmapHeight,
Ahdc, 0, 0, ulBitmapWidth, ulBitmapHeight, bf);


bf.BlendOp := AC_SRC_OVER;
bf.BlendFlags := 0;
bf.AlphaFormat := AC_SRC_ALPHA; // use source alpha
bf.SourceConstantAlpha := $ff; // opaque (disable constant alpha)

AlphaBlend(hdcwnd, trunc(ulWindowWidth/5),
trunc(ulWindowHeight/5+ulWindowHeight), ulBitmapWidth, ulBitmapHeight,
Ahdc, 0, 0, ulBitmapWidth, ulBitmapHeight, bf);

bf.BlendOp := AC_SRC_OVER;
bf.BlendFlags := 0;
bf.AlphaFormat := 0;
bf.SourceConstantAlpha := $3A;

AlphaBlend(hdcwnd, trunc(ulWindowWidth/5),
trunc(ulWindowHeight/5+2*ulWindowHeight), ulBitmapWidth,
ulBitmapHeight, Ahdc, 0, 0, ulBitmapWidth,
ulBitmapHeight, bf);

// do cleanup
DeleteObject(Ahbitmap);
DeleteDC(Ahdc);

Borna66
03-21-2009, 02:00 AM
كسانيكه با اينترنت كار ميكنند مطمنا براي يكبار هم شده از فايلهاي real استفاده كرده اند فايلهايي كه
با پسوند هاي rm,ra,ram,... مي باشند و فرمتهاي صوتي و تصويري را پشتيباني ميكنند .با اين توضيح به نكات
ذيل توجه كنيد!
اين نرم افزار توانايي دارد يك فايل mpeg با حجم 15 مگابايت را به فايل تصويري به حجم
1 مگابايت تبديل كند.البته لازم به توضيح است كه كيفيت تصوير چندان مطلوب نمي باشد و در مواردي مي توان از آن استفاده كرد.
همچنين فايلهاي صوتي حتيMP3 با كيفيت مطلوب توسط اين سيستم به مقدار قابل توجهي كم حجم ميشوند.
نرم افزاري هايي از قبيل REAL PRODUCER قابليت تبديل فايلها را با هر فرمتي به REAL دارا مي باشند واحتياجي به سخت افزار نمي باشد
چگونگي استفاده از اين امكانات در دلفي:
ابتدا بايد نرم افزار REAL بر روي رايانه شما نصب شود سپس در دلفي به :
را انتخاب كنيد.import activex control\commponent
در پنجره جديد real player activeX control library(version X,x) را انتخاب كرده و دكمه install را بزنيد.
حال در قسمت activex ايكوني آبي رنگ با علامت play داريد.آن را به فرم اضافه كنيد!
يك حستجو گر صوتي بر روي فرم شما ايجاد ميشود كه تصوير آن بستگي به نسخه نصب شده REAL بر روي سيستم شمادارد.
براي پخش يك فايل شما ميتوانيد نام آن را در source وارد كرده و برنامه را اجرا كنيد ويا براي كنترل فايل توسط
برنامه ميتوانيد از دستورات زير استفاده كنيد.

raelaudio1.source ='path\filename');
realaudio1.doplay;

براي استفاده يك كايد جهت play/pause مانند دستگاههاي video cd نيز ميتوانيد از دستور زير استفاده كنيد.

real audio1.doplaypause;

و

realaudio1.dostop;جهت پايان دادن به پخش
realaudio1.getitle;مشخصات فايل كه در زمان ساخت به آن معرفي ميگردد
realaudio1.setmute:=true/false;جهت قطع صدا
realaudio1.autostart:=true/false;جهت شروع خودكار در زمان اجراي برنامه

Borna66
03-21-2009, 02:01 AM
چگونه كنترلهاي OLE مثل (dynamic-link library (DLL يا كنترلهاي (ActiveX (OCX را از درون دلفي Register يا UnRegister بكنيم؟


يكي از چيزهايي كه دلفي را اين قدر براي من در زمان Deploy كردن يك پروژه محبوب كرده اين است كه شما به عنوان يك برنامه نويس (در اكثر موارد) مي توانيد فقط فايل exe رو براي كاربر بفرستيد و كاربر با خيال راحت مي تواند از همان فايل exe به تنهايي استفاده كنيد.
جهت اطلاع كساني كه نمي دانند مفهوم Deploy كردن چيست بايد توضيح بسيار مختصري بدهيم. شما ممكن است در پروژه خود از ActiveXها، DLLها و يا ساير فايلهاي ديگر استفاده كنيد. اما كاربر اين فايلهاي اضافه را بر روي كامپيوتر ندارد بنابراين نمي تواند پروژه شما را به تنهايي اجراي كند و بايد دوجين فايل اضافه را نيز همراه داشته باشد. Deploy كردن فرآيندي است كه شما در آن پروژه خود را براي اجراي روي كامپيوتر كاربر بدون نياز به فايلهاي اضافي آماده مي كنيد.

البته من مقاله اي ديگري نيز راجع به استفاده از Flash در دلفي نوشته ام كه در آن به خوبي نصب ActiveX فلش بر روي كامپيوتر كاربر توضيح داده شده است. ولي از آن جا كه كد آن پروژه كمي پيچيده و بزرگ است و از آن جا كه آن مقاله با وسواس تمام نوشته شده و بسيار مفصل است، تصميم گرفتم كه مقاله ديگري راجع به اين مساله بنويسم كه به طور مختصرتر به اين مقوله بپردازد و كدهاي ساده تر و قابل فهم تري نيز ارائه كنيد.
آدرس مقاله "استفاده از Flash در دلفي":

و اما اصل مطلب. بعضي مواقع شما در پروژه ها خود يك ActiveX را با استفاده از دستور "import an ActiveX control" وارد مي كنيد ولي اگر كاربر اين ActiveX را نداشته باشد با exception يا خطايي به نام EOleSysError مواجه خواهد شد و نخواهد توانست كه از برنامه شما استفاده كند.

RegSvr32.exe
دستور command-lineي يا خط فرماني RegSvr32.exe كار نصب كنترلهاي dl يا ActiveX را دارد. شما مي توانيد به طور دستي از اين ابزار استفاده كنيد. كافي است در ويندوز گزينه Run منوي Start را اجرا كرده و به راحتي اين دستور را اجرا كنيد. وقتي شما از RegSvr32.exe استفاده مي كنيد، سعي خواهد كرد كه كمپوننت را load كرده و تابع DLLSelfRegister آنرا فرا بخواند. اگر اين تلاش موفق باشد RegSvr32.exe يك پنجره با پيغام موفقيت نشان مي دهد.

RegSvr32.exe پارامترهاي زير را دارد:


Regsvr32 [/u] [/s] [/n] [/i[:cmdline]] dllname
/s - Silent; display no message boxes
/u - Unregister server
/i - Call DllInstall passing it an optional [cmdline];
when used with /u calls dll uninstall
/n - do not call DllRegisterServer; this option must
be used with /i



توجه: با استفاده از سوييچ ؟/ مي توانيد ليست تمامي پارامترهاي را ببينيد.

از درون دلفي.
براي اين كه شما اين كد را از درون دلفي اجرا كنيد به تابعي احتياج داريد كه يك فايل exe را اجرا كرده و تا اتمام اجراي آن صبر كند.

تابع RegisterOCX بايد چيزي شبيه به اين باشد:



procedure RegisterOCX(ocxPath: string);
type
TRegFunc = function : HResult; stdcall;
var
ARegFunc : TRegFunc;
aHandle : THandle;
begin
try
aHandle := LoadLibrary(PChar(ocxPath));
if aHandle <> 0 then
begin
ARegFunc := GetProcAddress(aHandle,'DllRegisterServer');
if Assigned(ARegFunc) then
begin
ExecAndWait('regsvr32','/s ' + ocxPath);
end;
FreeLibrary(aHandle);
end;
except
ShowMessage(Format('Unable to register %s', [ocxPath]));
end;
end;



توجه: متغيير ocxPath به نام ocx اشاره دارد. به عنوان مثال شما مي توانيد اين تابع را به اين شكل فرا بخوانيد:

RegisterOCX(ExtractFilePath(Application.ExeName) + 'Flash.ocx');
كه سبب نصب ActiveX مربوط به فلش مي شود.

براي اين كه يك ActiveX بتواند نصب شود كنترل ActiveX بايد تابع DllRegisterServer را اجرا كند. به زبان ساده، اين تابع مداخل registry را براي تمامي كلاسهاي داخل كنترل ايجاد مي كند. احتياج نيست ما نگران تابع DllRegisterServer باشيم. ما فقط بايد اطمينان پيدا كنيم كه اين تابع در ActiveX مربوطه وجود دارد.

در تابع بالا از تابع ديگري استفاده شده به نام ExecAndWait. اين تابع كار صدا كردن regsvr32 را با پارامتر s/ و نام فايل ocx انجام مي دهد. (پارامتر s به معناي silent سبب اجراي regsvr32 در مد خاموش مي شود. در اين مد پيغام هاي خطا و موفقيت نمايش داده نمي شود و كاربر از نصب ActiveX مطلع نخواهد شد.
و اين هم تابع ExecAndWait:


uses ShellAPI;
...
function ExecAndWait(const ExecuteFile, ParamString : string): boolean;
var
SEInfo: TShellExecuteInfo;
ExitCode: DWORD;
begin
FillChar(SEInfo, SizeOf(SEInfo), 0);
SEInfo.cbSize := SizeOf(TShellExecuteInfo);
with SEInfo do
begin
fMask := SEE_MASK_NOCLOSEPROCESS;
Wnd := Application.Handle;
lpFile := PChar(ExecuteFile);
lpParameters := PChar(ParamString);
nShow := SW_HIDE;
end;
if ShellExecuteEx(@SEInfo) then
begin
repeat
Application.ProcessMessages;
GetExitCodeProcess(SEInfo.hProcess, ExitCode);
until (ExitCode <> STILL_ACTIVE) or Application.Terminated;
Result:=True;
end
else Result:=False;
end;




البته توجه داشته باشيد كه ShellAPI بايد در ليست uses يونيت شما وجود داشته باشد.
تابع فوق از تابع APIي به نام ShellExecuteEx استفاده مي كند تا يك فايل exe را در سيستم اجرا كند. اگر شما به اطلاعات بيشتري راجع به اين تابع و توابعي مثل اين نياز داريد به مقاله "اجراي فايل exe از درون دلفي" توجه كنيد.

Flash.ocx داخل فايل exe دلفي
همه چيز به خوبي پيش رفت. تنها مسئله اي كه باقيست پنهان كردن Flash.ocx يا هر ocx ديگري از ديد كاربر است. انجام اين كار به سادگي امكان پذير است. فقط كافي است شما فايل ocx را در Resourceها اضافه كنيد. Resource مربوطه با Exe شما Compile خواهد شد و در هنگام اجراي برنامه شما به سادگي آن ocx را روي هارد ذخيره كرده و آن را نصب مي كنيد. براي اطلاعات بيشتر راجع به اين تكنيك به مقاله‌ي زير كه در ابتداي اين نوشتار هم آنرا معرفي كردم مراجعه كنيد.



خلاصه
فهميديم با استفاده از دستور خط فرماني regsvr32.exe مي توانيم يك كنترل OLE را Register يا UnRegister بكنيم.
همچنين ليست پارامتهاي اين تابع را ديديم. به علاوه تابعي به نام RegisterOCX ارائه كرديم كه كار نصب OCX را بر عهده دارد. اين تابع از تابع ديگري به نام ExecAndWait براي اجراي regsvr32.exe استفاده مي كند و تا اتمام اجراي آن صبر مي كند. به علاوه فهميديم كه اين تابع براي اجراي درست به يونيت ShellAPI احتياج داشته و از تابع ShellExecuteEx جهت اجراي فايل سود مي جويد.
به علاوه دانستيم كه به سادگي با استفاده از Resourceهاي مي توانيم فايل OCX خود را در داخل exe از ديد كاربر نهايي پنهان كنيم.