델파이 포인터 (Pointer) 10편
ShellApi 를 이용할때 윈도우에서 사용하는 언어인
'C' 와 델파이의 'Pascal'의 포인터 다루는 방법이 달라
많은 혼동(나만?)을 일으킵니다.
특히나 파스칼에서는 포인터방법이 여러가지가 있어 햇갈리기 아주 좋습니다.
해서 한번 정리하여 보았습니다.
예제는 폴더를 찾아 지정하는 SHBrowseForFolder 를 이용하는 것으로 하였습니다.
1. 버퍼를 이용하는 방법
var Buffer : array[0..255] of char;
begin
pszDisplayName:= @Buffer;
.......
MessageBox(handle, Buffer, '', MB_OK);
end;
2. pChar 를 이용하는 방법 : 'C' 와 유사하지요
var Buffer: pChar;
begin
GetMem(Buffer, 256);
pszDisplayName := Buffer
......
MessageBox(handle, Buffer, '', MB_OK);
FreeMem(Buffer);
end;
3. string 을 이용하는 방법 : 속도 면에서 가장 불리한 방법이라고 하데요.
var Buffer: string;
begin
SetLength(Buffer,256);
pszDisplayname:= @Buffer[1]; // 이 방법
MessageBox(handle, pChar(Buffer), '', MB_OK); // 이 방법
end;
사족: buffer[1]은 buffer 스트링의 첫번째 문자를 가르킵니다.
그러므로 @Buffer[1]은 그 주소..
4. pointer를 이용하는 방법 : pchar와 유사
var
Buffer: pointer;
tempStr: string;
begin
GetMem(buffer,256);
pszDisplayname:= Buffer;
MessageBox(handle, Buffer, '', MB_OK);
tempStr:= pChar(Buffer);
end;
방법 1에 의한 예제
function TfrmDemo.OpenFolderDialog(ATitle: String; var DirName: String): Boolean;
var
lpItemID : PItemIDList;
BrowseInfo : TBrowseInfo;
Buffer : array[0..MAX_PATH] of Char; // 이곳
begin
DirName := '';
FillChar(BrowseInfo, SizeOf(TBrowseInfo), #0);
with BrowseInfo do
begin
hwndOwner := Handle;
pszDisplayName := @Buffer; //이곳
lpszTitle := PChar(ATitle);
ulFlags := BIF_RETURNONLYFSDIRS;
end;
lpItemID := SHBrowseForFolder(BrowseInfo);
Result := not (lpItemId = nil);
MessageBox(handle, Buffer,'',MB_OK); // 이곳
if lpItemId <> nil then
begin
SHGetPathFromIDList(lpItemID, Buffer); // 이곳
DirName := Buffer; // 이곳
end;
// GlobalFreePtr(lpItemID); // pascal 에서 필요한가요?
end;
방법 2에 의한 예제
function TfrmDemo.OpenFolderDialog(ATitle: String; var DirName: String):Boolean;
var
lpItemID : PItemIDList;
BrowseInfo : TBrowseInfo;
Buffer : pchar; // 이곳
begin
DirName := '';
FillChar(BrowseInfo, SizeOf(TBrowseInfo), #0);
GetMem(Buffer, MAX_PATH+1); // 이곳
with BrowseInfo do
begin
hwndOwner := Handle;
pszDisplayName := Buffer; // 이곳
lpszTitle := PChar(ATitle);
ulFlags := BIF_RETURNONLYFSDIRS;
end;
lpItemID := SHBrowseForFolder(BrowseInfo);
Result := not (lpItemId = nil);
MessageBox(handle, Buffer,'',MB_OK); // 이곳
if lpItemId <> nil then
begin
SHGetPathFromIDList(lpItemID, Buffer); // 이곳
DirName := Buffer; //이곳
end;
FreeMem(Buffer); // 이곳
end;
방법 3에 의한 방법
function TfrmDemo.OpenFolderDialog(ATitle: String; var DirName: String): Boolean;
var
lpItemID : PItemIDList;
BrowseInfo : TBrowseInfo;
begin
FillChar(BrowseInfo, SizeOf(TBrowseInfo), #0);
setLength(DirName, MAX_PATH+1); // 이것 생략하면...
with BrowseInfo do
begin
hwndOwner := Handle;
pszDisplayName := @DirName[1]; // 이곳
lpszTitle := PChar(ATitle);
ulFlags := BIF_RETURNONLYFSDIRS;
end;
lpItemID := SHBrowseForFolder(BrowseInfo);
Result := not (lpItemId = nil);
MessageBox(handle, @DirName[1],'',MB_OK); // 이곳
if lpItemId <> nil then
begin
SHGetPathFromIDList(lpItemID, @DirName[1]); //이곳
end
else
DirName:= '';
end;
방법 3의 더욱 정확한 방법
function TfrmDemo.OpenFolderDialog(ATitle: String; var DirName: String): Boolean;
var
lpItemID : PItemIDList;
BrowseInfo : TBrowseInfo;
begin
FillChar(BrowseInfo, SizeOf(TBrowseInfo), #0);
SetLength(DirName, MAX_PATH+1); // 만약 이것을 생략하면 어떻게 될까요?
with BrowseInfo do
begin
hwndOwner := Handle;
pszDisplayName := pChar(DirName);
lpszTitle := PChar(ATitle);
ulFlags := BIF_RETURNONLYFSDIRS;
end;
lpItemID := SHBrowseForFolder(BrowseInfo);
Result := not (lpItemId = nil);
MessageBox(handle, pChar(DirName),'',MB_OK);
if lpItemId <> nil then
begin
SHGetPathFromIDList(lpItemID, pChar(DirName));
end
else
DirName:= '';
end;
'Delphi > 문법' 카테고리의 다른 글
델파이 Owner 와 Parent (0) | 2023.09.13 |
---|---|
델파이 포인터 (Pointer) 11편 (0) | 2023.08.24 |
델파이 포인터 (Pointer) 9편 (0) | 2023.08.22 |
델파이 포인터 (Pointer) 8편 (0) | 2023.08.21 |
델파이 포인터 (Pointer) 7편 (0) | 2023.08.11 |
댓글