본문 바로가기
Delphi/문법

델파이 포인터 사용 팁

by MonoSoft 2024. 7. 4.
728x90
반응형

델파이 포인터 사용 팁

728x90

 

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; //07.12.05 er추가함

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;

 

728x90
반응형

댓글