![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Property & var
faiwer © (2010-07-11 20:43:00)Доброго времени суток. Не могу никак врубиться вот во что:
private
aFolder: string;
proceduresetFolder(Value: string);
public
propertyFolder: string readaFolder writesetFolder;
...
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
Leonid Troyanovsky (2010-07-12 11:34:00) [1]
> faiwer © (12.07.10 11:16) [14]
> FreePIDL(BrowseInfo.pidlRoot);
Оно лишнее, бо BrowseInfo.pidlRoot:= JtemIDList;
> StrAlloc(MAX_PATH);
А для StrAlloc нет StrDispose.
--
Regards, LVT.
faiwer (2010-07-12 11:16:00) [2]На данный момент этот чудо код по показу древа папок выглядит так :) :
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 вижу что там не пусто )
Anatoly Podgoretsky (2010-07-12 11:07:00) [3]> faiwer (12.07.2010 10:33:12) [12]
Ты наверно испортил Path
faiwer (2010-07-12 10:33:00) [4]Добавил в конец процедуры
FreePIDL(ItemIDList);
FreePIDL(JtemIDList);
FreePIDL(BrowseInfo.pidlRoot);
FreeMem(Path);
Но получаю ошибку на FreeMem(Path);
Invalid Pointer Operation
Хотя вот в этом примере - точно также http://www.delphibasics.ru/FreeMem.php
Leonid Troyanovsky (2010-07-12 10:19:00) [5]
> 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:00:00) [6]
> Связь 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 07:49:00) [7]
> faiwer © (11.07.10 21:22) [3]
> procedure TTagsF.setFrom(Value: string);
Связь setFrom & GetFolderDialog не раскрыта.
> if SHGetPathFromIDList(ItemIDList, Path)
А освобождать ItemIDList, Path будет Пушкин?
--
Regards, LVT.
Омлет (2010-07-11 22:16:00) [8]Передавай еще один параметр с текущей папкой, тогда избавишься от лишнего присваивания
function GetFolderDialog(Handle: Integer; const Caption, CurFolder: string; out resultFolder: string): Boolean;
...
if GetFolderDialog(Handle, Caption, From, s) then
From := s;
faiwer (2010-07-11 22:12:00) [9]
> Причем, в данном случае ничего некрасивого:
>
> if (GetFolderDialog(..., s) then
> From := s;
Неа, не так ) Вот так:
> s:=From;
> if GetFolderDialog(...,s)
> then From:=s;
Иначе диалоговое окно всегда будет открываться на "моём компьютере" а не на папке == From :D
faiwer (2010-07-11 22:10:00) [10]
> Ясно же сказано - свойство не может быть передано как var
> параметр.
Constant object - переводится несколько иначе, нежели свойство :) В виду чего я решил, что я что то не правильно описал.
> Так и надо.
Ясно, thx
Омлет (2010-07-11 22:08:00) [11]Причем, в данном случае ничего некрасивого:
if (GetFolderDialog(..., s) then
From := s;
Омлет (2010-07-11 22:05:00) [12]Ясно же сказано - свойство не может быть передано как var параметр.
> Как то не красиво :) Или так и надо?)
Так и надо.
faiwer (2010-07-11 21:22:00) [13]Хм ок, я думал это не важно.
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 20:48:00) [14]Приведите точный и полный текст методов SetFolder и Some.
Jeer (2010-07-11 20:48:00) [15]Не видно реализации SetFolder, к примеру.