본문 바로가기
Delphi/문법

델파이 포인터 (Pointer) 10편

by MonoSoft 2023. 8. 23.
728x90
반응형

델파이 포인터 (Pointer) 10편

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;

  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
반응형

'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

댓글