PDA

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



Nesta
23-05-2005, 05:22
پس از گذشت 10 ماه ويرايش جديد دلفي 7 به بازار آمد، اين ويرايش همانند سابق در سه نسخه به بازار نرم افزار عرضه شده است كه شامل نسخه Standard، Professional و Enterprise مي‌باشد.

در ويرايش دلفي 7، شركت بورلند تغييراتي را در ساختار داخلي دلفي داده است كه مهمترين آن حمايت و توانايي برنامه‌نويسي بر اساس تكنولوژي .NET مي‌باشد. اين بدين معنااست كه برنامه‌نويسان دلفي مي‌توانند از هم اكنون به محيط .Net framework سوئيچ كنند و از مزاياي برنامه‌نويسي در آن كه مي‌توان به داشتن كلاسهاي برنامه‌نويسي فراوان، امنيت بالاي برنامه‌نويسي و وابسته نبودن به محيط برنامه‌نويسي و محيط اجراي برنامه را نام برد.

ويرايش جديد دلفي 7 در دو CD ارائه شده است كه CD اول كامپايلر دلفي بوده و CD دوم شامل نسخه Preview از .Net framework جهت اجراي برنامه‌هاي نوشته شده توسط دلفي 7 مي‌باشد. لازم به ذكر است كه كاربران بايد حتماً .Net را بر روي سيستم خود نصب كنند تا بتوانند در محيط دلفي 7 برنامه‌نويسي كنند.


حداقل سيستمي كه جهت كار با دلفي 7 پيشنهاد مي‌شود بايد داراي مشخصات زير باشد:

- Intel Pentium II/233MHz يا بالاتر

- MS Windows 98, 2000, XP

- RAM 64MB (البته 128MB پيشنهاد مي‌شود)

- 520MB فضاي خالي روي ديسك سخت

- درايو CD-ROM

- كارت گرافيكي SVGA يا بالاتر


امكانات جديد درون دلفي 7 شامل چندين بخش مي‌باشد :


- افزودن ابزار Model Driven Architecture (MDA) به دلفي، اين يكي از محصولات معروف شركت نرم افزاري بورلند مي‌باشد كه امكان مي‌دهد تا شما بتوانيد بهتر و قويتر معماري برنامه خود را كنترل و پشتيباني كنيد اين محصول براساس UML بوده و مدلهاي Rose را نيز حمايت مي‌كند.


- طراحي و مدلسازي برنامه‌ها با UML : يكي از ويژگيهاي ويرايش 7 دلفي حركت به سمت برنامه نويسي و طراحي شيءگرا با ابزار UML مي‌باشد. محصول Mode Maker از معروفترين اين ابزارها مي‌باشد كه جهت طراحي پروژه با UML در محيط دلفي توسط شركتي به همين نام نوشته شده است. در اين محصول شما امكان طراحي كلاسها و دياگرامهاي UML را داريد كه سورس دلفي آنها نيز بطور خودكار براي شما نوشته مي‌شود.


- ايجاد برنامه‌هاي C-business : در ويرايش جديد شما مي‌توانيد به راحتي به توليد برنامه‌هاي مبتني بر Web اقدام كنيد Websnap و bizsnap در ويرايش جديد كامل شده‌اند و تكنولوژي .Net را نيز همراه خود دارند، اين قابليت بزرگي مي‌باشد زيرا شما با كمترين زمان ممكن مي‌توانيد به توليد محصولات تحت وب بپردازيد و فروشگاههاي تجاري خود را ايجاد كنيد.


- ايجاد برنامه‌هاي كاربردي با ويندوز XP : از ديگر قابليتهاي جديد دلفي 7 افزودن حالات و شكل و قيافه ويندوز XP با VCLهاي دلفي مي‌باشد. اين امكان به شما اجازه مي‌دهد تا برنامه‌هاي قويتري را در محيط ويندوز پياده‌سازي كنيد.


- افزايش قدرت دلفي 7 در تهيه گزارشات و حمايت از محيط‌هاي كاري باعث شده است تا بتوان روي اين محصول بعنوان يكي از كامپايلرهاي قوي در محيط .Net سرمايه گذاري كرد، حمايت از Kylix3 در ويرايش جديد و توانايي برنامه نويسي تحت Linux از ديگر تواناييهاي دلفي ويرايش 7 مي‌باشد.


- امكان ايجاد سيستمهاي چند لايه (3-tier) براساس ساختار DCOM، COM+ و CORBA بر پايه تكنولوژي Datasnap و حمايت از تمامي بانكهاي اطلاعاتي معروف دنيا از قبيل DBZ ،Oracle ،MySQL ،SQL Server و ... كه در ويرايش 6 دلفي نيز وجود داشت ولي در ويرايش جديد اين امكانات بهتر، سريعتر و قويتر شده است.

Nesta
23-05-2005, 05:24
با سلام

Microsoft Agent يكي از سرگرم كننده ترين فن آوريهاي Microsoft مي باشد كه تا كنون توانسته بسيار مورد علاقه كاربران قرار بگيرد. Agentها به برنامه هاي شما جذابيت زيادي مي دهند و امكان ارتباط بهتر و جالبتري را با كاربر ايجاد ميكنند. در اينجا من مي خواهم شما را با Microsoft Agent و طريقه بكار گيري آن در برنامه هاي خودتان را آموزش بدهم كه اميدوارم مفيد باشد. از آنجايي كه من اين امكان را در دلفي استفاده كرده ام براي شما هم مثالهاي دلفي آورده ام ...

اولين باري كه از اين تكنولوژي استفاده شد در برنامه Office 97 بود كه خيلي مورد علاقه كاربران قرار گرفت. من اون موقع خيلي گشتم تا بتونم از اين امكان استفاده كنم ولي خوب نتونستم ): اما بعد ها با پيشرفت كردن علم برنامه نويسي و همچنين با پيشرفت كردن عقل Microsoft (كه از نظر من بزرگترين كلاه بردار قرن هست) اين تكنولوژي در اختيار ديگران هم قرار گرفت... براي همين در اوايل فقط در Office بود كه از اين امكان استفاده مي شد.

حالا اينا رو گفتم اما ببينيم اصلاً Agent چي هست؟؟!!!

شما اگه از Office استفاده ميكنيد حالا هر كدوم از برنامه هاش كه باشه (Word,Excel,FrontPage,...) يك شكلكي رو ميبينيد كه هميشه نسبت به كارهايي كه انجام ميدين يك سري حركات از خودش نشون ميده كه هم سرگرم كننده هست هم آموزنده. حالا حتماً متوجه شدين كه در مورد چي صحبت ميكنيم (هر چند كه ميدونم ميدونستيد (; ) خوب حالا مي خواهيم ببينيم كه چطور ميشه از اين امكان تو برنامه هاي خودمون استفاده كنيم مثلاً وقتي برنامه داره كار ميكنه يه شكلكي بياد براي كاربر ادا در بياره تا طرف نفهمه كه برنامه چيكار ميكنه (: يا مثلا موقع ذخيره كردن و بازيابي كردن و يا جستجو و ... يك سري حركات مربوط به آن عمل انجام بده...

اينكار خيلي ساده است و فقط كافي هست شما يك Agent رو انتخاب كنيد و در برنامتون تعريفش كنيد و بعد هر كاري كه خواستين رو بهش دستور بدين تا براتون انجام بده . ضمنا شما لازم نيست اصلاً غصه درست كار كردن اون رو بخورين چون خود Windows اونو كنترل ميكنه كه يه وقت كار بدي نكنه ((:

شما نميتونيد كه Agent رو داخل يك جعبه مكالمه (Dialog Box) قرار بدين و فقط ميتونيد جاي اوليه اون رو انتخاب كنيد بعد نمايش بدين و كاربر ميتونه اونو به دلخواه خود تغيير مكان بده با Drag كردن اينكار رو انجام ميده. خوب حالا براي شروع كار به يك سري Agent نياز داريم كه البته همراه ويندوز هميشه يك سري همراه هستند بهترين اونها كه ميتونه كارهاي زيادي انجام بده (منظور حالتهاي زيادي براش تعريف شده) Merlin هست كه يك جادوگر پير مي باشد. براي Download كردن اينها ميتونيد به سايتهايي كه معرفي ميكنم يك سري بزنيد. ضمناً شما خودتون هم ميتونيد يك Agent طراحي بكنيد كه براي اينكار بايد از يك سري نرم افزار استفاده كنيد.

براي اينكه كاربر بتونه از Agent برنامه شما استفاده كنه بايد حتماً Microsoft Agent Server‌ رو نصب كنه. كه البته من تا حالا تو هر ويندوزي كه برنامم رو اجرا كردم نصب شده بوده فكر كنم اين برنامه همراه خود ويندوز هست (; ولي اگه نبود شما ميتونيد يك سري به آدرس زير بزنيد اونجا چيزهاي جالبي در اين مورد داره كه يك مطالعه كنيد بد نيست.

[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]

در اين آدرس اخرين باري كه رفتم مطالب زير بود حالا اگه تا حالا بيلي جون حوصله اش از اونا سر نرفته باشه و عوض نكرده باشد بايد باشه:

- The Agent Server

- The Characters/Agents

- A Text-to-Speech pices

- A Voice command (input) pices



اين مطالب تحت عنوان Microsoft Agent Software Development Kit هست كه در اونجا شما همچنين ميتونيد نرم افزار Microsoft Agent Character Editor رو براي درست كردن Agent دريافت كنيد. در اين مقاله ما در مورد Voice Command‌ (فرمان هاي صوتي) و طراحي Agent صحبت نميكنيم و فقط طرز استفاده از اين امكان رو شرح ميدم كه خودتون بعداً ميتونيد در موردش بيشتر جستجو كنيد. ما براي كارمون فقط احتياج به Agent Server و يك كاراكتر داريم كه اگه روي ويندوزتون ندارين ميتونيد از اينجا Download بكنيد.

خوب حالا ميريم سر اصل مطلب:

بعد از اينكه مطمئن شدين روي ويندوزتون AgentServer رو دارين دلفي رو اجرا كنيد و مراحل زير رو مو به مو انجام بدين:

1- Component|Import ActiveX Control رو انتخاب كنيد.

2- Microsoft Agent Control رو از تو ليست پيدا كنيد و رو ي دكمه Install كليك كنيد.

3- خوب حالا بايد تو قسمت ActiveX يك آيكوني شبيه به MenInBlack داشته باشيد.

خوب تا يادم نرفته اينو بگم كه براي پيدا كردن يك كاراكتر روي ويندوزتون بايد براي acs.* جستجو كنيد كه البته به طور عادي اگر Agent Server نصب باشه توي شاخه Windows يك msagent بايد وجود داشته باشه و داخل اون هم يك شاخه ديگه به نام Char هم هست كه توش يك يا چند كاراكتر وجود داره كه اگر از XP استفاده ميكنيد حتماً يكيش Merlin.acs هست (كه من خيلي بهش علاقه دارم (: ) براي همين ما بايد تو برنامه مون چك كنيم كه آيا اين شاخه وجود داره يا نه اگه وجود داشت ميدونيم كه Agent Server روي ويندوز كاربر نصب هست و ما مي تونيم از Agent استفاده كنيم .

خوب براي اينكار بايد اول ActiveX رو به روي فرم منتقل كنيم با اينكار يك type با نام TAgent به تعاريف فرم اضافه ميشه . بعد بايد يك متغيير تعريف كنيم كه از نوع Boolean باشه تا با اون چك كنيم كه آيا Agent Server نصب هست يا نه براي اينكار ميشه از Code زير استفاده كرد:



TYourObject

private

AgentInstalled: Boolean;

function AgentIsInstalled: Boolean;

procedure CreateAndLoadAgentIfInstalled;

function GetColorDepth: Word;

function GetWinDir: String;

procedure SetFormColor;

function AgentWasClicked



شما ميتونيد روي ويندوز كاربر به دنبال اون شاخه و كاراكتري كه مي خواهيد از او استفاد هكنيد بگرديد و اگه بود كار رو باهاش شروع كنيد اگه هم نبود خوب ديگه كاربر بايد محيط خشك برنامتون رو تحمل كنه (;

حالا مثلاً ما مي خواهيم از Merlin استفاده كنيم :

{-----------------------------------------------}

function TYourObject.AgentIsInstalled: Boolean;

begin

Result := (FileSearch('Merlin.acs',

Format('%s\MSAGENT\CHARS', [GetWinDir]))<>'');

end;



{-----------------------------------------------}

function TYourObject.GetWinDir : string;

var

WinDirZ : array[0..256] of Char;

begin

GetWindowsDirectory(WinDirZ, SizeOf(WinDirZ));

Result := StrPas(WinDirZ);

end;



نكته : در بالا براي بدست آوردن نام شاخه اي كه ويندوز در آن نصب هست از API استفاده شده كه مسير كامل ويندوز را به ما ميدهد.

حال كه فهميديم كاربر امكان استفاده از Agent رو داره مي تونيم كار رو شروع كنيم. در ادامه بايد يك Object براي Agent خودمون بسازيم تا از اين به بعد از اون استفاده كنيم و مجبور نباشيم از ActiveX استفاده كنيم. براي اينكار از كد زير ميشه استفاده كرد:

implementation



uses

AgentDemoConsts,

Registry,

OLECtrls, AgentObjects_TLB;



{-----------------------------------------------}

procedure

TYourObject.CreateAndLoadAgentIfInstalled;

const

RightBias = 80;

TopBias = 70;

var

tp: TPoint;

begin

if (AgentInstalled) and

not (Assigned(RobotAgent)) then begin

RobotAgent := TAgent.Create(Application);

RobotAgent.Characters.Load('Merlin','Merlin.acs');

{ Move the Agent to the center of the screen }

tp.x := (Screen.Width div 2)-(Width div 2);

tp.y := (Screen.Height div 2)-(Height div 2);

with RobotAgent.Characters.Item['Merlin'] do begin

MoveTo(tp.x+RightBias, tp.y+TopBias, 0);

Show(0);

Play('Greet');

Play('Explain');

Speak(SDemoIntro, '');

Play('Pleased');

Play('RestPose');

Speak(SWhisper, '');

Speak(SMonotone, '');

Speak(SMap, '');

end;

end;

end;





چند خط اول كه مشخص هست چه كار ميكنه . اما بعد از اينكه كاراكتر تعريف شد (RobotAgent) اونو به Merlin نسبت ميديم وبعد هم اونو به وسط صفحه نمايش منتقل ميكنيم و حالا ميرسيم به مهمترين قسمت كار كه دستور دهي به Merlin هست.

با استفاده از Play شما ميتونيد به Agent دستور بدين اما براي هر Agnet دستورات متفاوت هست يعني ممكن هست كه دستوارتي كه براي Merlin كار ميكنه براي Robby (كه يكي ديگر از Agent ها هست) كار نكنه. شما اگه كاراكترتون رو خودتون درست ميكنيد خوب پس ليست دستوراتش رو داريد اما اگه اونو از جايي Download ميكنيد حتما ليست دستوارتش هم همراش هست مثلا شما ميتونيد در مورد Merlinو يا Robby و يا چند Agent ديگه از تو همون آدرسي كه در بالا دادم ليست دستوارتش رو بگيريد.

حالا در كد بالا ميبينيد كه در ابتدا از دستور Show استفاده شده اين دستور براي به نمايش در آوردن Agent هست و در تمامي آنها كار ميكنه . بعد با استفاده از Play كارهاي مورد نظرمون رو به Agent‌ ميگيم. مثلاً من در ابتدا با استفاده از دستور Greet از Agent خواستم كه سلام كنه و بعد هم با استفاده از Explain خواستم كه شروع كنه به گفتن يك سري مطالب كه با دستور Speak اونها رو كه در متغيير SDemoIntro قرار داده ام به صورت يك بالون كه بالاي سرش باز ميشه ميگه. شما براي اينكه بگين مطالب رو با چه حالتهايي بخونه مي تونيد از دستواراتي كه در جدول زير آوردم استفاده كنيد:

Addition

Resulting capability

\Chr="Whisper"\

The Agent will whisper the following text.

\Pau=N\

The Agent will pause for the designated number of milliseconds.

\Emp\

The Agent will give special emphasis to the following phrase.

\Chr="Montone"\

The Agent will emphasize nothing at all.

\Map=

The Agent will say one thing, and = "think" another.

خوب حالا براي اينكه بيشتر متوجه بشين در زير يك سري مثال آوردم كه ميتونيد اونها رو در برنامه استفاده كنيد و نقش هر كدوم از دستوارت رو ببينيد:

SFuzzyWuzzy = 'Fuzzy wuzzy was a bear;\Pau=500\ ' +

'fuzzy wuzzy had no hair;\Pau=500\ ' +

'fuzzy wuzzy wasn't very \Emp\fuzzy, \Emp\was he?';

SWhisper = '\Chr="Whisper"\Now I will whisper: ' +

'Whisper whisper whisper.';

SMonotone = '\Chr="Monotone"\Now I will speak in a ' +

'monotone. Pat Paulsen for President.';

SMap = '\Map="I will now continue to speak in ' +

'English, but you will see my words ' +

'translated into German in the balloon above ' +

'my head. How are you today? I am just ' +

'\Emp\dandy!"="Jetzt werde ich zwar immer ' +

'noch in Englisch reden, sie werden ' +

'aber meine Woerte im Balloon obenauf ins ' +

'Deutsch uebersetzt sehen. Wie geht es ' +

'Ihnen heute? Mir geht es ganz gut!"\';



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

ضمنا شما ميتونيد از Event ها هم در Agent استفاده كنيد و مثلا براي رويداد OnClick روي Agent‌ يك چيزي تعريف كنيد.



خوب در آخر از شما كه تا اينجا آمديد متشكرم و يك سري نكات رو هم بايد ذكر كنم :

1- اين مطالب حاصل تجربه خودم و همچنين برگرفته از يك سري مقالاتي بوده كه در اين مورد مطالعه كردم.

2- در مورد استفاده از اين كدهايي كه در اين مقاله آورده ام و همچنين در پايان اين مقاله ضميمه كرده ام هيچ گونه مسئوليتي بعهده من نخواهد بود كه درست كار كنه يا بزنه كامپيوتر شما رو بسوزونه !!!!!

3- استفاده از اين مقاله به شرط ذكرنام و آدرس اصلي مقاله در سايتها و جاهاي ديگر آزاد است .

4- اگه در اين مورد نظري دارين يا حتماً براي من ايميل كنيد خوشحال خواهم شد بشنوم.

Nesta
23-05-2005, 05:26
چگونه تمامي رويدادهاي يك شيء را در زمان اجرا به 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;

Nesta
23-05-2005, 05:27
طريقه بدست آوردن اطلاعات مربوط به هارد ديسک - سي دي رام - فلاپي ديسک
اطلاعاتي که روالهاي زير برمي گرداند عبارتست از شماره سريال - نوع سيستم فايل -
پشتيباني از نام فايلهاي طولاني و نام درايو


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);

Nesta
23-05-2005, 05:30
كمي تاريخچه
FastReport قبلا با نام FreeReport عرضه مي شد و يك محصول رايگان بود. ولي بعدها به FastReport تغيير نام پيدا كرد و به صورت تجاري عرض گرديد. البته هنوز كمپوننت FreeReport توسعه مي يابد و نسخه هاي جديدتر آن را از سايت [ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ] يا [ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ] مى‌توانيد داون لود كنيد.

آشنايي كلي با شكل گزارش سازي در FastReport
اين كمپوننت يك محيط Report Desinger در اختيار شما قرار مي دهد كه با استفاده از آن مي توانيد Reportها را طراحي كنيد، اسكريپت نويسي كنيد و يا فرم هاي جديد براي انتخابي كردن گزارش خود ايجاد كنيد. براي وارد شدن به اين Report Desinger بايد از كمپوننت TfrReport استفاده كنيد. كافي است يك كمپوننت TfrReport روي فرم بگذاريد و روي آن دابل كليك كنيد يا كليد سمت راست را زده و گزينه Design Report را انتخاب كنيد. ممكن است اين محيط كه موسوم به Desinger است در ابتدا كمي شلوغ به نظر بيايد ولي در انتهاي اين مقاله آموزشي كاملا با استفاده از اين Desinger آشنا خواهيد شد.

شما مي توانيد گزارش هاي خود را در فايلهايي با پسوند frf. ضبط كنيد و در موقع نياز هر كدام از آنها را Load نماييد و همچنين اگر برنامه شما تنها يك گزارش دارد مي توانيد آن گزارش را در خود فايل EXE نگهداري كنيد.

ساخت يك گزارش ساده
يك كمپوننت TfrReport را روي فرم قرار دهيد و روى آن دابل كليك كنيد تا به محيط Report Designer برويم. خوب ... مى‌خواهيم براى شروع يك گزارش بسيار ساده بسازيم.

از ToolBar سمت چپ گزينه Insert rectangle object را انتخاب كنيد. آيكن اين گزينه شبيه به آيكن كمپوننتMemo است.
مىبينيد كه وقتى اين كمپوننت را در محل مربوطه قرار مى‌دهيد پنجره اى باز مي شود:

همانند شكل در قسمت بالا تايپ كنيد: "سلام دوستان!" و سپس اين پنجره را ببنديد.
خوب! اولين گزارش خودمون رو ساختيم. حالا به سادگى گزارش را Save كنيد و اسم اون رو بگذاريد Test. اين فايل رو در همون جايى ضبط كنيد كه پروژه تون در اونجا Save شده است.
حالا Designer رو ببنديد و يك Button روي فرمتون بگذاريد و و در اونت OnClick آن كد زير رو بنويسيد:

frReport1.LoadFromFile('Test.frf');
frReport1.ShowReport;

خوب! كار ساخت اولين گزارشمون تمام شد. ما خيلي ساده در ابتدا گزارشى را كه قبلا ساخته بوديم Load كرديم و بعدش هم از متد ShowReport براى نمايش گزارش استفاده كرديم. البته مى‌توانستيم از متد PrintPreparedReportDlg براى چاپ مستقيم گزارش بدون نمايش پيش‌نمايش يا Preview استفاده كنيم.
نكته: در صورتى كه بخواهيم ميتوانم با True كردن پراپرتي StoredInDFM گزارش را در EXE خود ضبط كنيم. در آن صورت لازم نيست گزارش را ضبط كنيم و همچنين احتياجى نيست كه آن را در كد Load بكنيم.
اين حالت تنها وقتى مفيد است كه برنامه شما فقط يك گزارش داشته باشد.
خوب! ما تا حالا اصول استفاده از FastReport رو ياد گرفتيم. در باقي اين مقاله آموزشى گزارش‌هاى پيشرفته‌ترى مى‌سازيم و آرام آرام شما با FastReport احساس راحتى مى‌كنيد.

ساخت يك گزارش ديگر
خوب ... يك كمپوننت TTable رو از پالت BDE روى فرمتون قرار دهيد و پراپرتي DatabaseName آن را برابر DBDEMOS و پراپرتى TableName را برابر Biolife قرار دهيد.
يك كمپوننت TfrReport و همچنين يك كمپوننت TfrDBDataSet روى فرم قرار دهيد و پراپرتى DataSet آن را برابر نام Table1 قرار دهيد و پراپرتى DataSet كمپوننت TfrReport را برابر frDBDataSet1 قرار بدهيد. حالا با كليك بر روى كمپوننت frReport1 وارد محيط Designer شده و Tools>Tools>Insert DB Fields را انتخاب كنيد.
خوب شما انتخاب كنيد و آن را روي فرم قرار دهيد. پنجره اي شبيه به شكل زير نمايش داده مى‌شود:


تمام فيلدها را انتخاب كنيد و OK را بزنيد.....
خوب تقريبا كارمان تمام است. اگر خوب نگاه كنيد مي بينيد كه دو باند روى فرم گزارش اضافه شد كه يكى Page Header و ديگرى Master Data نام دارد. File>Preview را انتخاب كنيد و ببينيد گزارش شما چه شكلى خواهد بود. گزارش خودتان را Save كنيد و از روشى كه قبلا ذكر شد براى نمايش گزارش در زمان اجرا يا Run-Time استفاده كنيد.

ساخت گزارش‌هاى پيشرفته‌تر
به موارد زير توجه كنيد:
1- اگر بخواهيد از كمپوننتهايى مثل RichEdit - Chart - CheckBox و ... در گزارش خود استفاده كنيد بايد كمپوننت مربوطه را روى فرم برنامه خود قرار دهيد.
2- اگر بخواهيد امكان Export گزارش به فرمتهاى HTML - Text - CSV يا DOC را به برنامه خود بدهيد بايد كمپوننت مربوطه را روى فرم برنامه خود قرار دهيد.
3- اگر بخواهيد گزارش Master-Detailى بسازيد بايد از دو باند Master data و Detail data استفاده كنيد.
4- اگر بخواهيد مجموع مقادير يك فيلد رو در انتهاى يك گزارش بنويسيد بايد از يك باند Master footer استفاده كنيد و گزينه Insert rectangle object را انتخاب كنيد. سپس Insert Expression را انتخاب كنيد. Functions را انتخاب كنيد و از تابع Count براى انجام اين كار استفاده كنيد. همچنين مى‌توانيد Variables را انتخاب كنيد و از مواردى همچون شماره صفحه، كل صفحات، تاريخ و ... استفاده كنيد.

اميدوارم اين مقاله بتونه هر چند اندك شما رو با FastReport آشنا كنه

Nesta
23-05-2005, 05:31
يكي از فرمتهاي محبوب وب است و به راحتي مي توان براي ساخت Interfaceها در برنامه از آن استفاده كرد. بعضي از برنامه نويسان معتقدند استفاده از Flash سبب سنگين شدن برنامه، وابستگي برنامه به ActiveX فلش، امكان نداشتن تبادل اطلاعات بين Flash و دلفي و مشكلات ديگري مي شود.
در اين مقاله خواهيد ديد كه به راحتي تمامي اين مشكلات را مي توانيد رفع كنيد.

نصب ActiveX فلش
براي نصب ActiveX فلش به Component>Import ActiveX Control برويد. در ليست مربوطه به دنبال Shockwave Flash بگرديد. در صورتي كه آن را پيدا نكرديد. دكمه Add را زده و به آدرس زير برويد:

WIN_DIRECTORY\System32\Macromed\Flash

و فايل Flash.ocx را انتخاب كنيد و سپس Install را بزنيد.
خوب ... تا به اينجا كار نصب اكتيوايكس فلش تمام است. كمپوننت مربوطه را ميتوانيد در پالت ActiveX پيدا كنيد.
نكته: در صورتي كه شاخه مذكور در كامپيوتر شما وجود ندارد، احتمالا شما Flash Player را نصب نكرده‌ايد.
البته نگران نباشيد، با شيوه اي كه در اين مقاله ذكر شده كاربر شما بدون نياز به نصب Flash Player مي تواند برنامه شما را اجرا كند.

استفاده از اكتيوايكس فلش
اكتيوايكس فلش را مي‌توانيد در پالت ActiveX پيدا كنيد. آن را روي فرمتان قرار دهيد. از پراپرتيMovie ميتوانيد براي Load كردن فايل SWF خود استفاده كنيد.
به باقى پراپرتى‌هاى اكتيوايكس فلش دقت كنيد:
(البته توضيحات پراپرتى‌ها را به صورت انگليسى آورده‌ام. چون نوشتن آنها به صورت فارسى زياد جالب نيست. به خاطر اينكه پر از لغاتى هستند كه ترجمه‌شون غير ممكن است.)

ReadyState (get only)
0=Loading, 1=Uninitialized, 2=Loaded, 3=Interactive, 4=Complete.

TotalFrames (get only) Returns the total number of frames in the movie. This is not available until the movie has loaded. Wait for ReadyState = 4.

FrameNum (get or set) The currently displayed frame of the movie. Setting this will advance or rewind the movie.

Playing (get or set) True if the movie is currently playing, false if it is paused.

Quality (get or set) The current rendering quality (0=Low, 1=High, 2=AutoLow, 3=AutoHigh). This is the same as the QUALITY parameter.

ScaleMode (get or set) Scale mode (0=ShowAll, 1= NoBorder, 2 = ExactFit). This is the same as the SCALE parameter.

AlignMode (get or set) The align mode consists of bit flags. (Left=+1, Right=+2, Top=+4, Bottom=+8). This is the same as the SALIGN parameter.

BackgroundColor (get or set) Override the background color of a movie. An integer of the form red*65536+green*256+blue use -1 for the default movie color.

Loop (get or set) True if the animation loops, false to play once. Same as the MOVIE parameter.
Movie (get or set) The URL source for the Flash Player movie file. Setting this will load a new movie into the control. Same as the MOVIE parameter.


متدها:


Play() Start playing the animation.

Stop() Stop playing the animation.

Back() Go to the previous frame.

Forward() Go to the next frame.

Rewind() Go to the first frame.

SetZoomRect(int left, int top, int right, int bottom) Zoom in on a rectangular area of the movie. Note that the units of the coordinates are in twips (1440 units per inch). To calculate a rectangle in Flash, set the ruler units to Points and multiply the coordinates by 20 to get TWIPS.

Zoom(int percent) Zoom the view by a relative scale factor. Zoom(50) will double the size of the objects in the view. Zoom(200) will reduce the size of objects in the view by one half.

Pan(int x, int y, int mode) Pan a zoomed in movie. The mode can be: 0 = pixels, 1 = % of window.


نصب اكتيوايكس فلش روي كامپيوتر كاربر
براي اين كه كاربر نهايي بتواند از برنامه شما استفاده كند بايد اكتيوايكس فلش را داشته باشد. در واقع شما بايد اكتيوايكس مربوطه را براي او نصب كند. روش كار به اين گونه است كه شما بايد چك كنيد كه آيا كاربر نهايي اكتيوايكس فلش را بر روي دستگاه خود نصب كرده است يا نه و در صورتي كه وي اين اكتيوايكس را ندارد برنامه شما بايد به طور اتوماتيك آن را نصب كنيد.
براي پياده سازي اين روش ما بايد در ابتدا OCX فلش را با استفاده از Resourceها در فايل Exe خود مخلوط كنيم. در صورتي كه شما با Resourceها آشنايي نداريد نگران نباشيد. مراحل زير را انجام دهيد و باقي كار را به دلفي بسپاريد: 1- يك فايل Text بسازيد و اسم آن را SWFActivex.rc بگذاريد
2- خطوط زير را در آن قرار دهيد:

FlashOCX EXTRA Flash.ocx

و فايل Flash.ocx را از مسيري كه قبلا ذكر شد در شاخه پروژه خود قرار دهيد.
3- آن را ضبط كنيد و با استفاده از BRCC32.EXE كه در شاخه Bin محل نصب دلفي وجود دارد، آن را كامپايل كنيد. (خط زير را در Command Line تايپ كنيد يا به سادگي فايل SWFActivex.rc را بر روي فايل BRCC32.EXE دراگ (Drag) كنيد.

BRCC32.EXE MyExeRes.rc

خوب حالا شما يك فايل Resource كامپايل شده داريد به نام SWFActivex.res داريد.
4- خطوط زير را در در سورس كد فرم اصلي خود قرار دهيد:

...
...
implementation
...
...
...
{$R *.dfm}
{$R SWFActivex.RES}
5- حالا اين تابع را به كد خود اضافه كنيد:

function GetResourceFile(S : string; FilePath : string) : Boolean;
var
Res : TResourceStream;
begin
Result := True;
if S <> '' then
begin
if FindResource(hInstance, PChar(S), Pchar('EXTRA')) = 0 then
begin
Result := False;
Exit;
end;
try
Res := TResourceStream.Create(hInstance, S, Pchar('EXTRA'));
except
Result := False;
Exit;
end;
if FileExists(FilePath) then DeleteFile(FilePath);
try
Res.SaveToFile(FilePath);
except
Result := False;
end;
Res.Free;
end;
end;


6- اين تابع را نيز اضافه كنيد:

function GetSystemDir : string;
var
SysPath : PChar;
begin
GetMem(SysPath, MAX_PATH + 1);
GetSystemDirectory(SysPath, MAX_PATH);
Result := StrPas(SysPath)+ '\';
FreeMem(SysPath, MAX_PATH + 1);
end;



7- خوب! حالا بگذاريد به مهمترين قسمت قضيه يعني Register كردن OCX مربوطه بپردازيم. در ابتدا يونيت ActiveX را به ليست uses خود اضافه كنيد. سپس تابع زير را نيز به سورس خود اضافه نماييد.

function RegisterOCX( OCXFileName : string; Flag : Boolean) : Boolean;
var
OCXHand: THandle;
RegFunc: TDllRegisterServer;
OCXFileNamePtr : PChar;
begin
Result := True;
if not FileExists( OCXFileName ) then
begin
Result := False;
Exit;
end;
GetMem(OCXFileNamePtr, Length(OCXFileName) + 1);
StrPCopy(OCXFileNamePtr, OCXFileName);
OCXHand:= LoadLibrary(OCXFileNamePtr);
FreeMem(OCXFileNamePtr, Length(OCXFileName) + 1);
OCXFileNamePtr := nil;
if OCXHand = 0 then
begin
Result := False;
Exit;
end;
if Flag then
RegFunc:= GetProcAddress(OCXHand, 'DllRegisterServer')
else
RegFunc:= GetProcAddress(OCXHand, 'DllUnregisterServer');

if RegFunc = S_OK then
Result := False;

FreeLibrary(OCXHand);
end;


8- اين سه متغيير را نيز به كد خود اضافه كنيد:

var
FilePath : string;
FlashOCX: TShockwaveFlash;




9- تابع زير را نيز اضافه كنيد:

function CreateFlashOCX : Boolean;
var
FilePath : string;
begin
Result := True;
FilePath := GetSystemDir + 'Macromed\Flash\Flash.ocx';
if not GetResourceFile('FlashOCX', FilePath) then
begin
Result := False;
Exit;
end;
try
FlashOCX := TShockwaveFlash.Create(nil);
except
if not RegisterOCX(FilePath, True) then
Result := False
else
try
FlashOCX := TShockwaveFlash.Create(nil);
except
Result := False;
end;
end;
end;




10- كدهاي زير را به انتهاي فايل خود، قبل از .end اضافه كنيد:


initialization
CoInitialize(nil);
if not CreateFlashOCX then
ShowMessage('An Error Occured!' + #13 + 'Program dosent run correctly!');
finalization
if Assigned(FlashOCX) then
begin
try
FlashOCX.Free;
FlashOCX := nil;
except
end;
DeleteFile(FilePath);
end;
CoUninitialize;
end.

end.


11- در اونت OnCreate فرم خودتون به راحتي از كمپوننت مربوطه استفاده كنيد:

FlashOCX.Parent := Form1;
FlashOCX.Movie := ExtractFilePath(Application.ExeName) + 'Main.swf';
FlashOCX.Play;


Resize شدن درست
يكي از مشكلاتي كه ممكن است با اكتيو ايكس فلش پيدا كنيد مشكل Resize شدن است. همه ما مي دانيم كه يكي از مهمترين مزاياي فلش برداري بودن آن است و اين برداري بودن سبب مي شود كه فايل فلش بتواند در هر اندازه به درستي نشان داده شود. ولي متاسفانه فرم خود را در RunTime تغييراندازه مي دهيد فايل Flash تغيير اندازه نمي يابد. در اين جا يك راه حل ساده براي حل اين مشكل بيان شده كه به خوبي كار ميكند. كافي است كمپوننت فلش را در يك پانل قرار دهيد و پراپرتي Align آن را برابر alClient بگذاريد. حالا پراپرتي Anchor پانل خود را به گونه‌اي تنظيم كنيد كه مايل هستيد كمپوننت فلش Resize شود. سپس در اونت OnResize فرم خود، خطوط زير را درج كنيد:
FlashOCX.Parent := nil;
FlashOCX.Parent := Self;


غيرفعال كردن كليك سمت راست
مساله ديگرى كه ذهن بسيارى از برنامه‌نويسان را مشغول مى‌كند منوى Popup فلش است. غيرفعال كردن اين منو بسيار ساده است. كافي است يك كمپوننت TApplicationEvents را روي فرم خود قرار دهيد و كد زير را در اونت OnMessage اين كمپوننت بنويسيد:


if (Msg.message = WM_RBUTTONDOWN) and (Msg.hwnd := FlashOCX) then
begin
PopupMenu1.Popup(Mouse.CursorPos.X, Mouse.CursorPos.Y);
Handled := True;
end;



ارتباط بين Flash و دلفى
يكى از مسائل بسيار مهم و اساسى ديگر برقرارى ارتباط بين Flash و دلفي است. فرض كنيد در فايل SWF خود چند Button داشته باشيد و بخواهيد وقتى كاربر روى هر كدام از اين اونتها كليك كرد فرم خاصى باز شود. در اين صورت چه بايد بكنيد. پياده سازى اين كار بسيار ساده است. كافى است در Flash براى هر كدام از دكمه‌هاى خود يك Action تعريف كنيد و از دستور FSCommand استفاده نماييد. از يك مقدار دلخواه مثل fMatn يا fSearch استفاده كنيد و در دلفى نيز از اونت OnFSCommand به صورت زير استفاده كنيد:

if command = 'fMain' then fMain.ShowModal;
if command = 'fSearch' then fSearch.ShowModal;




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

Nesta
23-05-2005, 05:33
آيا به دنبال راهى مى‌گرديد كه اپلت‌هاى كنترل پانل را از داخل برنامه تان بدون باز كردن خود كنترل پانل باز كنيد؟

آيا احتياج داريد كه كاربرانتان بتوانند تاريخ/زمان سيستم را تغيير دهند، يك مودم اضافه كنند يا تنظيمات مربوط به joystick را تغيير دهند؟ يك راه ساده براي انجام چنين كارهاي بدون اين كه كاربر را مجبور كنيد Control Panel را باز كند وجود دارد. مسئله جالب اين است كه شما مي توانيد از اين روش در هر ويندوزى و يا در يك BATch فايل ساده استفاده كنيد.

اجرا كردن دستور زير در برنامه شما سبب انجام اين حقه خواهد شد (CPL نام فايلهاي اپلت كنترل پانل است. ليستى از اين فايلها را مى‌توانيد در انتهاى اين مقاله پيدا كنيد. مضافا اينكه مي توانيد به دنبال فايلهايى با پسوند CPL در شاخه ويندوز Search كنيد و ليست كامل فايلهاي را بيابيد)


rundll32.exe shell32.dll,Control_RunDLL CPL


به عنوان مثال براى نشان دادن پنجره "تنظيمات تاريخ/زمان" از كد زير استفاده كنيد:


rundll32.exe shell32.dll,Control_RunDLL timedate.cpl

مثال كد دلفي / C++ Builder
يونيت زير را در پروژه خود قرار دهيد و تابع RunControlPanelApplet را همراه با نام Applet مورد نظرتان صدا كنيد تا باز شود. به عنوان مثال: RunControlPanelApplet( 'timedate.cpl' );


unit open_cpl;

interface

function RunControlPanelApplet(
sAppletFileName : string) : integer;

implementation

uses Windows;

function RunControlPanelApplet(
sAppletFileName : string) : integer;
begin
Result :=
WinExec(
PChar('rundll32.exe shell32.dll,'+
'Control_RunDLL '+sAppletFileName),
SW_SHOWNORMAL);
end;

end.


چگونه نام فايلهاى اپلت را پيدا كنيم؟
اپلتهاى كنترل پانل پسوند CPL دارند. براى پيدا كردن ليستى از اپلتهاى نصب شده بر روي سيستم خود به شاخه SYSTEM (در ويندوزهاي 95) يا شاخه SYSTEM32 (در ويندوزهاي NT) برويد و به دنبال فايلهايى بگرديد كه پسوند CPL دارند.
در زير ليستي از اپلتهاى عمومى را در ويندوز 95 و ويندوز NT مى‌بينيد:


access.cpl: Accessibility Properties
appwiz.cpl: Add/Remove Programs Properties
desk.cpl: Display Properties
intl.cpl: Regional Settings Properties
joy.cpl: Joystick Properties
main.cpl: Mouse Properties
mmsys.cpl: Multimedia Properties
modem.cpl: Modems Properties
sysdm.cpl: System Properties
timedate.cpl: Time/Date Properties

خوب ديگه! تموم شد....

Nesta
23-05-2005, 05:34
چگونه از فايلهاى PDF در دلفى استفاده كنيم؟
1. دلفى را آغاز كرده و Component | Import ActiveX Control را انتخاب كنيد.
2. به دنبال "(Acrobat Control for ActiveX (Version x.x" بگرديد و به Install را بزنيد.
3. نام پالتى كه كمپوننت مورد نظر بايد در آن نصب شود را انتخاب كنيد.
4. Install را كليك كنيد.
5. Packageي كه قرار است كمپوننت در آن نصب شود را انتخاب كنيد يا يك Package جديد براى كنترل جديد TPdf بسازيد.
6. بر روي OK كليك كنيد.
7. دلفى به شما پيغام مى‌دهد كه آيا مايل به Rebuild كردن Package جديد/تغييريافته هستيد؟
8. Yes را كليك كنيد. دلفى به شما پيغام مى‌دهد كه كمپوننت TPdf نصب شده است.
9. Package را ببنديد و به دلفى اجازه دهيد كه آن را Save كند.
10. حالا كمپوننت در تب ActiveX موجود مى‌باشد.
13. كمپوننت TPdf را روي فرم بكشيد.
14. با استفاده از Object Inspector پراپرتي src را مطابق آدرس يك فايل PDF كه روى كامپيوتر شما يا وب موجود مى‌باشد قرار دهيد. حالا تنها كارى كه بايد انجام دهيد تغيير اندازه كمپوننت مورد نظر است.



نكات:
1. اگر شما ActiveX مربوطه را نداريد، همين حالا آن را از سايت [ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ] داون لود كنيد. چون براي اين مثال ضرورى است.
2. مي‌توانيد آخرين مرحله (مرحله 14) را در زمان اجرا يا RunTime انجام دهيد. بنابراين شما مى‌توانيد هر فايلى را در اجرا باز كرده و آنرا تغيير اندازه دهيد.

Nesta
23-05-2005, 05:36
پس از مطالعه اين مقاله خواهيد آموخت چگونه از دلفي براي توليد صفحات ديناميك وب مبتني بر تكنولوژي ASP.NET مايكروسافت استفاده كنيد .

مرحله اول : قبل از هركار بايد سيستم ASP.NET را از وجود دلفي به عنوان يكي از زبانهاي اسكريپت نگاري تحت NET. مطلع سازيد .

ASP.NET براي اجراي برنامه ها به دنبال فايلي با نام web.config خواهد گشت كه جزئيات زبانهاي مورد استفاده سيستم در آن ثبت شده است . اين فايل XML-Based بايد براي معرفي دلفي به سيستم تغيير كند .

كد زير نمونه خامي از اين نوع فايل را نمايش ميدهد :

كد:



<configuration>

<configSections>

<section name="appSettings"

type="System.Configuration.NameValueFileSectionHandler,

System, Version=1.0.3300.0,

Culture=neutral, PublicKeyToken=b77a5c561934e089" />

<section name="sessionState"

type="System.Web.SessionState.SessionStateSectionHandler ,

System.Web, Version=1.0.3300.0, Culture=neutral,

PublicKeyToken=b03f5f7f11d50a3a"

allowDefinition="MachineToApplication" />

</configSections>



<appSettings>

<add key="dsn" value="localhost;uid=MyUserName;pwd=;" />

<add key="msmqserver" value="server\myqueue" />

</appSettings>



<sessionState cookieless="true" timeout="10" />

</configuration>





فايل مورد نظر براي سازگاري با دلفي بايد به اين شكل باشد :



كد:



<configuration>

<system.web>

<compilation debug="true">

<assemblies>

<add assembly="DelphiProvider" />

</assemblies>

<compilers>

<compiler language="Delphi" extension=".pas"

type="Borland.Delphi.DelphiCodeProvider,DelphiProvider" />

</compilers>

</compilation>

</system.web>

</configuration>




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



مرحله دوم : در محيط ويژوال استوديو ( .. والبته اگر تمايل داريد Notepad !!!!! ) پروژه وب جديدي باز كنيد و يك تكست باكس - يك كليد - يك ليبل روي فرم خود قرار داده و تابع click را به رويداد OnClick كليد فشاري نسبت دهيد . نام تكست باكس را اديت وان و نام ليبل را مسج بگذاريد . فايل حاصل را بصورت زير ويرايش كنيد :



كد:


<html>

<script language="Delphi" runat="server">

procedure Click(Sender: System.Object; E: EventArgs);

begin

Message.Text := Edit1.Text;

end;

</script>

<body>

<form runat="server">

<asp:textbox id="Edit1" runat="server"/>

<asp:button text="Click Me!" OnClick="Click" runat="server"/>

</form>

<p><b><asp:label id="Message" runat="server"/></b></p>

</body>

</html>




فايل را با نام Test.AspX ذخيره كرده و اجرا كنيد . ( براي اجرا كرده برنامه هاي ASP.NET بايد IIS و NET. Run Times را قبلا نصب و تنظيم كرده باشيد !

... [ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ])

مجموعه كامپايلر دلفي و ASP.NET كد زير را توليد و كامپايل (!) ميكنند :

كد:


unit ASP;



interface



uses System.Collections, System.Collections.Specialized, System.Configuration,

System.Text, System.Text.RegularExpressions, System.Web, System.Web.Caching,

System.Web.SessionState, System.Web.Security, System.Web.UI, System.Web.UI.WebControls,

System.Web.UI.HtmlControls, System.Globalization;



var

editdemo_aspx___autoHandlers: Integer;

editdemo_aspx___intialized: Boolean = False;

editdemo_aspx___fileDependencies: System.Collections.ArrayList;

type

editdemo_aspx = class(System.Web.UI.Page, System.Web.SessionState.IRequiresSessionState)

protected

Edit1: System.Web.UI.WebControls.TextBox;

__control3: System.Web.UI.WebControls.Button;

__control2: System.Web.UI.HtmlControls.HtmlForm;

Message: System.Web.UI.WebControls.Label;

procedure ButtonClick(Sender: System.Object; E: EventArgs);

public

constructor Create;

function get_AutoHandlers: Integer; override;

function get_ApplicationInstance: System.Web.[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ] virtual;

function get_TemplateSourceDirectory: System.String; override;

procedure set_AutoHandlers(Value: Integer); override;

protected

property AutoHandlers: Integer read get_AutoHandlers write set_AutoHandlers;

property ApplicationInstance: System.Web.[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ] read get_ApplicationInstance;

public

property TemplateSourceDirectory: System.String read get_TemplateSourceDirectory;

private

function __BuildControlEdit1: System.Web.UI.Control;

function __BuildControl__control3: System.Web.UI.Control;

function __BuildControl__control2: System.Web.UI.Control;

function __BuildControlMessage: System.Web.UI.Control;

procedure __BuildControlTree(__ctrl: System.Web.UI.Control);

protected

procedure FrameworkInitialize; override;

public

function GetTypeHashCode: Integer; override;

end;



implementation


procedure editdemo_aspx.ButtonClick(Sender: System.Object; E: EventArgs);

begin

Message.Text := Edit1.Text;

end;

constructor editdemo_aspx.Create;

var

dependencies: System.Collections.ArrayList;

begin

inherited Create;



if (ASP.editdemo_aspx___intialized = False) then

begin

dependencies := System.Collections.ArrayList.Create;

dependencies.Add('d:\vslive\editdemo.aspx');

ASP.editdemo_aspx___fileDependencies := dependencies;

ASP.editdemo_aspx___intialized := True;

end;

Self.Server.ScriptTimeout := 30000000;

end;



function editdemo_aspx.get_AutoHandlers: Integer;

begin

Result := ASP.editdemo_aspx___autoHandlers;

end;



function editdemo_aspx.get_ApplicationInstance: System.Web.[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]

begin

Result := Self.Context.ApplicationInstance as System.Web.[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]

end;



function editdemo_aspx.get_TemplateSourceDirectory: System.String;

begin

Result := '/vslive';

end;



procedure editdemo_aspx.set_AutoHandlers(Value: Integer);

begin

ASP.editdemo_aspx___autoHandlers := Value;

end;



function editdemo_aspx.__BuildControlEdit1: System.Web.UI.Control;

var

__ctrl: System.Web.UI.WebControls.TextBox;

begin



__ctrl := System.Web.UI.WebControls.TextBox.Create;

Self.Edit1 := __ctrl;

__ctrl.ID := 'Edit1';

__ctrl.Width := System.Web.UI.WebControls.Unit.Parse('300px', System.Globalization.CultureInfo.InvariantCulture) ;

Result := __ctrl;

end;



function editdemo_aspx.__BuildControl__control3: System.Web.UI.Control;

var

__ctrl: System.Web.UI.WebControls.Button;

begin



__ctrl := System.Web.UI.WebControls.Button.Create;

Self.__control3 := __ctrl;

__ctrl.Text := 'Click Me!';

__ctrl.add_Click(Self.ButtonClick);

Result := __ctrl;

end;



function editdemo_aspx.__BuildControl__control2: System.Web.UI.Control;

var

__parser: System.Web.UI.IParserAccessor;

__ctrl: System.Web.UI.HtmlControls.HtmlForm;

begin



__ctrl := System.Web.UI.HtmlControls.HtmlForm.Create;

Self.__control2 := __ctrl;

__parser := __ctrl as System.Web.UI.IParserAccessor;

__parser.AddParsedSubObject(System.Web.UI.LiteralC ontrol.Create(''#13#10' '));

Self.__BuildControlEdit1;

__parser.AddParsedSubObject(Self.Edit1);

__parser.AddParsedSubObject(System.Web.UI.LiteralC ontrol.Create(''#13#10' '));

Self.__BuildControl__control3;

__parser.AddParsedSubObject(Self.__control3);

__parser.AddParsedSubObject(System.Web.UI.LiteralC ontrol.Create(''#13#10' '));

Result := __ctrl;

end;



function editdemo_aspx.__BuildControlMessage: System.Web.UI.Control;

var

__ctrl: System.Web.UI.WebControls.Label;

begin



__ctrl := System.Web.UI.WebControls.Label.Create;

Self.Message := __ctrl;

__ctrl.ID := 'Message';

Result := __ctrl;

end;



procedure editdemo_aspx.__BuildControlTree(__ctrl: System.Web.UI.Control);

var

__parser: System.Web.UI.IParserAccessor;

begin

__parser := __ctrl as System.Web.UI.IParserAccessor;

__parser.AddParsedSubObject(System.Web.UI.LiteralC ontrol.Create('<html>'#13#10' '));

__parser.AddParsedSubObject(System.Web.UI.LiteralC ontrol.Create(''#13#10' <body>'#13#10' '));

Self.__BuildControl__control2;

__parser.AddParsedSubObject(Self.__control2);

__parser.AddParsedSubObject(System.Web.UI.LiteralC ontrol.Create(''#13#10' <p><b>'));

Self.__BuildControlMessage;

__parser.AddParsedSubObject(Self.Message);

__parser.AddParsedSubObject(System.Web.UI.LiteralC ontrol.Create('</b></p>'#13#10' </body>'#13#10'</html>'#13#10));

end;



procedure editdemo_aspx.FrameworkInitialize;

begin

Self.__BuildControlTree(Self);

Self.FileDependencies := ASP.editdemo_aspx___fileDependencies;

Self.EnableViewStateMac := True;

end;



function editdemo_aspx.GetTypeHashCode: Integer;

begin

Result := -764444463;

end;



end.



كد فوق صرفا زماني قابل رويت است كه خطاي دستوري در برنامه دلفي خود داشته باشيد و وب سرور ضمن ارائه Error مربوط سورس كد را نير به شما نشان خواهد داد و در بقيه موارد راهي براي ديدن اين كد وجود ندارد و برنامه شما بصورت اسكريپت AspX كامپايل شده كه به زبان دلفي نوشته شده است قابل استفاده است .



هر چند هنوز محصول جامع و قابل اطمينان بورلند براي سازگاري محصولاتش با دات نت معرفي نشده است و احتمالا جزئيات موجود در .Net Preview نيز تغيير خواهند كرد اما اميد است توضيحات فوق تصوير نسبتا روشني از آنچه در آينده اي نزديك از تركيب تكنولوژي مايكروسافت و كامپايلر بورلند نصيبتان خواهد شد ايجاد كرده باشد .



به دو مثال زير نيز توجه كنيد :



الف)



يكي از اشيا مفيد همراه ويژوال استوديو براي توسعه وب Calendar ميباشد . يك نمونه از آن را روي فرم وب خود گذاشته و پس از نسبت دادن مقادير مناسب به خواص پايه اي آن كد مناسب دلفي را براي توليد خروجي با عنوان تاريخ انتخاب شده توسط كاربر و حركت به سمت تاريخ مورد نظر كاربر را به شكل زير بنويسيد :



كد:


<script language="Delphi" runat="server">

procedure Calendar1Selected(Sender: System.Object; E: EventArgs);

begin

Label1.Text := 'Delphi for .NET says you picked ' + Calendar1.SelectedDate.ToString('D');

end;



procedure Button1Click(Sender: System.Object; E:EventArgs);

begin

Calendar1.VisibleDate := System.Convert.ToDateTime(Edit1.Text);

Label1.Text := 'Delphi for .NET says you set ' + Calendar1.VisibleDate.ToString('D');

end;

</script>



<body style="font:18pt Verdana">

<form runat="server">

<center>

<h1>Delphi for .NET running in ASP.NET</h1>

<p>Please pick a date</p>

<asp:Calendar id="Calendar1" runat="server" ForeColor="#0000FF" BackColor="#FFFFCC"

OnSelectionChanged="Calendar1Selected">

<TodayDayStyle Font-Bold="True"/>

<NextPrevStyle ForeColor="#FFFFCC"/>

<DayHeaderStyle BackColor="#FFCC66"/>

<SelectedDayStyle ForeColor="Black" BackColor="#CCCCFF"/>

<TitleStyle Font-Size="14pt" Font-Bold="True" ForeColor="#FFFFCC" BackColor="#990000"/>

<OtherMonthDayStyle ForeColor="#CC9966"/>

</asp:Calendar>

<p><asp:TextBox id="Edit1" width=200 runat="server"/>

<asp:Button text="Set date" id="Button1" OnClick="Button1Click" runat="server" />

</p>

<p><asp:Label id="Label1" runat="server"/></p>

</center>

</form>

</body>



خروجي برنامه ASP.NET اي خواهد بود كه در محيط ويژوال استوديو توليد شده و از كامپوننت تقويم طراحي شده با #C استفاده ميكند و پياده سازي آن توسط دلفي انجام شده است .

ب)

اگر آشنائي مقدماتي با محيط ويژوال استوديو داشته باشيد ميدانيد كه اين محيط براي توليد سريع محتواي وب مبتني بر بانكهاي اطلاعاتي كامپوننتهاي خاصي جهت نمايش و ويرايش داده ها دارد .



يك نمونه از كامپوننت DataGrid را و يك نمونه TextBox را به فرم مثال قبلي ( تقويم ) اضافه كنيد . كد دلفي نوشته شده با بانك اطلاعاتي معروف Northwind موجود در سيستم ارتباط برقرار ميكند . ( بايد اسكوئل سرور 2000 نصب شده باشد ! ) .

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


<%@Import Namespace="System.Data"%>

<%@Import Namespace="System.Data.SqlClient"%>



<script language="Delphi" runat="server">

const

ProdName = 'Delphi for .NET';

DispFields = 'OrderID, CustomerID, ShipName, ShipCity, ShipCountry';



procedure DateSelected(Sender: System.Object; E: EventArgs);

begin

Label1.Text := ProdName + ' says you picked ' + Calendar1.SelectedDate.ToString('D');

DataGrid1.DataSource := GetOrders(Calendar1.SelectedDate);

DataGrid1.DataBind;

end;



procedure Button1Click(Sender: System.Object; E:EventArgs);

begin

Calendar1.VisibleDate := System.Convert.ToDateTime(Edit1.Text);

Label1.Text := ProdName + ' says you set ' + Calendar1.VisibleDate.ToString('D');

end;



procedure Button2Click(Sender: System.Object; E:EventArgs);

begin

DisplayFields.Text := DispFields;

end;



function GetOrders(Date : DateTime) : DataSet;

var

Adapter : SqlDataAdapter;

begin

Adapter := SqlDataAdapter.Create(

'select ' + DisplayFields.Text + ' from Orders '+

'where OrderDate = ''' + date.ToString('d')+'''',

'Server=(local);Database=Northwind;Trusted_Connect ion=yes');

Result := DataSet.Create;

Adapter.Fill(Result);

end;



</script>



<body style="font:18pt Verdana">

<form runat="server">

<h1><%=ProdName %> with a Calendar, DataGrid, & SqlClient in ASP.NET</h1>

<table>

<tr valign="top"><td>

<p><b>Pick a date</b></p>

<asp:Calendar id="Calendar1" runat="server" ForeColor="#0000FF" BackColor="#FFFFCC"

OnSelectionChanged="DateSelected">

<TodayDayStyle Font-Bold="True"/>

<NextPrevStyle ForeColor="#FFFFCC"/>

<DayHeaderStyle BackColor="#FFCC66"/>

<SelectedDayStyle ForeColor="Black" BackColor="#CCCCFF"/>

<TitleStyle Font-Size="14pt" Font-Bold="True" ForeColor="#FFFFCC" BackColor="#990000"/>

<OtherMonthDayStyle ForeColor="#CC9966"/>

</asp:Calendar>

<p><asp:TextBox id="Edit1" width=150 runat="server"/>

<asp:Button text="Set date" id="Button1" OnClick="Button1Click" runat="server" />

</p>

</td><td valign="top">

<p><b>Display fields:</b> <asp:TextBox id="DisplayFields"

text="OrderID, CustomerID, ShipName, ShipCity, ShipCountry" width=500 runat="server"/>

<asp:Button text="Reset fields" id="Button2" OnClick="Button2Click" runat="server" /></p>

<asp:DataGrid id="DataGrid1" runat="server" BorderColor="#FFCC66" ForeColor="#0000FF">

<HeaderStyle ForeColor="#FFFFCC" BackColor="#990000"/>

</asp:DataGrid>

</td></tr></table>

<p><asp:Label id="Label1" runat="server"/></p>

</form>

</body>


بخاطر داشته باشيد كه خطوط :
كد:



<%@Import Namespace="System.Data"%>

<%@Import Namespace="System.Data.SqlClient"%>



درست مانند SqlConnection و ClientDataset محيط دلفي عمل كرده و ارتباط با بانك داده ها و ظرفي براي استخراج داده ها فراهم مي آورند .

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

Nesta
23-05-2005, 05:37
به هر دليل امکان دارد يک برنامه نويس دلفي تصميم بگيرد - يا مجبور شود - که با ويژوال بيسيک برنامه بنويسد. در ابتدا اجازه دهيد به مساله اي بپردازيم که شايد همه ما به نحوي با آن برخورد کرده ايم، اسم اين حالت يا احساس را چه ميتوان گذاشت! مشخص نيست، ولي اجازه دهيد ساده بگوييم احساس برتري برنامه نويسان زبانهاي مختلف نسبت به برنامه نويسان ويژوال بيسيک. هر زبان برنامه نويسي برتريها و ضعفهاي مخصوص به خود را دارد. فرض کنيم قرار بر اين باشد که يک بازي نوشته شود، براي يک بازي جدي استفاده از ويژوال بيسيک با توجه به سرعت پايين برنامه هاي کامپايل شده آن منطقي به نظر نمي رسد، خوب در اين حالت از دلفي استفاده ميشود. يا در زماني که بخواهيم با يک زبان برنامه نويسي بر اساس کلاسها و اشياء (Object Oriented) واقعي کار کنيم، واضح است که دلفي يکي از بهترين انتخابهاست و در اين مورد ويژوال بيسيک بازنده حقيقي است (در ويژوال بيسيک هر چند از اشياء استفاده شده است اما مفهوم کلاسها، ارث بري و ... رعايت نشده اند). حال فرض کنيم قرار بر نوشتن برنامه اي ساده براي کار با يک پايگاه داده اي Microsoft Access باشد وبايد خيلي سريع هم آماده شود، کدام را انتخاب کنيم؟ جواب يک برنامه نويس دلفي کاملا واضح است! اما شايد اگر در کنار دلفي با ويژوال بيسيک هم کار کرده باشد نظر ديگري داشته باشد. در هر دو انتخاب ما کار با پايگاههاي داده اي پيش بيني شده است، هر دو نيز از قابليتهاي معيني براي کار برخوردار هستند که براي نوشتن برنامه ما کافي هستند. اگر با هر دو زبان کار کرده باشيد حتما قبول داريد نوشتن اين برنامه با ويژوال بيسيک به مراتب سريعتر از دلفي پايان ميپذيرد. خواهش ميکنم! قبل از اينکه من هدف حمله کفشهاي شما قرار بگيرم چند دقيقه اي تحمل کنيد و به بقيه بحث هم توجه کنيد...
بد هم نيست اگر يک برنامه نويس دلفي با ويژوال بيسيک هم برنامه نويسي کند، ويژوال بيسيک هم نقاط قوتي دارد که گاهي به برنامه نويس کمک ميکند. بعضي مواقع برنامه ها با ويژوال بيسيک خيلي سريعتر آماده ميشوند و براي برنامه نويسان دلفي يادگيري ويژوال بيسيک آسان است چون به هر حال امکانات و قابليتهاي آن به مراتب کمتر از دلفي است. ويژوال بيسيک يک زبان مبتني بر اشياء به معناي واقعي اينگونه زبانها نيست. ويژوال بيسيک از اشاره گرها استفاده نميکند، و همين آنرا به يک زبان آسان براي کار تبديل کرده است و البته کمي با قابليت! اما در همه برنامه ها وجود اشاره گرها و OOP (Object Oriented Programming) ضروري نيست. VB هم يکي از زبانهاي RAD(Rapid Application Development) است و آماده کردن برنامه ها با آن به نسبت سريعتر از دلفي است. راستي! گاهي نسخه اجرايي برنامه هاي ويژوال بيسيک از معادل دلفي آن کم حجم تر ميشود! البته دليل اينست که مستقل نيستند و يک کتابخانه زمان اجرا با حجمي در حدود يک مگا بايت را يدک ميکشند (مثلا در VB6 فايل msvbvm60.dll) و اين فايل بايد در کامپيوتر مورد نظر براي اجرا باشد.
در هر حال آشنايي با VB به عنوان يک زبان برنامه نويسي هم سطح دانش شما را در زمينه برنامه نويسي بالا ميبرد و هم ميبينيد که ويژوال بيسيک هم بدک نيست و فقط يک بيسيک تحت ويندوز نيست و به مراتب بيشتر از تغيير دلفي در مقايسه با پاسکال تحت DOS نسبت به بيسيک قديمي تغيير کرده است.


با VB آشنا شويم

خوب! ويژوال بيسيک همانگونه که از نام آن پيداست بر پايه BASIC ساخته شده است. اما در واقع بسيار گسترده تر از آن است. اجازه دهيد طرح کلي VB را بررسي کنيم. در VB بر خلاف دلفي بخش مربوط به unitها را نداريم. علاوه بر اين، حتي بخش VAR را براي تعاريف متغيرها نداريم! اين کار در هر جاي برنامه امکان پذير است، حتي اگر تمايل نداريد ميتوانيد اصلا اين کار را انجام ندهيد. مشخص کردن نوع متغير در VB به صورت اتوماتيک انجام ميشود.

بد نيست يک مثال از قطعه برنامه اي در اين دو زبان را بررسي کنيم. يک تابع:

Function AddNumbers( Num1: Integer; Num2: Integer): Integer;
Var
Num3: Integer;
Begin
Num3 := Num1 + Num2;
Result := Num3;
End;

FUNCTION AddNumbers( Num1 AS Integer, Num2 AS Integer) AS Integer
DIM Num3 AS Integer
Num3 = Num1 + Num2
AddNumbers = Num3
END FUNCTION

در کد VB علامت ";" در انتهاي دستورات قرار نميگيرد به اين دليل که VB بر اساس خطوط کار ميکند (اصطلاحا Line Based است) يعني دستورات چند خطي ندارد (البته اين مساله راه حلي دارد که از بحث خارج است). نکته دوم و بسيار مهم Begin و End در کد VB مشاهده نميشود و در واقع مجموعه دستورات پشتيباني نميشوند.
روش معرفي متغيرها در VB که در هر جاي برنامه امکان پذير است به صورت زير ميباشد:

Dim As


نکته ديگر اينست که در VB مانند اکثر زبانها و بر خلاف پاسکال از علامت = استفاده ميشود ( نه از := ). همچنين در VB هم - مانند دلفي - مقدار بازگشتي تابع در متغيري با نام خود تابع بازميگردد.
از بخشهاي مهم يک زبان برنامه نويسي دستورات شرطي آن است. در دلفي دستورات با If … Then شروع شده و دستورات در يک مجموعه که با Begin و End مشخص ميشوند قرار ميگيرند و امکان استفاده از Else هم پيش بيني شده است:

If a = 1 Then
begin
a := 0;
Text := ‘Hello World’;
end
Else
a := a + 1;

IF a = 1 THEN
a = 0
Text = "Hello World"
ELSE
a = a + 1
END IF

تفاوت آشکار است، باز هم عدم استفاده از Begin و End در کد VB، همچنين لزوم وجود END IF در پايان مجموعه شرطي و نکته مهم؛ استفاده از علامت (") در VB براي نمايش عبارات متني با جاي (‘) در دلفي. به نظر ميرسد تنها نکته گيج کننده عدم وجود Begin و End باشد. نوبتي هم باشد بايد حلقه ها را بررسي کنيم:

For i := 1 To 100 Do
Begin
a = i * 2;
Text := ‘Hello World’
End;

FOR i = 1 TO 100
a = i * 2
Text = "Hello World"
NEXT i

اولين تفاوتي که به چشم ميخورد عدم استفاده از Do در قالب دستور FOR در VB است. نکته ديگر مشخص شدن انتهاي حلقه با استفاده از دستور NEXT است. کليه دستورات مابين FOR و NEXT در حلقه قرار دارند. اما در مورد Repeat … Until کافيست از Do … Loop Until استفاده شود!
اما مساله بعد Procedureهاي دلفي هستند. معادل Procedure دلفي در VB از SUB(Subroutine) استفاده ميشود. و باقي مثل تابعي است که در بالا ديديم و در پايان آن هم از END SUB استفاده ميشود.
در توابع VB نکته مهم اينست که متغير Result نداريم و بايد حتما از نام همان تابع براي بازگرداندن مقدار استفاده کرد.
در مورد آرگومانهاي توابع و SUBها بايد دقت کرد به جاي (;) که در دلفي استفاده ميشود، اينجا بايد (,) را به کار برد و باقي مثل تعريف متغير در VB بدون استفاده از DIM است.
شايد بد نباشد مثالي از SUB هم ببينيد:

SUB MakeSound
Beep
END SUB

به نظر ميرسد مسائل اساسي بررسي شدند، باقي به عهده خودتان!
اما نکات زير را به خاطر داشته باشيد:
از (;) در انتهاي خطوط استفاده نکنيد. همانگونه که گفته شد VB به تغيير خط حساس است، يعني عبارت زير نيز ايجاد خطا ميکند:

IF (a = 1) AND (b = 2) AND (c = 3)
AND (d = 4) AND (e = 5) THEN
Beep
END IF

و بايد به صورت زير باشد:

IF (a = 1) AND (b = 2) AND (c = 3) AND (d = 4) AND (e = 5) THEN
Beep
END IF

البته همانطور که گفته شد براي ايجاد دستورات چند خطي راه حلي در نظر گرفته شده است و آن استفاده از (_) (Under-line/Underscore) است:

IF (a = 1) AND (b = 2) AND (c = 3)_
AND (d = 4) AND (e = 5) THEN
Beep
END IF

فراموش نکنيد در VB امکان استفاده از مجموعه دستورات را نداريد و تنها مجموعه ها عبارتند از:
IF…END IF, FOR…NEXT, DO…LOOP UNTIL, DO…LOOP WHILE, FUNCTION…END FUNCTION, SUB…END SUB

خوب فکر کنم کافي باشد، اگر علاقه مند شديد کتب متعدد ويژوال بيسيک راهنماي خوبي براي شما هستند...
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]


کيفيت مقاله :

Nesta
23-05-2005, 05:38
چگونه يك HotKey يا ميان بر سيستم درست كرده و آن را مديريت كنيم؟ (كه در تمامي برنامه ها كار كند)
مرجع: [ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ] p


{**********************

Copyright © by Jim McKeeth Licensed under LGPL
( [ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ] )

Demo of creating a system wide hotkey or shortcut
This was written in Delphi 7,
but should work in most other versions
(but obviously not Kylix)
You need a form with
1) a THotKey named HotKey1
2) a TCheckBox named CheckBox1
To demo
1) Change the hotkey in the value
2) Check the box
3) Minimize the application
4) Press the hot key
5) Be impressed
---------}
unit SystemHotKeyUnit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics,
Controls, Forms, StdCtrls, ComCtrls, Dialogs,
// Menus need to be added for calls in the code
Menus;

type
TForm1 = class(TForm)
HotKey1: THotKey;
CheckBox1: TCheckBox;
procedure FormCreate(Sender: TObject);
procedure CheckBox1Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
protected
// Handle the global hot key
messages when they are sent to the window
procedure HotyKeyMsg(var msg:TMessage); message WM_HOTKEY;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

var
myAtom: integer;

function ShiftState2Modifier(const Shift: TShiftState):Word;
begin
Result := 0;
if ssShift in Shift then
Result := Result or MOD_SHIFT;
if ssAlt in Shift then
Result := Result or MOD_ALT;
if ssCtrl in Shift then
Result := Result or MOD_CONTROL;
end;

function GetShortCutKey(ShortCut: TShortCut):Word;
var
shift: TShiftState;
begin
ShortCutToKey(ShortCut,Result,shift); // call in Menus!
end;

function GetShortCutModifier(ShortCut: TShortCut):Word;
var
key: Word;
shift: TShiftState;
begin
ShortCutToKey(ShortCut,key,shift); // call in Menus!
Result := ShiftState2Modifier(shift);
end;

function RegisterHotShortCut(const h:THandle; const Atom: integer;
const ShortCut: TShortCut):Boolean;
var
key : Word;
Shift: TShiftState;
begin
UnregisterHotKey(h,Atom); // call in Windows
ShortCutToKey(ShortCut,key,shift);
Result := RegisterHotKey(h,Atom,ShiftState2Modifier(Shift),k ey);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
// you need to type cast it as a pChar if you are using a string
myAtom := GlobalAddAtom(pchar('HotKeyDemo'));
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
UnregisterHotKey(Handle,myAtom);
GlobalDeleteAtom(myAtom);
end;

procedure TForm1.CheckBox1Click(Sender: TObject);
begin
if CheckBox1.Checked then
RegisterHotShortCut(Handle,myAtom,HotKey1.HotKey)
else
UnregisterHotKey(Handle,myAtom);
end;

procedure TForm1.HotyKeyMsg(var msg: TMessage);
begin
if (msg.LParamLo=GetShortCutModifier(HotKey1.HotKey))
and (msg.LParamHi=GetShortCutKey(HotKey1.HotKey)) then
begin
Application.BringToFront;
Showmessage('Hey, now that is a system wide hot key!')
end;
end;

end.

Nesta
23-05-2005, 05:40
در اين مقاله ميخواهم نحوه برقراري ارتباط با پروتکل ياهو مسنجر يکي ازمعروفترين و مهمترين مسنجرهاي اينترنتي را بيان کنم. در صورتي که علاقه منديد که با Msn مسنجر ارتباط برقرار کنيد مي توانيد از مقالات ديگر که در اين زمينه نوشته ام در همين سايت استفاده کنيد. براي برقراري با پروتکل ياهو مسنجر بايد با دستورات و روش برقراري ارتباط با آن مطلع باشيم. ولي در حال حاضر نمي خواهم به نکات ريز و نحو دستورات اين پروتکل بپردازم . بلکه يک برنامه در دلفي مينويسيم که با استفاده از آن بشود با ياهو مسنجر ارتباط برقرار کرد و از مزاياي آن استفاده کرد. در اين مثال از کمپوننتهاي ايندي Indy استفاده کرده ام ولي شما مي توانيد بر حسب نياز يا سليقه خود از هر کمپوننت ارتباطي ديگري براي برقراري ارتباطات tcp/ip استفاده کنيد.
کد دلفي

<-------------------------------BEGIN UNIT CODE ------------------------------>
unit YahooLogin;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls, IdBaseComponent, IdComponent, IdTCPConnection,
IdTCPClient, Id[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ] idGlobal;

type
TForm1 = class(TForm)
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ] TId[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
Panel1: TPanel;
Label1: TLabel;
Edit1: TEdit;
Label2: TLabel;
Edit2: TEdit;
Button1: TButton;
ListBox1: TListBox;
Label3: TLabel;
ListBox2: TListBox;
Label4: TLabel;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
FRemoteFile: TStringList;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

const
LoginURL = '[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]';

procedure TForm1.Button1Click(Sender: TObject);
var
Tmp, UserName, Password: String;
i, BuddyBegin, BuddyEnd: Integer;
begin
if (Edit1.Text = '') or (Edit2.Text = '') then
raise Exception.Create('Login/Password cannot be blank');

UserName := URLEncode(Edit1.Text);
PassWord := URLEncode(Edit2.Text);
Tmp := Format(LoginURL, [UserName, PassWord]);

FRemoteFile.Text := [ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ](Tmp);

if FRemoteFile[0] = 'OK' then
begin
for i := 0 to [ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ] -1 do
if pos('Set-Cookie', [ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ][i]) > 0 then
begin
//We only care about the first cookie
ShowMessage('Received Cookie: '+ Copy([ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ][i], Length('set0cookie.'), Length([ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ][i])));
//So we break after getting the first cookie
Break
end;

//Buddy list is delimited by a BEGIN BUDDYLIST and END BUDDYLIST
BuddyBegin := FRemoteFile.IndexOf('BEGIN BUDDYLIST') +1;
BuddyEnd := FRemoteFile.IndexOf('END BUDDYLIST') -1;

for i := BuddyBegin to BuddyEnd do
//These is the "raw" buddy list parsing is needed for it to make sense
//Since this is an example I discarded this code
ListBox1.Items.Add(FRemoteFile[i]);

BuddyBegin := FRemoteFile.IndexOf('BEGIN IGNORELIST') +1;
BuddyEnd := FRemoteFile.IndexOf('END IGNORELIST') -1;

for i := BuddyBegin to BuddyEnd do
ListBox2.Items.Add(FRemoteFile[i]);

for i := 0 to FRemoteFile.Count -1 do
if pos('Mail=', FRemoteFile[i]) > 0 then
begin
Tmp := Copy(FRemoteFile[i], length('mail01'), Length(FRemoteFile[i]));
if StrToInt(Tmp) = 1 then
ShowMessage('You have a yahoo mail account')
else
ShowMessage('You dont have a yahoo mail account');
Break;
end;
end else
raise Exception.Create('Couldnt log you on');
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
FRemoteFile := TStringList.Create;
end;

end.
<-----------------------------END UNIT CODE--------------------------------->

<-----------------------------BEGIN FORM CODE------------------------------->
object Form1: TForm1
Left = 192
Top = 121
Width = 379
Height = 443
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -13
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
OnCreate = FormCreate
PixelsPerInch = 120
TextHeight = 16
object Label3: TLabel
Left = 16
Top = 136
Width = 65
Height = 16
Caption = 'Buddys list'
end
object Label4: TLabel
Left = 194
Top = 138
Width = 64
Height = 16
Caption = 'Ignore lists'
end
object Panel1: TPanel
Left = 11
Top = 3
Width = 342
Height = 113
TabOrder = 0
object Label1: TLabel
Left = 11
Top = 24
Width = 63
Height = 16
Caption = 'Username'
end
object Label2: TLabel
Left = 11
Top = 56
Width = 60
Height = 16
Caption = 'Password'
end
object Edit1: TEdit
Left = 94
Top = 18
Width = 233
Height = 24
TabOrder = 0
end
object Edit2: TEdit
Left = 96
Top = 51
Width = 233
Height = 24
TabOrder = 1
end
object Button1: TButton
Left = 139
Top = 82
Width = 75
Height = 25
Caption = 'Login'
TabOrder = 2
OnClick = Button1Click
end
end
object ListBox1: TListBox
Left = 15
Top = 160
Width = 171
Height = 239
ItemHeight = 16
TabOrder = 1
end
object ListBox2: TListBox
Left = 192
Top = 160
Width = 171
Height = 239
ItemHeight = 16
TabOrder = 2
end
object [ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ] TIdHTTP
Request.Accept = 'text/html, */*'
Request.ContentLength = 0
Request.ContentRangeEnd = 0
Request.ContentRangeStart = 0
Request.ProxyPort = 0
Request.UserAgent = 'Mozilla/4.6 (compatible; Indy Library)'
Left = 320
Top = 48
end
end
<-----------------------------END FORM CODE ------------------------------->


اميدوارم که از کد فوق استفاده لازم را ببريد. انشالله درمقالات بعدي به تشريح کامل روشهاي برقراري ارتباط با اين پروتکل خواهم پرداخت.

Nesta
23-05-2005, 05:40
در اين مقاله طريقه اجرا يا باز کردن نرم افزار هاي خارج از محيط دلفي را با استفاده از تابع API ويندوز ShellExecute را ياد خواهيد گرفت.
چرا بايد برنامه ها را از دلفي اجرا کرد؟
شايد اين سوال براي شما پيش بيايد چرا بايد نرم افزارها را خارج از دلفي اجرا کرد. شما در يکي از موارد ذيل ممکن است نياز به اجراي يک نرم افزار خارج از دلفي داشته باشيد
• برنامه هاي نصب و عزل
• برنامه هاي سيستمي
• برنامه هاي اپليکيشن سرور
• برنامه هاي گزارش گيري
• و ....
موارد بسياري است که ممکن است شما بخواهيد از اين دستور استفاده کنيد که به چندي از آنها اشاره شد.

دستور ShellExecure
اين دستور به ما اجازه ميدهد که برنامه هاي ديگر را اجرا کنيم. نحو اين دستور به شکل ذيل مي باشد.

HINSTANCE ShellExecute(HWND hwnd,
LPCTSTR lpOperation,
LPCTSTR lpFile,
LPCTSTR lpParameters,
LPCTSTR lpDirectory,
INT nShowCmd
);

جدول زير پارامترهاي اين دستور را شرح ميدهد.

پارامتر ورودي/خروجي توضيحات

hwnd

ورودي

دستگيره يا هندل پنجره اصلي - براي گزارش خطاها حتما نياز است

lpOperation

ورودي

اشاره گر - اين پارامتر به نوع عمليات اشاره مي کند

lpFile

ورودي

اشاره گر به نام فايل اجرايي شما

lpParameters

ورودي

اشاره گر به پارامترهاي ارسالي به نرم افزار شما - در صورتي که پارامتر نباشد به صورت تهي بماند

lpDirectory

ورودي

دايرکتوري پيش فرض براي اجراي نرم افزار

nShowCmd

ورودي

اشاره گر تنظيم حالت نمايش برنامه بعد از اجرا


د ر صورتي که دستور shellexcute به درستي اجرا نشود يک کد خطا برمي گرداند شما مي توانيد با استفاده از تابع GetLastError خطا رخ داده را متوجه شويد. در صورتي که دستور Shellexecute به درستي اجرا شود کد خطاي بازگشتي بزرگتر از 32 مي باشد . در صورتي که کد خطا بازگشتي کمتر يا برابر با 32 باشد يک خطا رخ داده است. براي دريافت اطلاعات بيشتر در مورد کدهاي خطا اين دستور به MSDN مراجعه کنيد.
در دلفي شما به راحتي با استفاده از دستور SysErrorMessage مي توانيد آخرين خطا را بدست آوريد.نمونه کد زير روش استفاده از اين دستور را نشان داده است.

if ShellExecute(Handle, 'print', PChar('c:\log.txt'), nil, nil, SW_SHOWNORMAL) <= 32 then
ShowMessage(SysErrorMessage(GetLastError));


پارامتر lpOperation
با استفاده از دستور ShellExecute مي توان نرم افزارها و آبجکتهاي مختلف را اجرا کرد . مقادير قابل قبول براي پارامتر دوم اين دستور lpOperation به شرح جدول ذيل مي باشد.


lpOperation مقدار پارامتر

شرح

edit

باز کردن يک سند براي ويرايش در يک ويرايشگر

explore

مرورگر فايلهاي ويندوز براي مرور دايرکتوري خاص ...

find

جستجو به دنبال يک فايل در دايرکتوري خاص...

open

باز کردن يک فايل يا برنامه

print

چاپ يک سند

NULL

اطلاعات بيشتر در پايين ...



در صورتي که مقدار پارامتر lpOperation برابر با null قرار بگيرد براي باز کردن فايل يا برنامه از رجيستري ويندوز و از قسمت تخصيص فايلهاي اجرايي به پسوند فايلها براي اجراي دستور فوق استفاده مي گردد.
پارامتر nShowCmd
اين پارامتر به دستور ShellExecute مي گويد که بعد از اجراي يک برنامه آن را به چه حالتي نمايش بدهد. انواع حالات مختلف در جدول ذيل آمده است.



nShowCmd مقدار پارامتر

شرح

SW_HIDE

مخفي کردن پنجره

SW_MAXIMIZE

بزرگ کردن پنجره

SW_MINIMIZE

به حداقل رساندن پنجره

SW_RESTORE

فعال کردن يک پنجره در صورتي که به حالت حداقل يا حداکثر باشد

SW_SHOW

نمايش پنجره در حالت و موقعيت پيش فرض

SW_SHOWDEFAULT

نمايش پنجره به حالت پيش فرض در برنامه

SW_SHOWMAXIMIZED

فعال و به حداکثر رساندن پنجره

SW_SHOWMINIMIZED

فعال و به حداقل رساندن يک پنجره

SW_SHOWMINNOACTIVE

نمايش يک پنجره در حالت غير فعال و حداقل

SW_SHOWNA

نمايش يک پنجره در وضعيت فعلي

SW_SHOWNOACTIVATE

نمايش و فعال کردن يک پنجره - ويندوز اين پنجره را در حالت پيش فرض خود نمايش مي دهد.

SW_SHOWNORMAL

نمايش و فعال کردن پنجره به حالت عادي

وقتي که شما براي اولين بار يک برنامه را اجرا مي کنيد بايد از مقدار SW_SHOWNORMAL استفاده کنيد.

استفاده از دستور ShellExecute
درقسمت پايين چند نمونه از حالتهاي استفاده از اين دستور آورده شده است. شما مي توانيد اين دستورات را براي کار خود تغيير دهيد. در دلفي براي استفاده از اين دستور بايد دو يونيت Windows و ShellAPI در قسمت Uses قرار گرفته باشد.


اجراي برنامه Demo.exe از دايرکتوري C:\app

ShellExecute(Handle,NIL,PChar('C:\apps\demo.exe'), nil,nil,SW_SHOWNORMAL);

باز کردن فايل log.txt

ShellExecute(Handle,'open',PChar('c:\log.txt'), nil,nil,SW_SHOWNORMAL);

پخش فايل ending.mp3

ShellExecute(Handle,'play',PChar('c:\ending.mp3'), nil,nil,SW_SHOWNORMAL);

چاپ فايل log.txt

ShellExecute(Handle,'print',PChar('c:\log.txt'), nil,nil,SW_SHOWNORMAL);

باز کردن مروگر فايل ويندوز از C:\

ShellExecute(Handle,'explore',PChar('c:\'), nil,nil,SW_SHOWNORMAL);

ساخت يک نامه الکترونيکي جديد به واسطه Outlook Express

Procedure CreateEmail(Const EmailAddr, Subject, Body: String);
var
ConcatEmailStr: String;
Begin
ConcatEmailStr := EmailAddr + '?subject=' + Subject + '&body=' + Body;

ShellExecute(Handle,'open',PChar(ConcatEmailStr), nil, nil, SW_SHOWNORMAL);
end;

براي کسب اطلاعات بيشتر به آدرس ميکروسافت
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
مراجعه فرماييد.
اميدوارم که توانسته باشيد از اين مقاله استفاده کنيد.

Nesta
23-05-2005, 05:41
يكي از مشكلاتي كه بسياري از تازه كاران در دلفي با آن مواجه مي شوند اجراي فايلهاي ديگر يا اجراي دستورات shell است.

در اين مقاله سعي ما بر اين است كه شما را با اجراي فايلهاي ديگر از درون دلفي و كنترل آنها آشنا كنيم. شما پس از خواندن اين مقاله خواهيد توانست به راحتي فايلهاي ديگر -و نه تنها exe- را از درون دلفي اجرا كنيد و حتي دستورات shell را نيز صادر كنيد. به عنوان مثال ممكن است بخواهيد يك فايل html را با Editor پيش فرض كاربر باز كنيد. يا يك فايل html را با Browser پيش فرض كاربر باز كنيد. يا شايد بخواهيد يك فايل BMP را با اديتور پيش فرض كاربر باز نماييد و يا اين كه يك فايل INF را نصب نماييد.

با خواندن اين مقاله شما مي توانيد به راحتي به تمامي اين اهداف برسيد.
تابع APIي وجود دارد به نام WinExec. شكل كلي اين تابع از اين قرار است:


WinExec(lpCmdLine: PAnsiChar; uCmdShow: Cardinal);
كه lpCmdLine خط دستور مورد نظر شما براي اجراي فايل و uCmdShow بايد يكي از مقادير زير را داشته باشد:
SW_HIDE SW_MAXIMIZE SW_MINIMIZE
SW_RESTORE SW_SHOW SW_SHOWDEFAULT
SW_SHOWMAXIMIZED SW_SHOWMINIMIZED SW_SHOWMINNOACTIVE
SW_SHOWNA SW_SHOWNOACTIVATE SW_SHOWNORMAL


براي توضيحات بيشتر راجع به هر كدام از اين ثابت ها به راهنماي Windows SDK دلفي يا MSDN مراجعه كنيد.

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

تابع ديگري وجود دارد به نام ShellExecute. اين تابع در يونيت ShellAPI تعريف شده است. بنابر اين لازم است يونيت ShellAPI را در ليست uses يونيت خود وارد كنيد. اين يكي از توابع بسيار قدرتمند براي اجراي فايل است.
نگاهي به شكل كلي اين تابع بياندازيد:



function ShellExecute(hWnd: HWND; Operation, FileName, Parameters, Directory: PChar; ShowCmd: Integer): HINST; stdcall;

hWnd Handle پنجره اي كه اين دستور را فراخوانده است.
Operation نوع دستوري مورد نظر جهت اجرا
FileName نام فايل يا شاخه
Parameters پارامترهاي مورد نظر در هنگام اجراي فايل exe
Directory شاخه پيش فرض در هنگام اجراي فايل
ShowCmd مشخص كننده چگوني نمايش فايل در هنگام اجرا


پارامتر اول يك متغيير از نوع HWND است.
لازم است براي كساني كه با مفهوم Handle در ويندوز آشنا نيستند توضيحاتي راجع به Handle بدهم. هر پنجره يا آبجكتي در ويندوز داراي يك Handle است كه براي دسترسي به آن پنجره يا آبجكت شما بايد از اين Handle استفاده كنيد. در واقع يك Handle يك عدد در مبناي 16 است. Handle يك عدد unique يا همتا است كه ويندوز آن را مقداردهي مي كند. اگر از يك پنجره دو Instance اجرا شده باشد (مثلا يك برنامه دو بار اجرا شده باشد) هر كدام از اين Instanceها يك Handle جداگانه دارند.
با اين تفاصيل پارامتر اول Handle پنجره اي است كه اين دستور را صادر كرده است. شما براي اين پارامتر مي توانيد از Application.Handle استفاده كنيد و يا آن را برابر 0 قرار دهيد. به علاوه مي توانيد Handle يك برنامه ديگر را بدهيد.

در صورتي كه شما مي خواهيد پيغام هاي اخطار آن فايل را دريافت كنيد يا آن را كنترل نماييد و يا تا اجراي كامل آن اجراي برنامه را متوقف كنيد با Handle برنامه خود را با استفاده از Application.Handle به اين پارامتر بدهيد.

پارامتر دوم مشخص كننده وظيفه اي است كه قرار است انجام شود. اين پارامتر مقادير پيش فرضي ندارد و بستگي به خصوصيات فايل اجرايي دارد. روي يك فايل از نوع Text كليد سمت راست ماوس را بزنيد. احتمالا موارد بالاي ليست "open"، "Edit with ..." , "print" است. هر كدام از اين رشته هاي مي توانند يك عمليات يا Operation باشند. به عنوان مثال شما مي خواهيد يك فايل Text را چاپ كنيد. در اين صورت كافي است از عبارت print به عنوان operation استفاده كنيد. يا مي خواهيد يك فايل rar را با استفاده از WinRar باز كنيد. در اين صورت مي توانيد از "Extract files" استفاده كنيد. حتما تا به حال متوجه شده ايد كه دستور ShellExecute چه مقدار انعطاف پذير است. با استفاده از اين فرمان مي توانيد هر گونه دستور Shell را اجرا نماييد.

پارامتر سوم مشخص كننده نام فايل يا شاخه اي است كه شما مي خواهيد عمليات بر روي آن انجام شود.
پارامتر چهارم ليست پارامترهايي است كه تمايل داريد فايل exe با اين پارامترها اجرا شود. پارامترها پنجم نيز نام شاخه پيش فرض در هنگام اجراي فايل مورد نظر شماست. اگر شما فايل exe اي را اجرا كنيد و اين فايل exe بخواهد از شاخه جاري فايلهاي اضافه اي را استفاده كند ويندوز شاخه جاري را به اون مطابق با اين شاخه اطلاع خواهد داد. و اما آخرين پارامتر مشخص كننده شكل اجراي فايل است. مقدار اين پارامتر مي تواند يكي از ثابت هايي ليستي باشد كه در ابتداي اين مقاله عنوان شد. به عنوان مثال شما مي توانيد از SW_HIDE استفاده كنيد كه در اين صورت فايل اجراي شما مخفي خواهد بود و يا از SW_SHOWMINIMIZE استفاده كنيد كه در اين صورت برنامه شما Minimizeشده اجرا مي شود.

و حالا به يك نكته خيلي مهم توجه كنيد:
1- رشته هاي اين تابع از نوع PChar هستند بنابراين شما بايد رشته هاي string را به صورت PChar به اين تابع بدهيد. شما مي توانيد به طور عادي رشته مورد نظر خود را به اين تابع بدهيد و يا در صورتي كه رشته مورد نظر شما string است بايد با استفاده با استفاده از دستور PChar آن را Typecast كنيد. به عنوان مثال:


ShellExecute(0, 'open', PChar(ExtractFilePath(Application.ExeName) + 'test.exe') , '', '', SW_SHOWNORMAL);

در اين مثال با استفاده از تابع ExtractFilePath و Application.ExeName كه حاوي آدرس كامل فايل Exe است شاخه اي كه فايل exe در آن قرار دارد را پيدا كرده ايم و سپس فايل test.exe را كه در كنار فايل اصلي اجرايي وجود دارد را به آن اضافه كرده ايم. كل اين عبارت TypeCast شده است به PChar.
جهت اطلاع كساني كه نمي دانند TypeCast چيست. TypeCast فرآيندي است كه شما متغيير يا Objectي را از يك نوع به نوع ديگري تبديل ميكنيد. كد زير را نگاه كنيد و با نوع پيشرفته تري از TypeCast آشنا شويد:



procedure TForm1.Button1Click(Sender: TObject); begin TButton(Sender).Caption := 'Test'; end;

در اين مثال Sender را از نوع TObject است TypeCast كرده ايم به TButton. و پراپرتي Caption آنرا تغيير داده ايم. براي اطلاعات بيشتر راجع به TypeCast به كتب دلفي مراجعه كنيد.


و اجازه دهيد به چند مثال جالب نيز نگاهي بياندازيم:
edit كردن يك فايل HTML با Editor پيش فرض HTML:

ShellExecute(Handle, 'edit', 'test.htm', '', '', SW_SHOW);
نصب يك فايل INF


ShellExecute(Handle, 'install', 'divx.inf', '', '', SW_SHOW);
فشرده ساختن يك فايل با استفاده از winrar و ارسال آن به ايميل:


ShellExecute(Handle, 'compress and mail...', 'test.file', '', '', SW_SHOW);
ارسال ايميل به mamouri@ganjafzar.com و با موضوع "Great Article":


ShellExecute(0, 'open', 'mailto:mamouri@ganjafzar.com?subject=GreatArticle ', '', '', SW_SHOWNORMAL);
چگونه يك فايل exe را اجرا كنيم و تا اتمام آن برنامه را متوقف كنيم؟


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 يونيت خود اضافه كنيد.
در اين تابع از تابع ديگري به نام ShellExecuteEx استفاده شده است. اين تابع بر خلاف ShellExecute فقط يك پارامتر دارد كه بايد برابر متغييري از نوع TShellExecuteInfo قرار بدهيد. در ابتدا بايد با استفاده از تابع FillChar آنرا مقداردهي كنيد و وجود آنرا به ويندوز اطلاع دهيد. در واقع آن را Create كنيد:


FillChar(SEInfo, SizeOf(SEInfo), 0); SEInfo.cbSize := SizeOf(TShellExecuteInfo);

آبجكت ShellExecuteEx داراي پارامترهاي زير است:


cbSize: DWORD;
fMask: ULONG;
Wnd: HWND;
lpVerb: PAnsiChar;
lpFile: PAnsiChar;
lpParameters: PAnsiChar;
lpDirectory: PAnsiChar;
nShow: Integer;
hInstApp: HINST;


براي اطلاعات بيشتر راجع به اين پارامترها به راهنماي Windows SDK دلفي يا MSDN مراجعه كنيد. خروجي اين تابع از نوع boolean است و مشخص كننده اين است كه آيا اين تابع با موفقيت اجرا شده است يا نه؟
تابع ExecAndWait پس از اين كه اطمينان پيدا كرد كه فايل با موفقيت اجرا شده است يك حلقه repeat..until تشكيل داده. در داخل repeat دستور Application.ProcessMessage صادر شده است تا برنامه بتواند messageها را دريافت كند. سپس با استفاده از GetExitCodeProcess مقدار خروجي پروسس اجرا شده دريافت مي گردد. در صورتي كه خروجي اين تابع مخالف STILL_ACTIVE بود (كه نشانگر اجراي پروسس است) حلقه با كار خود ادامه مي دهد.

خروجي اين تابع مشخص كننده اجرا يا عدم اجراي فايل اجرايي است.

و حالا به چند مثال جالب ديگر توجه كنيد:
1- دسترسي به HotMail از درون دلفي:


program dummy;
var ToAddress: string;
EightSpaces: string;
begin
ToAddress := 'john@pacbell.net';
// Don't know why but this is required to get the
// correct compose address...
EightSpaces := ' ';
ShellExecute(Handle, PChar('open'), PChar('rundll32.exe'), PChar('C:\PROGRA~1\INTERN~1\HMMAPI.DLL,MailToProto colHandler' + EightSpaces + ToAddress), nil, SW_NORMAL)
end.

2- نمايش ديالوگ مشخصات يك فايل:



procedure ShowPropertiesDialog(Filename: string);
var
SEI: TShellExecuteInfo;
begin
FillChar(SEI, SizeOf(SEI), 0);
with SEI do
begin
cbSize := SizeOf(SEI);
lpFile := PChar(Filename);
lpVerb := 'properties';
fMask := SEE_MASK_INVOKEIDLIST;
end;
ShellExecuteEx(@SEI);
end;


3- اجراي ديالوگ Screen ويندوز (Control Panel > Display)


ShellExecute(HInstance, nil, PCHAR('rundll32.exe'), PCHAR('shell32.dll, Control_RunDLL desk.cpl, , 3') { 3 is the tab index }, NIL, 1);

همان طور كه متوجه شديد 3 شماره Tabي است كه مورد نظر شماست.

4- يك مثال كامل تر از فرستادن ايميل با استفاده از Outlook يا ارسال كننده پيش فرض email:


var
mail: string;
begin
mail := 'mailto:you@you.com' +
'?subject=hello' +
'&cc=me@me.com' +
'&body=Delphi is cool! ;)';
ShellExecute(Self.Handle, 'open', PChar(mail), nil, nil, SW_SHOWNORMAL);

خروجي هاي تابع ShellExecute يا ShellExecuteEx

خروجي هاي اين دو تابع مي تواند يكي از مقادير زير باشد:

0 سيستم عامل داراي resourceهاي كافي يا حافظه كافي جهت اجرا نيست.
ERROR_FILE_NOT_FOUND فايل مورد نظر پيدا نشد.
ERROR_PATH_NOT_FOUND آدرس مشخص شده پيدا نشد.
ERROR_BAD_FORMAT فايل EXE نامعتبر است يا اين يك فايل EXE از نوع Win32 نيست.
SE_ERR_ACCESSDENIED سيستم عامل دسترسي به فايل مشخص شده ندارد.
SE_ERR_ASSOCINCOMPLETE association فايل مورد نظر شما ناقص يا نامعتبر است. مثلا مشخص نشده كه فايل bmp كه شما مي خواهيد آن را اجراه كنيد بايد با چه برنامه اي باز شود.
SE_ERR_DDEBUSY DDE transaction مربوطه كامل نشد زيرا DDE transactionهاي ديگري در حال اجرا بودند.
SE_ERR_DDEFAIL DDE transaction ناموفق بود.
SE_ERR_DDETIMEOUT DDE transaction نتوانست اجرا شود زيرا درخواست Time Out شد.
SE_ERR_DLLNOTFOUND فايل dynamic-link library يا dll مشخص شده پيدا نشد.
SE_ERR_FNF فايل مورد نظر پيدا نشد.
SE_ERR_NOASSOC هيچ برنامه اي با پسوند فعلي فايل منطبق نشده است. مثلا مشخص نشده كه فايل bmp كه شما مي خواهيد آن را اجراه كنيد بايد با چه برنامه اي باز شود.
SE_ERR_OOM حافظه كافي جهت اجراي عمليات وجود ندارد.
SE_ERR_PNF آدرس مشخص شده پيدا نشد.
SE_ERR_SHARE يك خطاي sharin violation پيش آمد. يعني فايل مورد نظر share شده بود.


خلاصه:
در اين مقاله با سه تابع API مهم به نام هاي WinExec و ShellExecute و ShellExecuteEx آشنا شديم و پارامترهاي آنها را بررسي كرديم. به علاوه مثالهاي متعددي راجع به استفاده از ShellExecute ارائه داديم. به علاوه ثابتهاي استفاده شده در اين تابع ها را ليست كرده و بعضا آنها را مورد بررسي قرار داديم. همچنين تابعي به نام ExecAndWait ارائه داديم كه كار آن اجراي يك فايل exe و متوقف كردن برنامه تا اتمام فايل exe آشنا شديم و ساختمان داخلي اين تابع را مورد بررسي قرار داديم.

Nesta
23-05-2005, 05:42
برخي مواقع بعضي از برنامه هاي شما احتياج به خواندن اطلاعات از روي
CD را دارند. قبل از اجراي برنامه مي توان با استفاده از دستورات مختلفي
مانند FileExists وجود CD مورد نظر در CD-Rom را بررسي كرد و در صورت صحيح
بودن آن برنامه را اجرا كرد.

اما اگر كاربر در هنگام اجراي برنامه CD حاوي اطلاعات را از CD-Rom خارج كند
به چه صورت مي توان آن را تشخيص داد.

شايد بررسي مكرر توسط دستوراتي از قبيل FileExists كار درستي نباشد.
ويندوز براي شما يك دستور تدارك ديده كه توسط آن مي توانيد وارد و خارج شدن
CD از CD-Rom را تشخيص دهيد.

زماني كه شما يك CD را وارد CD-Rom مي كنيد آن به عنوان يك Device جديد
براي ويندوز شناخته مي شود. پس از اين روش مي توان وارد و خارج كردن آن را
در هنگام اجراي برنامه تشخيص داد.

به كد زير توجه فرماييد :


type
TForm1 = class(TForm)
private
procedure WMDeviceChange(var Msg: TMessage); message WM_DEVICECHANGE;
// اين قسمت فراموش نشود
public

end;

{...}

implementation

{$R *.DFM}

procedure TForm1.WMDeviceChange(var Msg: TMessage);
const
DBT_DEVICEARRIVAL = $8000; // system detected a new device
DBT_DEVICEREMOVECOMPLETE = $8004; // device is gone
var
myMsg: string;
begin
inherited;
case Msg.wParam of
DBT_DEVICEARRIVAL: myMsg := 'CD inserted!';
DBT_DEVICEREMOVECOMPLETE: myMsg := 'CD removed!';
end;
ShowMessage(myMsg);
end;



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

از اين كد در برنامه هاي خود استفاده كنيد و جلوي Error هاي برنامه را در
صورت عدم وجود CD در CD-Rom بگيريد.

برنامه را اجرا كنيد ، سپس يك CD در درايو قرار دهيد ، بار ديگر CD را از
درايو خارج نماييد و نتيجه آن را مشاهده كنيد.

Nesta
23-05-2005, 05:44
اين مقاله مناسب كاربراني مي باشد كه استفاده زيادي
از گرافيك در برنامه هاي خودشان مي كنند. توسط اين مقاله
مي توانيد تا يك تصوير نقشه بيتي را در داخل صفحه
با زواياي مختلف بچرخانيد .
اين فرمولها به صورت ماتريسي نوشته شده اند.
به طور كلي ماتريسها كمك بسيار زيادي در رابطه با گرافيك
و تغييرات آن اعمال مي كنند. در بسياري از روشهاي ويرايش
يك تصوير يا گرافيك ، ما از ماتريسها كمك مي گيريم.

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


كد:

CONST
MaxPixelCount = 32768;

TYPE
TRGBTripleArray = ARRAY[0..MaxPixelCount-1] OF TRGBTriple;
pRGBTripleArray = ^TRGBTripleArray;
...

// "Simple" approach. For pixel (i,j), use "reverse" rotation to find
// where the rotated pixel must have been before the rotation.
// Don't bother with center of pixel adjustment.
// Assumes input BitmapOriginal has PixelFormat = pf24bit.
FUNCTION RotateBitmapMethod1 (CONST BitmapOriginal: TBitmap;
CONST iRotationAxis, jRotationAxis: INTEGER;
CONST AngleOfRotation: DOUBLE {radians} ): TBitmap;

VAR
cosTheta : EXTENDED;
i : INTEGER;
iOriginal : INTEGER;
iPrime : INTEGER;
j : INTEGER;
jOriginal : INTEGER;
jPrime : INTEGER;
RowOriginal: pRGBTripleArray;
RowRotated : pRGBTRipleArray;
sinTheta : EXTENDED;
BEGIN
// The size of BitmapRotated is the same as BitmapOriginal. PixelFormat
// must also match since 24-bit GBR triplets are assumed in ScanLine.
RESULT := TBitmap.Create;
RESULT.Width := BitmapOriginal.Width;
RESULT.Height := BitmapOriginal.Height;
RESULT.PixelFormat := pf24bit; // Force this

// Get SIN and COS in single call from math library
sincos(AngleOfRotation, sinTheta, cosTheta);

// If no math library, then use this:
// sinTheta := SIN(AngleOfRotation);
// cosTheta := COS(AngleOfRotation);

// Step through each row of rotated image.
FOR j := RESULT.Height-1 DOWNTO 0 DO
BEGIN
RowRotated := RESULT.Scanline[j];
jPrime := j - jRotationAxis;

FOR i := RESULT.Width-1 DOWNTO 0 DO
BEGIN
iPrime := i - iRotationAxis;
iOriginal := iRotationAxis + ROUND(iPrime * CosTheta - jPrime * sinTheta);
jOriginal := jRotationAxis + ROUND(iPrime * sinTheta + jPrime * cosTheta);

// Make sure (iOriginal, jOriginal) is in BitmapOriginal. If not,
// assign blue color to corner points.
IF (iOriginal >= 0) AND (iOriginal <= BitmapOriginal.Width-1) AND
(jOriginal >= 0) AND (jOriginal <= BitmapOriginal.Height-1)
THEN BEGIN
// Assign pixel from rotated space to current pixel in BitmapRotated
RowOriginal := BitmapOriginal.Scanline[jOriginal];
RowRotated[i] := RowOriginal[iOriginal]
END
ELSE BEGIN
RowRotated[i].rgbtBlue := 255; // assign "corner" color
RowRotated[i].rgbtGreen := 0;
RowRotated[i].rgbtRed := 0
END

END
END
END {RotateBitmapMethod1};



همان طور كه در كد بالا ملاحظه مي فرماييد ما از دستور ScanLine جهت
چاپ و نمايش پيكسلهاي تصوير استفاده كرده ايم. اين دستور يكي از
بهترين دستورات دلفي براي نمايش پيكسلهاي تصوير مي باشد.
اين دستور به صورت اسمبلي تدوين شده است و نتيجه آن بسيار سريع
مي باشد و سرعت نمايش آن نسبت به ساير دستورات ترسيم ، به خاطر
خطي بودن آن ، بسيار بالاتر مي باشد.

در ابتدا ما به صورت موقت يك تصوير نقشه بيتي ديگر مي سازيم. سپس
تصوير اوليه را با استفاده از فرمول ذكر شده ، مي چرخانيم و در تصوير
جديد قرار مي دهيم. نتيجه يا همان Result اين Function به صورت يك
تصوير نقشه بيتي مي باشد كه همان تصوير چرخانده شده است.

به خاطر داشته باشيد كه تمامي دستورات مربوط به گرافيك و سرعت
عملكرد آنها بستگي كامل به سرعت كامپيوتر كاربر دارد.

Nesta
23-05-2005, 05:45
محيط دلفي براي برنامه نويسي يكي از بهترين محيطهاي برنامه نويسي است گذشته از كاركرد داخلي و كمپايلر آن كه بسيار قوي و سريع است، محيط آن يعني 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 را بزنيد. در اينحالت اگر روي كد تابع باشيد به قسمت تعريف آن خواهيد رفت.



خوب اين هم قسمت اول اين مقاله كه اميدوارم مفيد بوده باشد.

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

Nesta
23-05-2005, 05:47
سلام حتما تا به حال چندين بار سعي کرده ايد که از توابع API در دلفي استفاده کنيد ولي هميشه در استفاده از توابع API مشکل داشته ايد. يکي از اين مشکلات نبودن مثالهاي استفاده از توابع API براي دلفي است. از اينرو تمامي منابع موجود فقط به معرفي پارامترهاي کلي و مقادير بازگشتي مي پردازند. مثلا وقتي در يک منبع گفته شده که نوع ورودي اين تابع از نوع UCHAR هست اين به چه معني است. ما که در دلفي چنين نوعي نداريم. بله شايد درست حدس زده باشيد , اين انواع براي ويندوز هستند و دلفي انواع ديگري با آنها برابري مي کنند. در ذيل به معرفي اين انواع و نوع برابر آنها در دلفي مي پردازم. اميدوارم که مورد استفاده دوستان قرار بگيرد.

نوع ويندوز نوع مشابه در دلفي توضيحات
LPSTR PAnsiChar; اشاره گر به رشته
LPCSTR PAnsiChar; اشاره گر به رشته
DWORD Integer; عدد صحيح
BOOL LongBool; مقدار منطقي
PBOOL ^BOOL; يک اشاره گر به يک متغيير منطقي
Pbyte ^Byte; يک اشاره گر به يک متغيير از نوع بايت
PINT ^Integer; يک اشاره گر به يک متغيير از نوع عدد
Psingle ^Single; يک اشاره گر به يک متغيير از نوع سينگل
PWORD ^Word; يک اشاره گر به متغيير 16 بيتي
PDWORD ^DWORD; يک اشاره گر به متغيير 32 بيتي
LPDWORD PDWORD; يک اشاره گر به متغيير 32 بيتي
UCHAR Byte; يک متغيير 8 بيتي - از اين متغيير مي توان براي ذخيره اطلاعات يک کاراکتر استفاده کرد
PUCHAR ^Byte; اشاره گر به متغيير 8 بيتي
SHORT Smallint; عدد صحيح 16 بيتي
UINT Integer; عدد صحيح 32 بيتي.
PUINT ^UINT; اشاره گر به يک عدد صحيح 32 بيتي
ULONG Longint; عدد صحيح 32 بيتي
PULONG ^ULONG; اشاره گر به عدد صحيح 32 بيتي
PLongint ^Longint; اشاره گر به عدد 32 بيتي
PInteger ^Integer; اشاره گر به يک متغيير 32 بيتي
PSmallInt ^Smallint; اشاره گر به يک متغيير 16 بيتي
PDouble ^Double; اشاره گر به يک متغيير از نوع دابل
LCID DWORD; يک معين کننده داخلي
LANGID Word; يک معين کننده زبان
THandle Integer; يک نوع عددي به نام هندل ( دستگيره) - اين نوع در اکثر توابع مورد استفاده قرار مي گيرد
PHandle ^THandle; يک اشاره گر به يک هندل
WPARAM Longint; يک پارامتر 32 بيتي براي توابع
LPARAM Longint; يک پارامتر 32 بيتي براي توابع
LRESULT Longint; يک مقدار 32 بيتي بازگشتي از توابع
HWND Integer; يک هندل براي يک پنجره - با استفاده از اين هندل مي توان به پنجره ها دستيابي پيدا کرد
HHOOK Integer; يک هندل براي يک دستگيره عملياتي
ATOM Word; يک شماره ايندکس براي اشاره به جدول اتمها
HGLOBAL THandle; يک اشاره گر به يک قسمت از حافظه,
HLOCAL THandle; يک اشاره گر به يک قسمت از حافظه,
FARPROC Pointer; يک اشاره گر به يک رويه
HGDIOBJ Integer; يک اشاره گر به يک آبجکت GDI
HBITMAP Integer; يک هندل به يک بيت مپ
HBRUSH Integer; يک هندل به يک براش
HDC Integer; يک هندل براي يک دستگاه
HENHMETAFILE Integer; يک هندل براي متا فايلها
HFONT Integer; يک هندل براي فونت
HICON Integer; يک هندل براي يک آيکون
HMENU Integer; يک هندل براي يک منو
HMETAFILE Integer; يک هندل براي يک متا فايل
HINST Integer; يک هندل براي يک آبجکت
HMODULE HINST; يک هندل براي يک ماژول
HPALETTE Integer; يک هندل براي جدول رنگ
HPEN Integer; يک هندل براي قلم
HRGN Integer; يک هندل براي اشکال هندسي
HRSRC Integer; يک هندل براي منابع ويندوز
HKL Integer; يک هندل براي حالت صفحه کليد
HFILE Integer; يک هندل براي يک فايل باز
HCURSOR HICON; يک هندل براي يک اشاره گر موشواره
COLORREF DWORD; يک نوع رنگ از نوع عددي

Nesta
23-05-2005, 05:47
با سلام
كسانيكه با اينترنت كار ميكنند مطمنا براي يكبار هم شده از فايلهاي 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;جهت شروع خودكار در زمان اجراي برنامه

همچنين دستوراتي نيز براي كنترل فريم هاي فايل (ff,rew,...) وجود دارد كه در مقاله بعدي به همراه چگونگي استفاده از قابليت تصويري اين كنترل كه بسيار جالب مي باشد شرح خواهم داد. ان شا الله

Nesta
23-05-2005, 05:49
xml
L مي تواند دقيقا همچون يك Table براي شما عمل نمايد. در واقع شما مي توانيد با استفاده از XML اطلاعات خودتان را در قالب يك جدول ذخيره كنيد.
براي اين كار مي توانيد از كمپوننت ClientDataSet استفاده كنيد. (اين كمپوننت را مي توانيد در تب DataAccess بيابيد). در واقع اين كمپوننت يك In-Memory Table است. يعني اطلاعات خود را در حافظه نگهداري مي كند و به همين علت نيز فوق العاده سريع است.
نگاهي به كد زير بيانداريد و با Load كردن يك XML و درست كردن آن آشنا شويد:




ClientDataSet1.FileName := ExtractFilePath(

Application.ExeName) +

'test.xml';
if FileExists(ClientDataSet1.FileName) then
ClientDataSet1.Open
else
begin
//AddFieldDef version
with ClientDataSet1.FieldDefs do
begin
Clear;
with AddFieldDef do
begin
Name := 'ID';
DataType := ftAutoInc;
end; //with AddFieldDef do
with AddFieldDef do
begin
Name := 'First Name';
DataType := ftString;
Size := 20;
end; //with AddFieldDef do
with AddFieldDef do
begin
Name := 'Last Name';
DataType := ftString;
Size := 20;
end; //with AddFieldDef do
end; //with ClientDataSet1.FieldDefs
ClientDataSet1.CreateDataSet;
end; //else


همان طور كه در اين كد مشاهده مي كنيد در ابتدا سعي شده است كه فايل test.xml را كه در شاخه خود برنامه قرار دارد Load كنيم و در صورتي كه اين فايل پيدا نشد. آنگاه مي توان به سادگي (همان طور كه مي بينيد) اين فايل را از ابتدا تعريف كرد. فيلدهاي مورد نظر و مشخصات مورد نياز خود را وارد كنيم و همچنين در صورتي كه نياز بود با استفاده از IndexDefs يك يا چند Index جديد ساخت.

به چند نكته راجع به اين كد توجه كنيد:
1- با استفاده از متد FieldDefs.AddFieldDef مربوط به ClientDataSet مي توانيد يك فيلد جديد درست كنيد.
2- براي ساخت Index نيز مي توانيد از متد IndexDefs.AddIndexDef مربوط به ClientDataSet استفاده كرد.
2- هر فيلد مي توانيد شامل انواع زير باشد:


type TFieldType = (ftUnknown, ftString, ftSmallint, ftInteger, ftWord, ftBoolean, ftFloat, ftCurrency, ftBCD, ftDate, ftTime, ftDateTime, ftBytes, ftVarBytes, ftAutoInc, ftBlob, ftMemo, ftGraphic, ftFmtMemo, ftParadoxOle, ftDBaseOle, ftTypedBinary, ftCursor, ftFixedChar, ftWideString, ftLargeint, ftADT, ftArray, ftReference, ftDataSet, ftOraBlob, ftOraClob, ftVariant, ftInterface, ftIDispatch, ftGuid, ftTimeStamp, ftFMTBcd);


بنابراين شما به جاي ftString و يا ftAutoInc مي توانيد از هر كدام از اين ثابت ها استفاده كنيد.
همان طور كه مستحضريد به راحتي مي توانيد در XML حتي از BLOB هم استفاده كرده و در آن صدا يا تصوير ذخيره كنيد.
3- از متد CreateDataSet پس از ساخت فيلدهاي مورد نظرتون استفاده كنيد تا اين تغييرات تثبيت بشود.
4- يك ClientDataSet را مي توانيد به سادگي به يك كمپوننت DataSource وصل كنيد. پس از آن مي توانيد از هر كمپوننت Data-Aware مثل DBGrid براي Browse يا ويرايش اطلاعات استفاده كنيد.
5- با استفاده از Filter و Filtered مي توانيد به سادگي اطلاعات رو ----- كنيد و به علاوه به سادگي مي توانيد از Locate و FindKey و FindNearest براي جستجو در Tableتون استفاده كنيد.
6- در ClientDataSet هم مي توانيد از Lookupها و فيلدهاي محاسباتي استفاده كنيد. همچنين مي توانيد دو نوع فيلد ديگه به اسم InternalCalc و Aggregate رو هم استفاده كنيد. راهنماي مربوط به InternalCalc و Aggregate دلفي رو در اين جا آورده ام:


InternalCalc:
Retrieves values calculated at runtime by a client dataset and stored with its data (instead of being dynamically calculated in an OnCalcFields event handler). InternalCalc is only available if you are working with a client dataset. Values calculated for an InternalCalc field are stored and retrieved as part of the client dataset’s data.

Aggregate:
Retrieves a value summarizing the data in a set of records from a client dataset.

Nesta
23-05-2005, 05:50
*** دو کد زير در دلفي 7 تحت ويندوزهاي 98، 2K و XP تست شده اند ***


يک روش ساده براي نمايش فايلهاي داخل يک folder همراه با Icon آنها و اعلام نوع فايل (استفاده از API)
يک ListView، يک ImageList و يک Buttonروي فرم قرار دهيد.
کد از نايتي


unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, StdCtrls, ImgList, ShellAPI;

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

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure InsertFilesInList( strPath: String; ListView: TListView; ImageList: TImageList);
var
pFile: Integer;
Icon: TIcon;
SearchRec: TSearchRec;
ListItem: TListItem;
FileInfo: SHFILEINFO;
begin
// Create a temporary TIcon
Icon := TIcon.Create;
ListView.Items.BeginUpdate;
try
// search for the first file
pFile := FindFirst(strPath + '*.*', faAnyFile, SearchRec);
while pFile = 0 do
begin
with ListView do
begin
// On directories and volumes
if ((SearchRec.Attr and FaDirectory <> FaDirectory) and
(SearchRec.Attr and FaVolumeId <> FaVolumeID)) then
begin
ListItem := ListView.Items.Add;
//Get The DisplayName
SHGetFileInfo(PChar(strPath + SearchRec.Name), 0, FileInfo,
SizeOf(FileInfo), SHGFI_DISPLAYNAME);
Listitem.Caption := FileInfo.szDisplayName;
// Get The TypeName
SHGetFileInfo(PChar(strPath + SearchRec.Name), 0, FileInfo,
SizeOf(FileInfo), SHGFI_TYPENAME);
ListItem.SubItems.Add(FileInfo.szTypeName);
//Get The Icon That Represents The File
SHGetFileInfo(PChar(strPath + SearchRec.Name), 0, FileInfo,
SizeOf(FileInfo), SHGFI_ICON or SHGFI_SMALLICON);
Icon.Handle := FileInfo.hIcon;
ListItem.ImageIndex := ImageList.AddIcon(Icon);
// Destroy the Icon
DestroyIcon(FileInfo.hIcon);
end;
end;
pFile := FindNext(SearchRec);
end;
finally
Icon.Free;
ListView.Items.EndUpdate;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
// Assign a Imagelist to the ListView
ListView1.SmallImages := ImageList1;
// Show Listview in Report Style and add 2 Columns
ListView1.ViewStyle := vsReport;
ListView1.Columns.Add;
ListView1.Columns.Add;
InsertFilesInList('C:\', ListView1, ImageList1);
end;

end.



گاهي بد نيست براي انجام بعضي کارها از خود سيستم کمک بگيريم. کد زير اندازه فايلي که انتخاب ميشود را بر ميگرداند. بد نيست، به درد Text-fileها ميخوره .
يک Button، يک Label، يک OpenDialog روي فرم قرار دهيد.
کد از کريس بري

procedure TForm1.Button1Click(Sender: TObject);
var
SearchRec: TSearchRec;
begin
if OpenDialog1.Execute then
if FindFirst(OpenDialog1.FileName, faAnyFile, SearchRec) = 0 then
Label1.Caption := FloatToStrF(SearchRec.Size/1048576, ffFixed, 7, 2)+' MB';
FindClose(SearchRec);
end;

double_n
23-05-2005, 12:17
جناب کارلوس عزیز
من بتازگی یک پک دلفی خریده ام که روش نوشته دلفی 8 ایا این درسته

ضمنا یه کتاب آموزشی و یک کتاب مرجع واسه این دلفی معرفی کنین که خیلی باحاله
من که کف کردم :o :o :wink:
ممنون از آموزشهای خوبتون :wink:

Nesta
23-05-2005, 20:55
سلام دوست من
آره دلفی‌ نسخه 8 را شما خریدی ولی‌ اون یه کم پیشرفت هست و asp هم پشتیبانی‌ می‌کنه ولی‌ برای شروع کار من به شما نسخه 7 رو پیشنهاد می‌کنم که بیشتر برای برنامه نویسی‌ windows application
هست نه کار های .net بهترین کتابی‌ که من طی‌ این مدت قبولش دارم .
کتاب برنامه نویسی‌ با دلفی‌ ویراست دوم یا حالا بالاتر
نویسنده:مهندس عین الله جعفر نژاد قمی‌ و مهندس رمضان عباس نژاد
هستش که خیلی‌ برای کار با شروع خوبه و پیچیده توضیح نداده .قیمت هم 4000 تومن هستش/

double_n
23-05-2005, 21:05
قربون دستت داداش :wink:

Nesta
23-05-2005, 21:33
سلام راستی‌ در بخش انجمن پیشنهادات در رابطه با مدیریت برای سایت نظر بدید یادتون نر که داره دیر می‌شه .متشکر.

double_n
23-05-2005, 22:05
داش کارلوس رفتم . . .

Nesta
24-05-2005, 20:09
سلام
دستت درد نکنه داداشی‌ .متشکر.

JNK
26-05-2005, 06:46
خىلى خوب هست

Nesta
26-05-2005, 08:26
سلام
دوست عزیز خوش آمدید لطفا فونت رو درست کن متشکر.

Mohammad Modarresi
10-09-2006, 02:21
ممنون ولي اي كاش پي دي اف بود

soldier
10-09-2006, 10:35
سلام
نه! مشكل اين نيست كه پي دي اف نيستند!
مشكل اينجاست كه خيلي زياد هستند!
مثلآ اگر به صورت كتاب نوشته بشن! خوب خيلي بهتر ميشد!

موفق باشي

sepidehdam
23-11-2014, 19:23
با سلام خدمت دوستان
چگونه میتوان با کد نویسی در هنگام اجرای برنامه ای با دلفی میتوان حجم غایل log در sql را کم نمود ممنون