-
چگونه يك 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.
-
در اين مقاله ميخواهم نحوه برقراري ارتباط با پروتکل ياهو مسنجر يکي ازمعروفترين و مهمترين مسنجرهاي اينترنتي را بيان کنم. در صورتي که علاقه منديد که با 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, IdHTTP, idGlobal;
type
TForm1 = class(TForm)
HTTP: TIdHTTP;
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 = 'http://msg.edit.yahoo.com/config/ncclogin?&n=1&login=%s&passwd=%s';
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 := Http.Get(Tmp);
if FRemoteFile[0] = 'OK' then
begin
for i := 0 to HTTP.Response.ExtraHeaders.Count -1 do
if pos('Set-Cookie', HTTP.Response.ExtraHeaders[i]) > 0 then
begin
//We only care about the first cookie
ShowMessage('Received Cookie: '+ Copy(HTTP.Response.ExtraHeaders[i], Length('set0cookie.'), Length(HTTP.Response.ExtraHeaders[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 HTTP: 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 ------------------------------->
اميدوارم که از کد فوق استفاده لازم را ببريد. انشالله درمقالات بعدي به تشريح کامل روشهاي برقراري ارتباط با اين پروتکل خواهم پرداخت.
-
در اين مقاله طريقه اجرا يا باز کردن نرم افزار هاي خارج از محيط دلفي را با استفاده از تابع 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;
براي کسب اطلاعات بيشتر به آدرس ميکروسافت
[ برای مشاهده لینک ، با نام کاربری خود وارد شوید یا ثبت نام کنید ]
مراجعه فرماييد.
اميدوارم که توانسته باشيد از اين مقاله استفاده کنيد.
-
يكي از مشكلاتي كه بسياري از تازه كاران در دلفي با آن مواجه مي شوند اجراي فايلهاي ديگر يا اجراي دستورات 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);
ارسال ايميل به
[ برای مشاهده لینک ، با نام کاربری خود وارد شوید یا ثبت نام کنید ]
و با موضوع "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 آشنا شديم و ساختمان داخلي اين تابع را مورد بررسي قرار داديم.
-
برخي مواقع بعضي از برنامه هاي شما احتياج به خواندن اطلاعات از روي
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 را از
درايو خارج نماييد و نتيجه آن را مشاهده كنيد.
-
اين مقاله مناسب كاربراني مي باشد كه استفاده زيادي
از گرافيك در برنامه هاي خودشان مي كنند. توسط اين مقاله
مي توانيد تا يك تصوير نقشه بيتي را در داخل صفحه
با زواياي مختلف بچرخانيد .
اين فرمولها به صورت ماتريسي نوشته شده اند.
به طور كلي ماتريسها كمك بسيار زيادي در رابطه با گرافيك
و تغييرات آن اعمال مي كنند. در بسياري از روشهاي ويرايش
يك تصوير يا گرافيك ، ما از ماتريسها كمك مي گيريم.
حال اجازه دهيد اين فرمول را به دستورات دلفي تبديل كنيم
و نتيجه آن را مشاهده كنيم ...
كد:
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 به صورت يك
تصوير نقشه بيتي مي باشد كه همان تصوير چرخانده شده است.
به خاطر داشته باشيد كه تمامي دستورات مربوط به گرافيك و سرعت
عملكرد آنها بستگي كامل به سرعت كامپيوتر كاربر دارد.
-
محيط دلفي براي برنامه نويسي يكي از بهترين محيطهاي برنامه نويسي است گذشته از كاركرد داخلي و كمپايلر آن كه بسيار قوي و سريع است، محيط آن يعني 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 را بزنيد. در اينحالت اگر روي كد تابع باشيد به قسمت تعريف آن خواهيد رفت.
خوب اين هم قسمت اول اين مقاله كه اميدوارم مفيد بوده باشد.
-
برنامه نويسان دوران 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 و اسمبلي را باهم بكار گرفته و برنامه هايي با بازدهي بسيار بالا بسازيد.از حالا به بعد اگر شنيديد كه :"آره بابا با دلفي نميشه فلان كارو انجام داد ، بايد با اسمبلي كد بنويسي" ميدانيد چه جوابي بدهيد.
-
سلام حتما تا به حال چندين بار سعي کرده ايد که از توابع 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; يک نوع رنگ از نوع عددي
-
با سلام
كسانيكه با اينترنت كار ميكنند مطمنا براي يكبار هم شده از فايلهاي 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,...) وجود دارد كه در مقاله بعدي به همراه چگونگي استفاده از قابليت تصويري اين كنترل كه بسيار جالب مي باشد شرح خواهم داد. ان شا الله