Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2010.10.03;
Скачать: CL | DM;

Вниз

Property & var   Найти похожие ветки 

 
faiwer ©   (2010-07-11 20:43) [0]

Доброго времени суток. Не могу никак врубиться вот во что:

private
 aFolder: string;
 procedure setFolder(Value: string);
public
 property Folder: string read aFolder write setFolder;
 ...
end;

...
Some(..., {тут var} Folder);
...


Не работает. "[DCC Error] Tags.pas(99): E2197 Constant object cannot be passed as var parameter". Временно решаю так:

var
 s: string;
begin
 s:=Folder;
 Some(...,s);
 Folder:=s;


Как то не красиво :) Или так и надо?)

P.S. D2009 W7


 
Юрий Зотов ©   (2010-07-11 20:48) [1]

Приведите точный и полный текст методов SetFolder и Some.


 
Jeer ©   (2010-07-11 20:48) [2]

Не видно реализации SetFolder, к примеру.


 
faiwer ©   (2010-07-11 21:22) [3]

Хм ок, я думал это не важно.

   aFrom: string;
   procedure setFrom(Value: string);
   function getFrom: string;
   property From: string read getFrom write setFrom;


procedure TTagsF.setFrom(Value: string);
begin
 if DirectoryExists(Value) then aFrom:=Value
   else if Value="" then aFrom:=""
     else begin
       GoM.Enabled:=false;
       exit;
     end;

 GoM.Enabled:=true;
 FolderE.Text:=aFrom;
end;


А вот Some() будет сложнее, ибо большая копипаста :D

function BrowseCallbackProc(hwnd: HWND; uMsg: UINT; lParam: LPARAM; lpData: LPARAM): Integer; stdcall;
begin
 if (uMsg = BFFM_INITIALIZED) then
   SendMessage(hwnd, BFFM_SETSELECTION, 1, lpData);
 BrowseCallbackProc:= 0;
end;

function GetFolderDialog(Handle: Integer; Caption: string; var strFolder: string): Boolean;
const
 BIF_STATUSTEXT           = $0004;
 BIF_NEWDIALOGSTYLE       = $0040;
 BIF_RETURNONLYFSDIRS     = $0080;
 BIF_SHAREABLE            = $0100;
 BIF_USENEWUI             = BIF_EDITBOX or BIF_NEWDIALOGSTYLE;

var
 BrowseInfo: TBrowseInfo;
 ItemIDList: PItemIDList;
 JtemIDList: PItemIDList;
 Path: PChar;
begin
 Result:= False;
 Path:=StrAlloc(MAX_PATH);
 SHGetSpecialFolderLocation(Handle, CSIDL_DRIVES, JtemIDList);
 with BrowseInfo do
 begin
   hwndOwner:= GetActiveWindow;
   pidlRoot:= JtemIDList;
   SHGetSpecialFolderLocation(hwndOwner, CSIDL_DRIVES, JtemIDList);

   { Возврат названия выбранного элемента }
   pszDisplayName:= StrAlloc(MAX_PATH);

   { Установка названия диалога выбора папки }
   lpszTitle:= PChar(Caption); // "Выбрать папку на Delphi (Дельфи)";
   { Флаги, контролирующие возврат }
   lpfn:= @BrowseCallbackProc;
   { Дополнительная информация, которая отдаётся обратно в обратный вызов (callback) }
   lParam:= LongInt(PChar(strFolder));
 end;

 ItemIDList:= SHBrowseForFolder(BrowseInfo);

 if (ItemIDList <> nil) then
   if SHGetPathFromIDList(ItemIDList, Path) then
   begin
     strFolder:= Path;
     Result:= True;
   end;
end;


 
Омлет ©   (2010-07-11 22:05) [4]

Ясно же сказано - свойство не может быть передано как var параметр.

> Как то не красиво :) Или так и надо?)

Так и надо.


 
Омлет ©   (2010-07-11 22:08) [5]

Причем, в данном случае ничего некрасивого:

if (GetFolderDialog(..., s) then
 From := s;


 
faiwer ©   (2010-07-11 22:10) [6]


> Ясно же сказано - свойство не может быть передано как var
> параметр.

Constant object - переводится несколько иначе, нежели свойство :) В виду чего я решил, что я что то не правильно описал.


> Так и надо.

Ясно, thx


 
faiwer ©   (2010-07-11 22:12) [7]


> Причем, в данном случае ничего некрасивого:
>
> if (GetFolderDialog(..., s) then
>  From := s;


Неа, не так ) Вот так:


>   s:=From;
>   if GetFolderDialog(...,s)
>     then From:=s;


Иначе диалоговое окно всегда будет открываться на "моём компьютере" а не на папке == From :D


 
Омлет ©   (2010-07-11 22:16) [8]

Передавай еще один параметр с текущей папкой, тогда избавишься от лишнего присваивания

function GetFolderDialog(Handle: Integer; const Caption, CurFolder: string; out resultFolder: string): Boolean;
...

 if GetFolderDialog(Handle, Caption, From, s) then
   From := s;


 
Leonid Troyanovsky ©   (2010-07-12 07:49) [9]


> faiwer ©   (11.07.10 21:22) [3]

> procedure TTagsF.setFrom(Value: string);

Связь setFrom & GetFolderDialog не раскрыта.

>    if SHGetPathFromIDList(ItemIDList, Path)

А освобождать ItemIDList, Path будет Пушкин?

--
Regards, LVT.


 
faiwer ©   (2010-07-12 10:00) [10]


> Связь setFrom & GetFolderDialog не раскрыта.


Теперь связь такая:

procedure TTagsF.BrowseBClick(Sender: TObject);
var
 s: string;
begin
 if GetFolderDialog(Handle,"Выберите директорию",From,s)
   then From:=s;
end;


Предполагалась, до ответа Омлета, такая: GetFolderDialog(Handle,"...",From);


> А освобождать ItemIDList, Path будет Пушкин?

А как освободить PChar и PItemIDList? Так?

Dispose(Path);
Dispose(ItemIDList);
Dispose(JtemIDList);


внутри TBrowseInfo тоже много PChar-ов и PItemIDList-ов, его тоже надо как то освобождать? GetFolderDialog() не моя, я не понимаю толком, как она работает.


 
Leonid Troyanovsky ©   (2010-07-12 10:19) [11]


> faiwer ©   (12.07.10 10:00) [10]

> А как освободить PChar и PItemIDList? Так?

1. AllocMem-FreeMem
2. By Peter Below:

Uses ShlObj, ActiveX;

Getting the Personal files directory:

Procedure FreePidl( pidl: PItemIDList );
 Var
   allocator: IMalloc;
 Begin
   If Succeeded(SHGetMalloc(allocator)) Then Begin
     allocator.Free(pidl);
   {$IFDEF VER90}
     allocator.Release;
   {$ENDIF}
   End;
 End;

procedure TForm1.Button2Click(Sender: TObject);
Var
 pidl: PItemIDList;
 buf: Array[0..MAX_PATH] of Char;
begin
 If Succeeded( ShGetSpecialFolderLocation( Handle, CSIDL_PERSONAL,
pidl ))
 Then Begin
   If ShGetPathfromIDList( pidl, buf ) Then
     ShowMessage( buf );
   FreePIDL( pidl );
 End;
end;

--
Regards, LVT.


 
faiwer ©   (2010-07-12 10:33) [12]

Добавил в конец процедуры

 FreePIDL(ItemIDList);
 FreePIDL(JtemIDList);
 FreePIDL(BrowseInfo.pidlRoot);
 FreeMem(Path);


Но получаю ошибку на FreeMem(Path);
Invalid Pointer Operation

Хотя вот в этом примере - точно также http://www.delphibasics.ru/FreeMem.php


 
Anatoly Podgoretsky ©   (2010-07-12 11:07) [13]

> faiwer  (12.07.2010 10:33:12)  [12]

Ты наверно испортил Path


 
faiwer ©   (2010-07-12 11:16) [14]

На данный момент этот чудо код по показу древа папок выглядит так :) :

function BrowseCallbackProc(hwnd: HWND; uMsg: UINT; lParam: LPARAM; lpData: LPARAM): Integer; stdcall;
begin
 if (uMsg = BFFM_INITIALIZED) then
   SendMessage(hwnd, BFFM_SETSELECTION, 1, lpData);
 BrowseCallbackProc:= 0;
end;

procedure FreePidl( pidl: PItemIDList );
var
 allocator: IMalloc;
begin
 If Succeeded(SHGetMalloc(allocator)) then begin
   allocator.Free(pidl);
   {$IFDEF VER90}
     allocator.Release;
   {$ENDIF}
 end;
end;

function GetFolderDialog(Handle: Integer; Caption, Default: string;
                        out strFolder: string): Boolean;
const
 BIF_STATUSTEXT           = $0004;
 BIF_NEWDIALOGSTYLE       = $0040;
 BIF_RETURNONLYFSDIRS     = $0080;
 BIF_SHAREABLE            = $0100;
 BIF_USENEWUI             = BIF_EDITBOX or BIF_NEWDIALOGSTYLE;

var
 BrowseInfo: TBrowseInfo;
 ItemIDList: PItemIDList;
 JtemIDList: PItemIDList;
 Path: PChar;
begin
 Result:= False;
 Path:=StrAlloc(MAX_PATH);
 SHGetSpecialFolderLocation(Handle, CSIDL_DRIVES, JtemIDList);
 with BrowseInfo do
 begin
   hwndOwner:= GetActiveWindow;
   pidlRoot:= JtemIDList;
   SHGetSpecialFolderLocation(hwndOwner, CSIDL_DRIVES, JtemIDList);

   { Возврат названия выбранного элемента }
   pszDisplayName:= StrAlloc(MAX_PATH);

   { Установка названия диалога выбора папки }
   lpszTitle:= PChar(Caption); // "Выбрать папку на Delphi (Дельфи)";
   { Флаги, контролирующие возврат }
   lpfn:= @BrowseCallbackProc;
   { Дополнительная информация, которая отдаётся обратно в обратный вызов (callback) }
   lParam:= LongInt(PChar(Default));
 end;

 ItemIDList:= SHBrowseForFolder(BrowseInfo);

 if (ItemIDList <> nil) then
   if SHGetPathFromIDList(ItemIDList, Path) then
   begin
     strFolder:= Path;
     Result:= True;
   end;

 FreePIDL(ItemIDList);
 FreePIDL(JtemIDList);
 FreePIDL(BrowseInfo.pidlRoot);
end;


Когда мышкой навожу на Path вижу что там не пусто )


 
Leonid Troyanovsky ©   (2010-07-12 11:34) [15]


> faiwer ©   (12.07.10 11:16) [14]

>  FreePIDL(BrowseInfo.pidlRoot);

Оно лишнее, бо BrowseInfo.pidlRoot:= JtemIDList;

> StrAlloc(MAX_PATH);

А для StrAlloc нет StrDispose.

--
Regards, LVT.



Страницы: 1 вся ветка

Текущий архив: 2010.10.03;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.008 c
2-1278159774
alex810
2010-07-03 16:22
2010.10.03
Запрос с нечувствительностью к регистру


15-1277989076
12
2010-07-01 16:57
2010.10.03
Как Вам х.ф. Сумерки.Затмение ?


3-1245876026
Miau
2009-06-25 00:40
2010.10.03
Передача параметра в хранимую процедуру.


2-1278658000
Виталий
2010-07-09 10:46
2010.10.03
Установить группу битов числа


13-1126182925
Ilya39
2005-09-08 16:35
2010.10.03
Потоки в C#