PDA

نسخه کامل مشاهده نسخه کامل : زبان برنامه‌نویسی دلفی



soleares
25-08-2006, 03:32
دِلفی (Delphi) یا به تعبیری ویژوآل پاسکال

– یک زبان برنامه‌نویسی است و بستری برای توسعهٔ نرم‌افزار که شرکت بورلند آن را تولید کرده است. این زبان، در بدو انتشار خود در سال 1995، به عنوان یکی از نخستین ابزارهایی مطرح شد که از توسعهٔ نرم‌افزار بر مبنای متدولوژی RAD پشتیبانی می‌کردند؛ یعنی تولید و توسعهٔ سریع برنامه‌های کاربردی.

این نرم افزار بر مبنای پاسکال شی‌گرا بوده و از این زبان مشتق شده است. البته بورلند نسخه‌ای از دلفی و سی‌پلاس‌پلاس‌بیلدر را برای لینوکس به نام کایلیکس (Kylix) ارائه کرد که مورد استقبال توسعه دهندگان نرم‌افزارهای لینوکس قرار نگرفت. نرم‌افزارهای دلفی در ابتدا به صورت مستقیم از کتابخانه‌های ویندوز و کتابخانهٔ مخصوص خود به نام VCL استفاده می‌کرد، اما پس از نسخه ۶ دلفی، امکانات استفاده از دات‌نت هم به آن اضافه شد. در حال حاضر می‌توان دلفی را یکی از رایج‌ترین زبان‌های ممکن در ایران دانست.

زبانِ دلفی که پیشتر بنام Object-Pascal یا پاسکال شیءگرا خوانده می‌شد و برای طراحی نرم‌افزاهای تحت ویندوز به کار می‌رفت، امروزه چنان توسعه یافته است که برای تولید نرم‌افزارهای تحت سیستم‌عاملِ لینوکس و دات‌نت نیز به کار می‌آید. بیشترین کاربرد دلفی در طراحی برنامه‌های رومیزی و پایگاه دا‌ده‌ها‌ است، اما به عنوان یک ابزارِ «چند- منظوره»، برای طراحی انواع گوناگونی از پروژه‌های نرم‌افزاری نیز مورد استفاده قرار می‌گیرد.

دلفی 2006

شرکت بورلند در سال 2006 نرم‌افزار جدید خود را با ویژگیهای جدید به بازار ارائه کرد. این برنامه جدید امکان برنامه نویسی با دلفی و سی پلاس پلاس و همچنین سی‌شارپ را بطور هم‌زمان ارائه می‌دهد. بدین ترتیب برنامه نویسانی که با ابزارهای مختلفی کار می‌کنند براحتی می‌توانند در این محیط جدید برنامه نویسی کنند. ویژگی مهم این نگارش نسبت به نگارش 2005 بحث مدیریت حافظه است. در نگارش 2005 ضعفهائی در این زمینه وجود داشت که در این نسخه حل شده است.

soleares
25-08-2006, 03:35
ساخت DLL

استفاده از DLL و كدهاي داخل آن بهترين راه حل براي برنامه شما مي باشد
چرا كه در آينده اگر قصد تغييراتي در برنامه خود را داشته باشيد مي توانيد
با ويرايش اين DLL آن تغييرات را اعمال كنيد.

با ساخت دستورات و عملكردهاي گوناگون در DLL مي توانيد سورس كد
راحت تر و منظم تري در برنامه اصلي خود داشته باشيد. يكي ديگر از مزاياي
DLL قابليت Update نرم افزار مي باشد. به طور مثال فرض كنيد برنامه شما از
يك DLL براي دستورات خود استفاده مي كند. اگر در آينده نياز به تغييراتي
در آن داشته باشيد ، مي توانيد DLL خود را تغيير دهيد و از كاربران بخواهيد
تا به جاي تغيير دادن كل برنامه شما ، فقط DLL مربوطه را تغيير دهند تا
برنامه شما عملكرد جديدي داشته باشد.


ضمناْ به ياد داشته باشيد DLL نوشته شده در هر زباني قابل استفاده در
زبانهاي برنامه نويسي ديگر نيز مي باشند .
پس به خاطر داشته باشيد استفاده از DLL ها مزاياي فراواني را به شما
در برنامه نويسي مي دهد.

چگونگي ساخت DLL در دلفي ...

ساختن يك DLL در دلفي بسيار آسان مي باشد. فقط لازم است كه در
هنگام ساخت ، حواستان به تمامي دستورات باشد تا نتيجه خوبي در
اجراي آن بگيريد . حال بياييد قدم به قدم اولين DLL خود را درست كنيم :




ابتدا از منوي File گزينه New و سپس Other را انتخاب نماييد.



سپس مطابق شكل گزينه DLL Wizard را انتخاي كرده و OK را فشار دهيد.






اكنون فرمي باز شده كه حاوي يك سري توضيحات مي باشد. اين فايل را
با نام MyDll.dpr ذخيره كنيد.
اكثر كتابهاي دلفي يا دوستاني كه در اين رابطه مطلبي نوشته اند به شما
مي گويند كه تمامي دستورات و متدهاي خود را در اين فايل بنويسيد. اما
اگر مي خواهيد فايل DLL شما به صورتي مرتب باشد ، شما بايد فايلهاي خود
را طبقه بندي و جدا نماييد كه من اين روش را به شما پيشنهاد مي كنم.


از منوي File گزينه New و سپس Unit را انتخاب نماييد



اكنون اين فايل را با نام uDll.pas در همان شاخه اي كه فايل قبلي خود را
با نام MyDll.dpr قرار داديد ، ذخيره نماييد.

براي يك شروع آسان اجازه دهيد عملكردي بنويسيم كه يك رشته را گرفته
و يك مقدار Boolean را برمي گرداند. اين اولين دستور ما در فايل DLL مي باشد.

فايل جديد باز شده را به صورت زير تغيير دهيد :
كد:

unit uDLL;

interface

uses Dialogs;

function DisplayMsg(s:String):Boolean;stdcall;

implementation

function DisplayMsg(s:String):Boolean; stdcall;
begin
ShowMessage(s);
Result := True;
end;

end.

*** فراموش نكنيد كه عبارت uses Dialogs را دقيقاْ در جاي خودش
قرار دهيد ، در غير اين صورت پيغام خطا دريافت خواهيد كرد.
در انتها فايل خود را ذخيره كنيد و آن را ببنديد.


حال نوبت استفاده از عملكرد ساخته شده در DLL مي باشد. در اصطلاح اين
عمل ، يعني اجازه استفاده از دستورات داخل DLL را Exports مي گويند.
اكنون دوباره فايل MyDll.dpr را كه در ابتدا ساخته بوديم باز كنيد .
همان طور كه در ابتداي فايل مشاهده مي نماييد ، توضيحاتي مربوط به
استفاده از يونيت ShareMem در صورت استفاده از رشته هاي استاندارد
دلفي و رد شدن آنها بين DLL و برنامه خود ، نوشته شده است.
اين بدين خاطر است كه در برخي مواقع استفاده از PChar بهتر از حالت
معمول مي باشد . به خصوص در حالت دلفي و C .

اگر شما تصميم به استفاده از ShareMem گرفته ايد مي بايست فايلي با
نام borlndmm.dll را به همراه برنامه خود منتشر نماييد. اين فايل حاوي
دستورات مربوط به رد شدن رشته ها و ... مي باشد. اين فايل مي بايست
در شاخه برنامه شما ، يا يكي از شاخه هاي سيستمي ويندوز قرار بگيرد.
من شخصاْ شاخه System ويندوز را ترجيح مي دهم.

البته اگر تمايلي به استفاده از دستورات رد و بدل رشته ها در DLL خود را
نداشتيد ، ديگر نيازي به اين همه دنگ و فنگ نداريد !

به فايل اصلي خودمان يعني MyDll.dpr باز مي گرديم. در اين مثال به خاطر
اينكه من در عملكرد خود ، از رشته ها استفاده كردم ، مي بايست در خط
uses برنامه ، گزينه ShareMem را اضافه كنيم .

كلمه كليدي ، همان طور كه قبلاْ توضيح دادم ، Exports مي باشد كه به
برنامه هاي ديگر مي گويد كه كدام دستور در داخل DLL قابل اجرا مي باشد.


پس كد ما به اين صورت مي شود :
كد:

library Mydll;

uses ShareMem,
SysUtils,
Classes,
uDLL in 'uDLL.pas';

{$R *.RES}

exports DisplayMsg;

begin
end.


در انتها فايل خود را كامپايل كنيد .
كار ساخت DLL تمام شد ! به شاخه ضبط فايل خود برويد و فايل DLL را مشاهده
كنيد. حال شما قادر هستيد تا از اين DLL در برنامه خودتان استفاده نماييد.


در انتها من توضيحي در رابطه به stdcall ، كه در فايل اول استفاده كرديم
مي دهم و اصولاْ چرا از اين دستور استفاده كردم ؟
همان طور كه در ابتداي بحث گفتم يكي از قابليتهاي DLL ها استفاده آنها
در تمامي برنامه ها مي باشد. به طور مثال DLL ساخته شده در دلفي
مي تواند در Visual Basic ، Visual C و ... استفاده شود.

كلمه كليدي stdcall نيز به همين معني در انتهاي دستورات گنجانده شده.
اين كلمه به دلفي مي گويد تا اين دستور را به صورتي ترجمه كن كه ويندوز
قابليت شناسايي آن را داشته باشد و زماني كه ويندوز قابليت شناسايي
اين دستور را داشته باشد ، برنامه هاي ديگر هم اين قابليت را پيدا مي كنند.

استفاده از اين دستور بستگي به تصميم شما دارد كه آيا قرار است فايل DLL
شما در برنامه هاي ديگر هم استفاده شود يا خير ؟
در صورتي كه تصميم به استفاده از DLL فقط در دلفي داريد ، مي توانيد
به جاي دستور فوق ، از دستور register در انتهاي خطوط استفاده نماييد.
اما استفاده از stdcall ، خاطر شما را در استفاده از DLL در آينده راحت
مي سازد. چرا كه ممكن است روزي بخواهيد فايل DLL خود را در زبان
برنامه نويسي ديگري استفاده نماييد.

soleares
25-08-2006, 03:36
پس از اينكه بورلند تكنولوژي MIDAS را در جهت انجام برنامه‌هاي چند لايه و تحت Web ارائه كرد در ويرايش جديد دلفي تكنولوژي را مطرح كرده كه مي‌توان گفت تاثير زيادي بر دنياي برنامه‌نويسي Web خواهد داشت. تكنولوژي Websnap در واقع پايه ويرايش WebBroker در دلفي 5 مطرح كرده است كه ويژگيهاي بسيار زيادي همراه آن مي‌باشد:

- Multiple Modules
- New wizards
- Server side scripting
- New component
- Surface design

Multiple Modules :

يك برنامه منفي Websnap مي‌تواند از چند مدل وب پشتيباني كند، در اين حالت چندين پياده‌ساز توانايي كاربردهاي يك يا چند پروژه مشابه را دارند بطوري كه كمترين تداخل بين آنها صورت گيرد براي اين منظور يك Wizard جهت ايجاد Websnap ايجاد شده است كه شما براحتي مي‌توانيد، انواع مدلها از قبيل Webappage، WebAppData، Webpage و WebData را ايجاد كنيد. مدل WebData همانند يك ظرف براي اجزاء كه شما بين برنامه Web خود به اشتراك مي‌گذاريد مي‌باشد.

مدل Webpage براي شما يك صفحه Web را در برنامه مورد نظر شما ايجاد مي‌كند كه داراي فرمت و تواناييهاي HTML مي‌باشد و شما توسط Websnap surface designer توانايي نمايش Scriptهاي خاصي خود را داريد.

Server-side scripting :

Websnap داراي اسكريپت نويسي سرويس دهنده مي‌باشد يك زبان ساده جهت طراحي و برنامه‌نويسي يك صفحه Web كه شامل:

- يك اسكريپت كه توانايي دسترسي به Componentهاي دلفي را دارد.

- از زبانهاي Script همانند VB يا JavaScript حمايت مي‌كند.

- ولي مي‌تواند تركيبي در اسكريپت و HTML باشد.

DataSnap :

اين تكنولوژي اجازه مي‌دهد تا بانكهاي اطلاعاتي چندلايه ايجاد شوند كه برنامه‌هاي دلفي توانايي اتصال سرويس گيرنده‌ها را به اين لايه‌ها فراهم مي‌كنند.بوسيله اين تكنولوژي شما توانايي جستجو و كار با بانكهاي اطلاعاتي در روي سرورهاي مختلف در چند نقطه را خواهيد داشت بعنوان مثال مي‌توانيد از ايران روي سرور در ژاپن Query بزنيد و نتيجه آن را در Query ديگري در سرور آلمان شركت دهيد. البته اين قابليت مي‌تواند در محيطهاي غير Web نيز استفاده شود.

soleares
25-08-2006, 03:36
طريقه بدست آوردن اطلاعات مربوط به هارد ديسک - سي دي رام - فلاپي ديسک
اطلاعاتي که روالهاي زير برمي گرداند عبارتست از شماره سريال - نوع سيستم فايل -
پشتيباني از نام فايلهاي طولاني و نام درايو

From The Windows.Pas
--------------------
--------------------

function GetVolumeInformationA(lpRootPathName: PAnsiChar;
lpVolumeNameBuffer: PAnsiChar; nVolumeNameSize: DWORD; lpVolumeSerialNumber: PDWORD;
var lpMaximumComponentLength, lpFileSystemFlags: DWORD;
lpFileSystemNameBuffer: PAnsiChar; nFileSystemNameSize: DWORD): BOOL; stdcall;

function GetVolumeInformationW(lpRootPathName: PWideChar;
lpVolumeNameBuffer: PWideChar; nVolumeNameSize: DWORD; lpVolumeSerialNumber: PDWORD;
var lpMaximumComponentLength, lpFileSystemFlags: DWORD;
lpFileSystemNameBuffer: PWideChar; nFileSystemNameSize: DWORD): BOOL; stdcall;

function GetVolumeInformation(lpRootPathName: PChar;
lpVolumeNameBuffer: PChar; nVolumeNameSize: DWORD; lpVolumeSerialNumber: PDWORD;
var lpMaximumComponentLength, lpFileSystemFlags: DWORD;
lpFileSystemNameBuffer: PChar; nFileSystemNameSize: DWORD): BOOL; stdcall;

Example
-------
-------

Used Variables
--------------
Path : PChar;
--> String that contains the root directory of the volume to
be described.
VolumeName : PChar;
--> Points to a buffer that receives the name of the specified
volume.
VolumeNameSize : DWord;
--> Specifies the lenght in characters of the buffer that
receives the volume name.
SerialNumber : DWord;
--> Points to a variable that receives the volume's serial
number.
MaxLength : DWord;
--> Receives the maximum length in characters of a filename
supported by the specified file system.
(to indicate if long file names are supported)
- long file names --> value : 255
Flags : DWord;
- FS_CASE_IS_PRESERVED
- FS_CASE_SENSITIVE
- FS_UNICODE_STORED_ON_DISK
- FS_PERSISTENT_ACLS
- FS_FILE_COMPRESSION
- FS_VOL_IS_COMPRESSED
(for more info on the flags look in the help file)
FileSystem : PChar;
--> Points to a buffer that receives the name of the specified
file system.
FileSystemNameSize: DWord;
--> Specifies the lenght in characters of the buffer that
receives the filesytem name.

Code
----
Path := 'C:\';
VolumeNameSize := 256;
FileSystemNameSize := 256;
GetVolumeInformation(Path,VolumeName,VolumeNameSiz e,
@SerialNumber,MaxLength,Flags,FileSystem,FileSyste mNameSize);

soleares
25-08-2006, 03:37
چگونه با استفاده از شيوه Boyer-Moore جستجو كنيم؟





راه حل اول:


unit BMSearch;

interface

type
{$IFDEF WINDOWS}
size_t = Word;
{$ELSE}
size_t = LongInt;
{$ENDIF}

type
TTranslationTable = array[char] of char; { translation table }
TSearchBM = class(TObject)
private
FTranslate: TTranslationTable; { translation table }
FJumpTable: array[char] of Byte; { Jumping table }
FShift_1: integer;
FPattern: pchar;
FPatternLen: size_t;
public
procedure Prepare(Pattern: pchar; PatternLen: size_t; IgnoreCase: Boolean);
procedure PrepareStr(const Pattern: string; IgnoreCase: Boolean);
function Search(Text: pchar; TextLen: size_t): pchar;
function Pos(const S: string): integer;
end;

implementation

uses
SysUtils;

{Ignore Case Table Translation}

procedure CreateTranslationTable(var T: TTranslationTable; IgnoreCase: Boolean);
var
c: char;
begin
for c := #0 to #255 do
T[c] := c;
if not IgnoreCase then
exit;
for c := 'a' to 'z' do
T[c] := UpCase(c);

{ Mapping all accented characters to their uppercase equivalent }

T['Á'] := 'A';
T['À'] := 'A';
T['Ä'] := 'A';
T['Â'] := 'A';

T['á'] := 'A';
T['à'] := 'A';
T['ä'] := 'A';
T['â'] := 'A';

T['É'] := 'E';
T['È'] := 'E';
T['Ë'] := 'E';
T['Ê'] := 'E';

T['é'] := 'E';
T['è'] := 'E';
T['ë'] := 'E';
T['ê'] := 'E';

T['Í'] := 'I';
T['Ì'] := 'I';
T['Ï'] := 'I';
T['Î'] := 'I';

T['í'] := 'I';
T['ì'] := 'I';
T['ï'] := 'I';
T['î'] := 'I';

T['Ó'] := 'O';
T['Ò'] := 'O';
T['Ö'] := 'O';
T['Ô'] := 'O';

T['ó'] := 'O';
T['ò'] := 'O';
T['ö'] := 'O';
T['ô'] := 'O';

T['Ú'] := 'U';
T['Ù'] := 'U';
T['Ü'] := 'U';
T['Û'] := 'U';

T['ú'] := 'U';
T['ù'] := 'U';
T['ü'] := 'U';
T['û'] := 'U';

T['ñ'] := 'Ñ';
end;

{Preparation of the jumping table}

procedure TSearchBM.Prepare(Pattern: pchar; PatternLen: size_t; IgnoreCase: Boolean);
var
i: integer;
c, lastc: char;
begin
FPattern := Pattern;
FPatternLen := PatternLen;
if FPatternLen < 1 then
FPatternLen := strlen(FPattern);
{This algorythm is based on a character set of 256}
if FPatternLen > 256 then
exit;
{1. Preparing translating table}
CreateTranslationTable(FTranslate, IgnoreCase);
{2. Preparing jumping table}
for c := #0 to #255 do
FJumpTable[c] := FPatternLen;
for i := FPatternLen - 1 downto 0 do
begin
c := FTranslate[FPattern[i]];
if FJumpTable[c] >= FPatternLen - 1 then
FJumpTable[c] := FPatternLen - 1 - i;
end;
FShift_1 := FPatternLen - 1;
lastc := FTranslate[Pattern[FPatternLen - 1]];
for i := FPatternLen - 2 downto 0 do
if FTranslate[FPattern[i]] = lastc then
begin
FShift_1 := FPatternLen - 1 - i;
break;
end;
if FShift_1 = 0 then
FShift_1 := 1;
end;

procedure TSearchBM.PrepareStr(const Pattern: string; IgnoreCase: Boolean);
var
str: pchar;
begin
if Pattern <> '' then
begin
{$IFDEF Windows}
str := @Pattern[1];
{$ELSE}
str := pchar(Pattern);
{$ENDIF}
Prepare(str, Length(Pattern), IgnoreCase);
end;
end;

{Searching Last char & scanning right to left}

function TSearchBM.Search(Text: pchar; TextLen: size_t): pchar;
var
shift, m1, j: integer;
jumps: size_t;
begin
result := nil;
if FPatternLen > 256 then
exit;
if TextLen < 1 then
TextLen := strlen(Text);
m1 := FPatternLen - 1;
shift := 0;
jumps := 0;
{Searching the last character}
while jumps <= TextLen do
begin
Inc(Text, shift);
shift := FJumpTable[FTranslate[Text^]];
while shift <> 0 do
begin
Inc(jumps, shift);
if jumps > TextLen then
exit;
Inc(Text, shift);
shift := FJumpTable[FTranslate[Text^]];
end;
{ Compare right to left FPatternLen - 1 characters }
if jumps >= m1 then
begin
j := 0;
while FTranslate[FPattern[m1 - j]] = FTranslate[(Text - j)^] do
begin
Inc(j);
if j = FPatternLen then
begin
result := Text - m1;
exit;
end;
end;
end;
shift := FShift_1;
Inc(jumps, shift);
end;
end;

function TSearchBM.Pos(const S: string): integer;
var
str, p: pchar;
begin
result := 0;
if S <> '' then
begin
{$IFDEF Windows}
str := @S[1];
{$ELSE}
str := pchar(S);
{$ENDIF}
p := Search(str, Length(S));
if p <> nil then
result := 1 + p - str;
end;
end;

end.





راه حل دوم:
اين يك دمو براى الگوريتم جستجوى Boyer-Moore است. ايده بسيار ساده است. در ابتدا يك فهرست از رشته‌هاى مورد نظر جهت جستجو ساخته و سپس روتين BMsearch را صدا مى‌كنيم. فراموش نكنيد كه در برنامه نهايى خود Range Checking را با سوييج {$R-} خاموش كنيد. در غير اينصورت جستجو 2 الى 3 ساعت بيشتر از زمان عادي طول مي‌كشد.


{Public-domain demo of Boyer-Moore search algorithm.
Guy McLoughlin - May 1, 1993.}

program DemoBMSearch;

{Boyer-Moore index table data definition}
type
BMTable = array[0..127] of byte;

{Create a Boyer-Moore index table to search with.}

procedure Create_BMTable(Pattern: string; var BMT: BMTable);
var
Index: byte;
begin
fillchar(BMT,

soleares
25-08-2006, 03:39
دلفي و اسمبلي




برنامه نويسان دوران 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 و اسمبلي را باهم بكار گرفته و برنامه هايي با بازدهي بسيار بالا بسازيد.از حالا به بعد اگر شنيديد كه :"آره بابا با دلفي نميشه فلان كارو انجام داد ، بايد با اسمبلي كد بنويسي" ميدانيد چه جوابي بدهيد.

هدف از زندگي كردن لذت بردن است ، پس از زندگي لذت ببريد و ديگران را در اين لذايذ سهيم كنيد.

soleares
25-08-2006, 03:40
چگونه تمامي رويدادهاي يك شيء را در زمان اجرا به Nil تنظيم ‌كنيم؟

در اين مقاله روشي را جهت اينكه تمامي رويدادهاي يك شيء تعريف شده در دلفي را در زمان اجرا به Nil تنظيم كنيد براي شما بازگو مي‌كنيم. شما مي‌توانيد از RTTIها جهت رسيدن به اهداف خود استفاده كنيد اما فقط براي زمان طراحي و اجرا و اين امكان براي رويدادها وجود ندارد. استفاده از RTTI، تا حدودي پيچيده است بنابراين من رويه‌اي را براي نسبت دادن Nil به يك شيء موجود در زمان اجراي يك برنامه در دلفي آورده‌ام كه نحوه انجام اين كار را به شما نشان مي‌دهد.

unit uNilEvent;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{Private declarations}
public
{Public declarations}
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

uses
Typlnfo;

procedure NilEvents(lnstance: TObject);
var
Typelnfo: PTypelnfo;
I, Count: Integer;
PropList: PPropList;
Proplnfo: PProplnfo;
Method: TMethod;
begin
Typelnfo := Instance.Classlnfo;
Method.Code := nil;
Method.Data := nil;
Count := GetPropList(Typelnfo, [tkMethod], nil);
GetMem(PropList, Count * SizeOf(Pointer));
try
GetPropList(Typelnfo, [tkMethod], PropList);
for I := 0 to Count -1 do
begin
Proplnfo := PropList^[I];
SetMethodProp(lnstance, Proplnfo, Method);
end;
finally
FreeMem(PropList);
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
const
sText = 'The 2nd time you click Button1 the event will not fire';
begin
NilEvents(Button1);
ShowMessage(sText);
end;

end.

چگونه رويداد مربوط به تمامي اجزاء درون برنامه خود را تغيير دهيم؟

گاهي لازم مي‌شود تا ما فراميني را براي يكي از رويدادهاي برنامه خود به تمامي اشياء استفاده شده در برنامه نسبت دهيم اينكار مي‌تواند با استفاده از RTTI دلفي صورت گيرد شما مثالي را مي‌بينيد كه اين كار را شبيه‌سازي كرده است.

uses
Typlnfo;

procedure TFrmRTTIOnChange.Button1Click(Sender: TObject);
var
proplnfo: PProplnfo;
thisEvent: TNotifyEvent;
begin
proplnfo := GetProplnfo(Memo1.Classlnfo, 'OnChange');
if proplnfo <> nil then
begin
thisEvent := Memo1AltChange;
SetOrdProp(Memo1, Proplnfo, integer(@thisEvent));
end;
end;

procedure TFrmRTTIOnChange.Memo1Change(Sender: TObject);
begin
Caption := 'Normal On Change';
end;

procedure TFrmRTTIOnChange.Memo1AltChange(Sender: TObject);
begin
Caption := 'Alternate On Change';
end;

soleares
25-08-2006, 03:45
بررسي فشردن كليد توسط كاربر در هنگام اجراي يك حلقه

زماني كه شما از حلقه ها يا همان Loop در برنامه خود استفاده مي كنيد
در برخي مواقع شايد لازم باشد كه كاربر بتواند اين حلقه را در هر لحظه اي
متوقف سازد. در اكثر برنامه هاي ديده شده اين عمل انجام نمي شود و كاربر
بايد زمان طولاني براي رسيدن به آخر حلقه صبر كند.

به طور مثال فرض كنيد برنامه شما مي خواهد يك سري اعداد اتفاقي توليد كند
و به كاربر نمايش دهد. تعداد اين اعداد شايد به صدهزار عدد برسد. حال فرض
كنيد حلقه اي بسازيد كه براي كاربر ، اين اعداد را يكي يكي نشان دهد.

شايد كاربر شما در حين كار خسته شود و بخواهد اين عمل را لغو كند.
اما اگر به صورت معمول اين حلقه را اجرا كنيد ، وي مجبور است تا انتهاي حلقه
صبر كند و اين كار بسيار خسته كننده اي مي باشد.

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

اما را حل چيست ؟ آيا راهي وجود دارد كه به كاربر اجازه دهد تا عمليات را
در هر زماني لغو كند ؟

جواب اين سوال در استفاده از دستور ProcessMessages خلاصه مي شود.
به كار بردن اين دستور باعث مي شود تا دلفي متوجه باشد كه ديگر دستورات
برنامه را حين عمليات زير نظر بگيرد و آنها را اجرا كند.

به طور مثال با به كار بردن اين دستور ، دلفي مي تواند فشار دادن يك كليد
توسط كاربر را هنگام اجراي حلقه متوجه شود و آن را اجرا كند.

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

اين دستور ، به صورت Application.ProcessMessages به كار مي رود.

حال به كد زير دقت فرماييد :


procedure TForm1.Button1Click(Sender: TObject);
var
LoopAborted: Boolean;
i: Integer;
begin
LoopAborted := False;
i := 0;
repeat

Label1.Caption := IntToStr(i);
Application.ProcessMessages;

if GetKeyState(VK_Escape) and 128 = 128 then
begin
LoopAborted := True;
Break;
end;

Inc(i);
until i = 100000;
if LoopAborted then
ShowMessage('User has aborted the loop!');
end;



همان طور كه ملاحظه مي كنيد دستور ذكر شده در داخل حلقه گنجانده
شده تا فشار دادن كليد ESC توسط كاربر در زمان اجراي حلقه شناخته شود.

اين دستور به كاربر اين امكان را مي دهد تا هر لحظه اي كه تمايل داشت
اجراي حلقه را لغو كند.

توجه داشته باشيد كه به كار بردن دستور ProcessMessages تنها محدود به
حلقه ها نمي باشد و در كل هر جايي كه لازم باشد تا چندين دستور به همراه
هم اجرا شوند ، اين دستور نقش اصلي را ايفا مي كند.

soleares
25-08-2006, 03:49
نكات مفيد براي كار در محيط دلفي


محيط دلفي براي برنامه نويسي يكي از بهترين محيطهاي برنامه نويسي است گذشته از كاركرد داخلي و كمپايلر آن كه بسيار قوي

و سريع است، محيط آن يعني 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 را بزنيد. در اينحالت اگر روي كد تابع باشيد به قسمت تعريف آن خواهيد

رفت.

soleares
25-08-2006, 03:50
اميدوارم مورد توجهتون قرار بگيره . استاد دلفي هم كه سولجر جان هستند .

soldier
25-08-2006, 10:58
سلام
تشكر فراوان به خاطر زحماتي كه كشيدي
شما كه اينقدر فعالي چرا تا حالا يه سر هم
به اينجا نزدي!؟

مرد مباح
25-08-2006, 12:04
سولاريس جان.
خودتون اين مطالب رو نوشتين يا از جايي پيدا كرديد؟
منظورم اينه كه خودتون دلفي كاريد؟
اگه هستيد بيشتر به ما سر بزنيد. خوشحال ميشيم.

soleares
25-08-2006, 17:20
من بازم سر ميزنم ! ولي دلفي كار نيستم ! اينا مال دوستم بود .

amin a.^2
25-08-2006, 18:08
سلام سولئاریس جان خیلی خوب بود یعنی عالی بود بازم ازین کپی برداری ها برای ما انجام بده چون خیلی مفید :cool: