PDA

View Full Version : سوال: مشکل این برنامه چیه(به نوع داده گیر میده)



بهروز عباسی
دوشنبه 22 اسفند 1390, 20:39 عصر
درود به تمام برنامه نویس های گل
من دارم یه کامپوننت ساده مینویسم اینم کدش هنگام کامپایل به این کد گیر میده LinkInfo.FullPathAndNameOfLinkFile :=FFileName;

اینم لیست برنامه:

unit PCshortcutTarget;

interface

uses
SysUtils, Classes,
ComObj , Activex, ShlObj,Windows;

type
PShellLinkInfoStruct = ^TShellLinkInfoStruct;
TShellLinkInfoStruct = record
FullPathAndNameOfLinkFile: array [0 .. MAX_PATH] of Char;
FullPathAndNameOfFileToExecute: array [0 .. MAX_PATH] of Char;
FindData: TWIN32FINDDATA;
end;

TPCShortcutTarget = class(TComponent)
private

FFileName: char;

procedure GetLinkInfo(lpShellLinkInfoStruct: PShellLinkInfoStruct);
protected
{ Protected declarations }
public
function Get_Target():string;
published
property FileName:char read FFileName write FFileName ;
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('programming-Co', [TPCShortcutTarget]);
end;

{ TPCShortcutTarget }

procedure TPCShortcutTarget.GetLinkInfo(
lpShellLinkInfoStruct: PShellLinkInfoStruct);
var
ShellLink: IShellLink;
PersistFile: IPersistFile;
AnObj: IUnknown;
begin
// access to the two interfaces of the object
AnObj := CreateComObject(CLSID_ShellLink);
ShellLink := AnObj as IShellLink;
PersistFile := AnObj as IPersistFile;

// Opens the specified file and initializes an object from the file contents.
PersistFile.Load
(PWChar(WideString(lpShellLinkInfoStruct^.FullPath AndNameOfLinkFile)), 0);
with ShellLink do
begin
// Retrieves the path and file name of a Shell link object.
GetPath(lpShellLinkInfoStruct^.FullPathAndNameOfFi leToExecute,
SizeOf(lpShellLinkInfoStruct^.FullPathAndNameOfLin kFile),
lpShellLinkInfoStruct^.FindData, SLGP_UNCPRIORITY);
end;


end;

function TPCShortcutTarget.Get_Target: string;
var
LinkInfo: TShellLinkInfoStruct;
begin
LinkInfo.FullPathAndNameOfLinkFile :=FFileName;
GetLinkInfo(@LinkInfo);
Result:=(LinkInfo.FullPathAndNameOfFileToExecute);
end;

end.

Ananas
دوشنبه 22 اسفند 1390, 23:07 عصر
سلام.
این دو تا رو ببین:
FullPathAndNameOfLinkFile: array [0 .. MAX_PATH] of Char;
FFileName: char;

دو تا نوع متفاوتند.

بهروز عباسی
دوشنبه 22 اسفند 1390, 23:10 عصر
دو تا نوع متفاوتند.
ممنون از کمک
اماایناکه هردو Char هستن فقط یکی آرایه است

راه حل شما چیه چطور باید این کارو بکنم؟

Ananas
سه شنبه 23 اسفند 1390, 00:15 صبح
خوب نمیشه که این فقط یک کاراکتره ولی اون یکی چند تا کاراکتره. اگه بخوای اولین عضو آرایه رو با این کاراکتر مقدار بدی باید بنویسی :
LinkInfo.FullPathAndNameOfLinkFile[0] := FFileName;
آرایه تقریبا یه جور اشاره گر هست به اولین عضو.
اگه چیز دیگه ای تو نظرت هست بگو.
به نظرم برای FileName بهتره از string استفاده کنی چون اگه بخوای از چیزی مثل PChar استفاده کنی تو قسمت published ارور میده و char هم که خوب یک کاراکتر بیشتر نیست. بعدا موقع نسبت دادن مقادیر به هم می تونی براش تابع بنویسی و به شکل باینری اطلاعاتشو تو آرایه بریزی با استفاده از Move یا CopyMemory یا همچین چیزی و یا با یک حلقه for.

بهروز عباسی
سه شنبه 23 اسفند 1390, 00:55 صبح
اگه ممکنه راه حلی بگو که کد بالا درست کار کنه(حتی با تغییرکد)ممنون میشم اگه کمک کنی.

بهروز عباسی
سه شنبه 23 اسفند 1390, 00:59 صبح
FFileName چیزی که کار برباید وارد کنه من فقط میخوام برنامه این قدارو بخونه و خروجی رو به همین حالا نوعFFileName چی باشه مهم نیست فقط برنامه گیرنده
راهی برای این کار هست.

Ananas
سه شنبه 23 اسفند 1390, 01:00 صبح
پستو ویرایش کردم احتمالا ندیدیش :
به نظرم برای FileName بهتره از string استفاده کنی چون اگه بخوای از چیزی مثل PChar استفاده کنی تو قسمت published ارور میده و char هم که خوب یک کاراکتر بیشتر نیست. بعدا موقع نسبت دادن مقادیر به هم می تونی براش تابع بنویسی و به شکل باینری اطلاعاتشو تو آرایه بریزی با استفاده از Move یا CopyMemory یا همچین چیزی و یا با یک حلقه for.

بهروز عباسی
سه شنبه 23 اسفند 1390, 01:08 صبح
به نظرم برای FileName بهتره از string استفاده کنی چون...
اول ازstring استفاده کردم بازم گیر دار باPchar تبدیلش کردم بازم گیر داد...
نمیدونم چکار کنم

بهروز عباسی
سه شنبه 23 اسفند 1390, 01:15 صبح
اینم خطایی که هنگام کامپایل بانوع string میده.

[DCC Error] PCshortcutTarget.pas(72): E2010 Incompatible types: 'array[0..260] of Char' and 'string'

Ananas
سه شنبه 23 اسفند 1390, 01:19 صبح
اینو امتحان کن :

unit PCshortcutTarget;

interface

uses
SysUtils, Classes,
ComObj , Activex, ShlObj,Windows;

type
TArrayChar = array [0 .. MAX_PATH] of Char;
PShellLinkInfoStruct = ^TShellLinkInfoStruct;
TShellLinkInfoStruct = record
FullPathAndNameOfLinkFile: TArrayChar;//array [0 .. MAX_PATH] of Char;
FullPathAndNameOfFileToExecute: TArrayChar;//array [0 .. MAX_PATH] of Char;
FindData: TWIN32FINDDATA;
end;

TPCShortcutTarget = class(TComponent)
private

FFileName: string;//PWideChar;


procedure GetLinkInfo(lpShellLinkInfoStruct: PShellLinkInfoStruct);
protected
{ Protected declarations }
public
function Get_Target:string;
published
property FileName:string read FFileName write FFileName ;
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('programming-Co', [TPCShortcutTarget]);
end;

{ TPCShortcutTarget }

procedure TPCShortcutTarget.GetLinkInfo(
lpShellLinkInfoStruct: PShellLinkInfoStruct);
var
ShellLink: IShellLink;
PersistFile: IPersistFile;
AnObj: IUnknown;
begin
// access to the two interfaces of the object
AnObj := CreateComObject(CLSID_ShellLink);
ShellLink := AnObj as IShellLink;
PersistFile := AnObj as IPersistFile;

// Opens the specified file and initializes an object from the file contents.
PersistFile.Load
(PWChar(WideString(lpShellLinkInfoStruct^.FullPath AndNameOfLinkFile)), 0);
with ShellLink do
begin
// Retrieves the path and file name of a Shell link object.
GetPath(lpShellLinkInfoStruct^.FullPathAndNameOfFi leToExecute,
SizeOf(lpShellLinkInfoStruct^.FullPathAndNameOfLin kFile),
lpShellLinkInfoStruct^.FindData, SLGP_UNCPRIORITY);
end;


end;

function TPCShortcutTarget.Get_Target: string;
var
LinkInfo: TShellLinkInfoStruct;
//i : Integer;
j : Integer;
begin
j := Length(FFileName);
if j > MAX_PATH then
j := MAX_PATH;
//---------------------
{
for i := 0 to j do
begin
LinkInfo.FullPathAndNameOfLinkFile[i] := FFileName[i];
end;
}
Move(FFileName[1], LinkInfo.FullPathAndNameOfLinkFile[0], SizeOf(Char) * j);
LinkInfo.FullPathAndNameOfLinkFile[j] := #00;
//---------------------
GetLinkInfo(@LinkInfo);
Result:=(LinkInfo.FullPathAndNameOfFileToExecute);
end;

end.

بهروز عباسی
سه شنبه 23 اسفند 1390, 01:28 صبح
خیـــــــــــــــــــلی ممنون از کمک درست شد اگه ممکنه کمی در باره تغییراتی که دادی توضیح بده اگرهم نه که بازم ممنون .

Ananas
سه شنبه 23 اسفند 1390, 01:41 صبح
متشکر.
تابع Move رو که CopyMemory هم ازش استفاده میکنه یک متغیر منبع و یک متغیر مقصد رو میگیره و تعدادی بایت رو از منبع به مقصد کپی می کنه. از اونجایی که آرایه ما و اون string هر دو اطلاعاتشون در حافظه به شکل پشت سر هم قرار داره می تونیم این کار رو با Move انجام بدیم. و اگه بیشتر از مقدار فضای آرایه بخوایم کپی کنیم ممکنه با خطا مواجه بشیم پس نوشتم :

j := Length(FFileName);
if j > MAX_PATH then
j := MAX_PATH;

______________
متغیر های رشته ای مثل string و PWideChar یا PAnsiChar (که دو تا آخری اشاره گر هستند) برای مشخص شدن پایان رشته از کاراکتر nil استفاده میکنن. یعنی هر کجا که رشته میرسه به کاراکتر 0 اونجا آخر متن هست. پس بعد از متنمون یک کاراکتر اظافه رو با مقدار nil یا همون 0 یا #00 به رشته اضافه میکنیم تا مطمئن بشیم رشته رو بستیم.

LinkInfo.FullPathAndNameOfLinkFile[j] := #00;

البته شاید خود string این کارو کرده باشه یعنی لازم نباشه که ما دستی به اون مقدار بدیم و به مقدار Length(s) + 1 تا کاراکتر کپی رو انجام بدیم ولی من برای اطمینان اون رو دستی وارد کردم.