Q&A

  • Re: 프린터 등록정보에 관한 질문 입니다.(소스포함)
안녕하세요. 최용일입니다.



예전에 자유게시판에 쓴글이 있는데 그걸 이용하시면 되겠군요. 아래 링크를 참고하시면 ShellExecuteEx의 실행이 끝난뒤에 메세지가 출력될겁니다.



http://www.delphi.co.kr/cgi-bin/cwb/CrazyWWWBoard.cgi?mode=read&num=6276&db=freetalk&ftype=7&fval=shellexecuteex&backdepth=1



^^ 항상 즐코하세요...



완저초보 wrote:

> 안녕하세요!

> 어제 한델에서 받은 소스를 이용해서 테스트용으로 만들었는데

> 잘되는 안는군요!!

> 문제의부분을 (**********표시부분) 실행하고 다음에 그부분아래의 함수를

> 실행하려고 했더니 같이 실행되더군요!

> 혹시 문제의 부분을 실행하고 난후에 그 부분아래의 함수를 실행할수는 없을까요??

> 아시는 고수님들의 조언을 부탁드림니다..

> 무지급하거든요?

> 오늘안에 해결해야되요!!

> 도와주세요!!

> 소스!!!!

> unit Unit1;

>

> interface

>

> uses

> Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

> StdCtrls, printers, ActiveX, ShlObj, ShellAPI;

>

> type

> TForm1 = class(TForm)

> Button1: TButton;

> ListBox1: TListBox;

> ComboBox1: TComboBox;

> Button2: TButton;

> procedure Button1Click(Sender: TObject);

> procedure FormShow(Sender: TObject);

> procedure Button2Click(Sender: TObject);

> private

> { Private declarations }

> public

> { Public declarations }

> FUNCTION ExecuteAddPrinter: BOOLEAN;

> FUNCTION GetAddPrinterItem(CONST Allocator: IMalloc): pItemIDList;

>

> FUNCTION GetItemIDName(CONST Folder: IShellFolder;

> CONST ItemIDList: pItemIDList;

> CONST Flags: INTEGER;

> CONST Name: pCHAR;

> CONST MaxNameLength: INTEGER): BOOLEAN;

> FUNCTION GetPrinterItemIDList(CONST DeskTopFolder: IShellFolder): pItemIDList;

> FUNCTION GetThisPrinter(CONST PrinterName: STRING; CONST Allocator: IMalloc): pItemIDlist;

>

> FUNCTION ItemIDListCreate(CONST Allocator: IMalloc; CONST size: INTEGER): pItemIDList;

> FUNCTION ItemIDListGetNextItem(CONST ItemIDList: pItemIDList): pItemIDList;

> FUNCTION ItemIDListGetSize(CONST ItemIDList: pItemIDList): INTEGER; {size in bytes}

>

> FUNCTION ItemIDListsConcatenate(CONST Allocator: IMalloc;

> CONST List1, List2: pItemIDList): pItemIDlist;

>

> FUNCTION OpenPrinterProperties(CONST PrinterName: STRING): BOOLEAN;

> FUNCTION OpenThisPrinter(CONST PrinterName: STRING): BOOLEAN;

> end;

>

> var

> Form1: TForm1;

>

> implementation

>

> TYPE

> ESHprintersError = CLASS(Exception);

>

> {$R *.DFM}

>

> procedure TForm1.Button1Click(Sender: TObject);

> var

> PrinterName: String;

> begin

> // 프린터 리스트를 구한다

> ListBox1.Items := Printer.Printers;

>

> // default printe의 이름을 구한다

> PrinterName := Printer.Printers[ComboBox1.Itemindex];

> PrinterName := COPY(PrinterName,1,POS(' on ', PrinterName)-1);

>

> // 기본 프린터의 등록정보(Properties)를 보여준다

> if not OpenPrinterProperties(PrinterName) then

> ShowMessage('"Printer Properties" for ' +PrinterName+ ' are not available');

>

> ShowMessage('ddddd');

>

> end;

>

>

> procedure TForm1.FormShow(Sender: TObject);

> begin

> ComboBox1.Items := Printer.Printers;

> ComboBox1.ItemIndex := Printer.PrinterIndex;

>

> end;

>

> procedure TForm1.Button2Click(Sender: TObject);

> begin

> close;

> end;

>

> // See ExecuteAddPrinter in Printers.CPP (line 359)

> FUNCTION TForm1.ExecuteAddPrinter: BOOLEAN;

> VAR

> AddPrinterItemIDList: pItemIDList;

> Allocator : IMalloc;

> ShellExecuteInfo : TShellExecuteInfo;

> BEGIN

> RESULT := FALSE;

>

> IF CoGetMalloc(MEMCTX_TASK, Allocator) = S_OK

> THEN BEGIN

> AddPrinterItemIDList := GetAddPrinterItem(Allocator);

> TRY

> IF AddPrinterItemIDList = NIL

> THEN RESULT := FALSE

> ELSE BEGIN

> ZeroMemory(@ShellExecuteInfo, SizeOf(TShellExecuteInfo));

>

> WITH ShellExecuteInfo DO

> BEGIN

> cbSize := SizeOf(TShellExecuteInfo);

> fMask := SEE_MASK_INVOKEIDLIST OR SEE_MASK_FLAG_NO_UI;

> lpIDList := AddPrinterItemIDlist;

> nShow := SW_SHOWDEFAULT

> END;

>

> ShellExecuteEx(@ShellExecuteInfo);

> RESULT := TRUE

> END

> FINALLY

> Allocator.Free(AddPrinterItemIDList)

> END

> END

> END {ExecuteAddPrinter};

>

>

> // See GetAddPrinterItem in Printers.CPP (line 428)

> FUNCTION TForm1.GetAddPrinterItem(CONST Allocator: IMalloc): pItemIDList;

> VAR

> DeskTopFolder : IShellFolder;

> EnumIDList : IEnumIDList;

> hOK : hResult;

> PrinterItemIDList: pItemIDList;

> PrintersFolder : IShellFolder;

> Retrieved : INTEGER;

> TargetItemIDList : pItemIDList;

> TempItemIDList : pItemIDList;

> BEGIN

> TargetItemIDList := NIL;

>

> IF Allocator <> NIL

> THEN BEGIN

>

> IF Succeeded(SHGetDesktopFolder(DeskTopFolder))

> THEN BEGIN

>

> PrinterItemIDList := GetPrinterItemIDList(DeskTopFolder);

> IF PrinterItemIDList <> NIL

> THEN BEGIN

> // Get the IShellFolder for Printers

> hOK := DeskTopFolder.BindToObject(PrinterItemIDList,

> NIL,

> IID_IShellFolder,

> Pointer(PrintersFolder));

> IF Succeeded(hOK)

> THEN BEGIN

> IF Succeeded(PrintersFolder.EnumObjects(0, SHCONTF_FOLDERS OR SHCONTF_NONFOLDERS,

> EnumIDList))

> THEN BEGIN

> // Get the first item's ItemIDList. This will be the item for adding a printer.

> hOK := EnumIDList.Next(1, TempItemIDList, Retrieved);

>

> IF (Retrieved > 0) AND Succeeded(hOK)

> THEN TargetItemIDList := ItemIDListsConcatenate(Allocator,

> PrinterItemIDList,

> TempItemIDList);

>

> END

>

> END

> END

>

> END;

> END;

>

> RESULT := TargetItemIDList

> END {GetAddPrinterItem};

>

>

> // See GetItemIDName in Printers.CPP (line 551)

> FUNCTION TForm1.GetItemIDName(CONST Folder: IShellFolder;

> CONST ItemIDList: pItemIDList;

> CONST Flags: INTEGER;

> CONST Name: pCHAR;

> CONST MaxNameLength: INTEGER): BOOLEAN;

> VAR

> p : PCHAR;

> StrRet: TStrRet;

> BEGIN

> RESULT := TRUE; // Be optimistic

> IF Succeeded(Folder.GetDisplayNameOf(ItemIDList, Flags, StrRet))

> THEN BEGIN

> CASE StrRet.uType OF

> STRRET_WSTR: WideCharToMultiByte(CP_ACP, 0, StrRet.pOleStr,

> -1, Name, MaxNameLength,

> NIL, NIL);

>

> STRRET_OFFSET:

> BEGIN

> p := pCHAR(ItemIDlist);

> INC(p, StrRet.uOffset);

> StrLCopy(Name, p, MaxNameLength)

> END;

>

> STRRET_CSTR: StrLCopy(Name, StrRet.cStr, MaxNameLength)

>

> ELSE

> RESULT := FALSE

> END

> END

> ELSE RESULT := FALSE

> END {GetItemIDName};

>

>

> // See GetPrintersPidl in Printers.CPP (line 406)

> FUNCTION TForm1.GetPrinterItemIDList(CONST DeskTopFolder: IShellFolder): pItemIDlist;

> VAR

> hOK : hResult;

> PrinterItemIDList: pItemIDList;

> BEGIN

> IF DeskTopFolder = NIL

> THEN RESULT := NIL

> ELSE BEGIN

> hOK := SHGetSpecialFolderLocation(0,

> CSIDL_PRINTERS, // Virtual folder of installed printers

> PrinterItemIDList);

> IF Failed(hOK)

> THEN RESULT := NIL

> ELSE RESULT := PrinterItemIDList

> END

> END {GetPrinterItemIDList};

>

>

> // See GetThisPrinter in Printers.CPP (line 485)

> FUNCTION TForm1.GetThisPrinter(CONST PrinterName: STRING;

> CONST Allocator: IMalloc): pItemIDlist;

> VAR

> Continue : BOOLEAN;

> DeskTopFolder : IShellFolder;

> EnumIDList : IEnumIDList;

> hOK : hResult;

> PrinterItemIDList: pItemIDList;

> PrintersFolder : IShellFolder;

> Retrieved : INTEGER;

> TargetItemIDList : pItemIDList;

> TempItemIDList : pItemIDList;

> TempString : ARRAY[0..255] OF CHAR;

> BEGIN

> TargetItemIDList := NIL;

>

> IF Allocator <> NIL

> THEN BEGIN

>

> IF Succeeded(SHGetDesktopFolder(DeskTopFolder))

> THEN BEGIN

>

> PrinterItemIDList := GetPrinterItemIDList(DeskTopFolder);

> IF PrinterItemIDList <> NIL

> THEN BEGIN

>

> // Get the IShellFolder for Printers

> hOK := DeskTopFolder.BindToObject(PrinterItemIDList,

> NIL,

> IID_IShellFolder,

> Pointer(PrintersFolder));

> IF Succeeded(hOK)

> THEN BEGIN

> IF Succeeded(PrintersFolder.EnumObjects(0, SHCONTF_FOLDERS OR SHCONTF_NONFOLDERS,

> EnumIDList))

> THEN BEGIN

> continue := TRUE;

> WHILE continue

> DO BEGIN

> hOK := EnumIDList.Next(1, TempItemIDList, Retrieved);

>

> // Check its name

> GetItemIDName(PrintersFolder, TempItemIDList, SHGDN_NORMAL,

> @TempString, SizeOf(TempString));

> continue := Succeeded(hOK) AND (Retrieved > 0) AND

> (StrIComp(TempString, pChar(PrinterName)) <> 0);

> END;

>

> IF (Retrieved > 0) AND Succeeded(hOK)

> THEN TargetItemIDList := ItemIDListsConcatenate(Allocator,

> PrinterItemIDList,

> TempItemIDList);

>

> END

>

> END

> END

> END

> END;

>

> RESULT := TargetItemIDList;

> END {GetThisPrinter};

>

>

> // See Pidl_Create in Printers.CPP (line 689)

> // Returns a pointer to the new ItemIDList, or NIL if a problem occurred.

> FUNCTION TForm1.ItemIDListCreate(CONST Allocator: IMalloc; CONST size: INTEGER): pItemIDList;

> VAR

> NewItemIDList: pItemIDList;

> BEGIN

> NewItemIDList := Allocator.Alloc(size);

>

> IF NewItemIDList <> NIL

> THEN ZeroMemory(NewItemIDList, size);

>

> RESULT := NewItemIDList

> END {ItemIDListCreate};

>

> // See Pidl_GetNextItem in Printers.CPP (line 710)

> // Returns a pointer to the next item in the ItemIDList (Microsoft's Pidl_GetNextItem)

> FUNCTION TForm1.ItemIDListGetNextItem(CONST ItemIDList: pItemIDList): pItemIDList;

> BEGIN

> IF ItemIDlist = NIL

> THEN RESULT := NIL

> ELSE RESULT := Pointer(INTEGER(ItemIDList) + ItemIDList.mkid.cb)

> END {ItemIDListGetNextItem};

>

>

> // See Pidl_GetSize in Printers.CPP (line 655)

> // Returns total number of bytes in an ItemIDList (Microsoft's Pidl_GetSize)

> FUNCTION TForm1.ItemIDListGetSize(CONST ItemIDList: pItemIDList): INTEGER; {size in bytes}

> VAR

> TempItemIDList: pItemIDList;

> BEGIN

> RESULT := 0;

> TempItemIDList := ItemIDList;

>

> IF TempItemIDList <> NIL

> THEN BEGIN

> WHILE (TempItemIDList.mkid.cb > 0) DO

> BEGIN

> INC(RESULT, TempItemIDList.mkid.cb);

> TempItemIDList := ItemIDListGetNextItem(TempItemIDList)

> END;

>

> // Requires a 16 bit zero value for the null terminator

> INC(RESULT, 2*SizeOf(BYTE))

> END

> END {ItemIDListGetSize};

>

>

> // See Pidl_Concatenate in Printers.CPP (line 612)

> // Creates a new ItemIDList with List1 appended to List2

> FUNCTION TForm1.ItemIDListsConcatenate(CONST Allocator: IMalloc;

> CONST List1, List2: pItemIDList): pItemIDlist;

> VAR

> List1Length : INTEGER;

> List2Length : INTEGER;

> NewItemIDList: pItemIDList;

> BEGIN

> List1Length := 0;

> // List1 can possibly be NIL if it points to the desktop. Since we only

> // need a sngle NIL terminator, we remove the extra 2 bytes from the size

> // of the first ItemIDList

> IF List1 <> NIL

> THEN List1Length := ItemIDListGetSize(List1) - 2*SizeOf(BYTE);

>

> List2Length := ItemIDListGetSize(List2);

>

> // Create a new ItemIDList that is the size of List1 and List2, then

> // copy List1 and List2 to the new list.

>

> NewItemIDList := ItemIDListCreate(Allocator, List1Length + List2Length);

>

> IF NewItemIDList <> NIL

> THEN BEGIN

> IF List1 <> NIL

> THEN CopyMemory(NewItemIDList, List1, List1Length);

>

> CopyMemory(Pointer(INTEGER(NewItemIDList) + List1Length),

> List2, List2Length)

> END;

>

> RESULT := NewItemIDList

> END {ItemIDListsConcatenate};

>

>

> // See OpenThisPrinter in Printers.CPP (line 233)

> FUNCTION TForm1.OpenThisPrinter(CONST PrinterName: STRING): BOOLEAN;

> VAR

> Allocator : IMalloc;

> PrinterItemIDList: pItemIDList;

> ShellExecuteInfo : TShellExecuteInfo;

> BEGIN

> RESULT := FALSE;

>

> IF CoGetMalloc(MEMCTX_TASK, Allocator) = S_OK

> THEN BEGIN

>

> PrinterItemIDList := GetThisPrinter(PrinterName, Allocator);

> TRY

> IF PrinterItemIDList = NIL

> THEN RESULT := FALSE

> ELSE BEGIN

> ZeroMemory(@ShellExecuteInfo, SizeOf(TShellExecuteInfo));

>

> WITH ShellExecuteInfo DO

> BEGIN

> cbSize := SizeOf(TShellExecuteInfo);

> fMask := SEE_MASK_INVOKEIDLIST OR SEE_MASK_FLAG_NO_UI;

> lpIDList := PrinterItemIDlist;

> nShow := SW_SHOWDEFAULT

> END;

>

> ShellExecuteEx(@ShellExecuteInfo);

> RESULT := TRUE

> END

> FINALLY

> Allocator.Free(PrinterItemIDList)

> END

> END

> END {OpenThisPrinter};

>

>

> // See OpenPrinterProperties in Printers.CPP (line 41)

> FUNCTION TForm1.OpenPrinterProperties(CONST PrinterName: STRING): BOOLEAN;

> VAR

> Allocator : IMalloc;

> PrinterItemIDList: pItemIDList;

> ShellExecuteInfo : TShellExecuteInfo;

> BEGIN

> RESULT := FALSE;

> IF CoGetMalloc(MEMCTX_TASK, Allocator) = S_OK

> THEN BEGIN

> PrinterItemIDList := GetThisPrinter(PrinterName, Allocator);

> TRY

> IF PrinterItemIDList = NIL

> THEN RESULT := FALSE

> ELSE BEGIN

> ZeroMemory(@ShellExecuteInfo, SizeOf(TShellExecuteInfo));

>

> WITH ShellExecuteInfo DO

> BEGIN

> fMask := SEE_MASK_INVOKEIDLIST OR SEE_MASK_FLAG_NO_UI OR SEE_MASK_NOCLOSEPROCESS;

> lpIDList := PrinterItemIDlist;

> lpVerb := 'Properties';

> nShow := SW_SHOWDEFAULT;

> cbSize := SizeOf(TShellExecuteInfo);

>

> END; //*******문제부분1

> ShellExecuteEx(@ShellExecuteInfo); <= 1

> showmessage('하하하하'); <= 1을 실행하고 확인이나취소를 했을때 실행

> RESULT := TRUE

> END

> FINALLY

> Allocator.Free(PrinterItemIDList);

>

> END;

> END;

> END; {OpenPrinterProperties}

>

> end.

>

1  COMMENTS
  • Profile
    완저초보 2001.05.19 03:04
    최용일 wrote:

    > 안녕하세요. 최용일입니다.

    >

    > 예전에 자유게시판에 쓴글이 있는데 그걸 이용하시면 되겠군요. 아래 링크를 참고하시면 ShellExecuteEx의 실행이 끝난뒤에 메세지가 출력될겁니다.

    >

    > http://www.delphi.co.kr/cgi-bin/cwb/CrazyWWWBoard.cgi?mode=read&num=6276&db=freetalk&ftype=7&fval=shellexecuteex&backdepth=1

    >

    > ^^ 항상 즐코하세요...

    >

    > 완저초보 wrote:

    > > 안녕하세요!

    > > 어제 한델에서 받은 소스를 이용해서 테스트용으로 만들었는데

    > > 잘되는 안는군요!!

    > > 문제의부분을 (**********표시부분) 실행하고 다음에 그부분아래의 함수를

    > > 실행하려고 했더니 같이 실행되더군요!

    > > 혹시 문제의 부분을 실행하고 난후에 그 부분아래의 함수를 실행할수는 없을까요??

    > > 아시는 고수님들의 조언을 부탁드림니다..

    > > 무지급하거든요?

    > > 오늘안에 해결해야되요!!

    > > 도와주세요!!

    > > 소스!!!!

    > > unit Unit1;

    > >

    > > interface

    > >

    > > uses

    > > Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

    > > StdCtrls, printers, ActiveX, ShlObj, ShellAPI;

    > >

    > > type

    > > TForm1 = class(TForm)

    > > Button1: TButton;

    > > ListBox1: TListBox;

    > > ComboBox1: TComboBox;

    > > Button2: TButton;

    > > procedure Button1Click(Sender: TObject);

    > > procedure FormShow(Sender: TObject);

    > > procedure Button2Click(Sender: TObject);

    > > private

    > > { Private declarations }

    > > public

    > > { Public declarations }

    > > FUNCTION ExecuteAddPrinter: BOOLEAN;

    > > FUNCTION GetAddPrinterItem(CONST Allocator: IMalloc): pItemIDList;

    > >

    > > FUNCTION GetItemIDName(CONST Folder: IShellFolder;

    > > CONST ItemIDList: pItemIDList;

    > > CONST Flags: INTEGER;

    > > CONST Name: pCHAR;

    > > CONST MaxNameLength: INTEGER): BOOLEAN;

    > > FUNCTION GetPrinterItemIDList(CONST DeskTopFolder: IShellFolder): pItemIDList;

    > > FUNCTION GetThisPrinter(CONST PrinterName: STRING; CONST Allocator: IMalloc): pItemIDlist;

    > >

    > > FUNCTION ItemIDListCreate(CONST Allocator: IMalloc; CONST size: INTEGER): pItemIDList;

    > > FUNCTION ItemIDListGetNextItem(CONST ItemIDList: pItemIDList): pItemIDList;

    > > FUNCTION ItemIDListGetSize(CONST ItemIDList: pItemIDList): INTEGER; {size in bytes}

    > >

    > > FUNCTION ItemIDListsConcatenate(CONST Allocator: IMalloc;

    > > CONST List1, List2: pItemIDList): pItemIDlist;

    > >

    > > FUNCTION OpenPrinterProperties(CONST PrinterName: STRING): BOOLEAN;

    > > FUNCTION OpenThisPrinter(CONST PrinterName: STRING): BOOLEAN;

    > > end;

    > >

    > > var

    > > Form1: TForm1;

    > >

    > > implementation

    > >

    > > TYPE

    > > ESHprintersError = CLASS(Exception);

    > >

    > > {$R *.DFM}

    > >

    > > procedure TForm1.Button1Click(Sender: TObject);

    > > var

    > > PrinterName: String;

    > > begin

    > > // 프린터 리스트를 구한다

    > > ListBox1.Items := Printer.Printers;

    > >

    > > // default printe의 이름을 구한다

    > > PrinterName := Printer.Printers[ComboBox1.Itemindex];

    > > PrinterName := COPY(PrinterName,1,POS(' on ', PrinterName)-1);

    > >

    > > // 기본 프린터의 등록정보(Properties)를 보여준다

    > > if not OpenPrinterProperties(PrinterName) then

    > > ShowMessage('"Printer Properties" for ' +PrinterName+ ' are not available');

    > >

    > > ShowMessage('ddddd');

    > >

    > > end;

    > >

    > >

    > > procedure TForm1.FormShow(Sender: TObject);

    > > begin

    > > ComboBox1.Items := Printer.Printers;

    > > ComboBox1.ItemIndex := Printer.PrinterIndex;

    > >

    > > end;

    > >

    > > procedure TForm1.Button2Click(Sender: TObject);

    > > begin

    > > close;

    > > end;

    > >

    > > // See ExecuteAddPrinter in Printers.CPP (line 359)

    > > FUNCTION TForm1.ExecuteAddPrinter: BOOLEAN;

    > > VAR

    > > AddPrinterItemIDList: pItemIDList;

    > > Allocator : IMalloc;

    > > ShellExecuteInfo : TShellExecuteInfo;

    > > BEGIN

    > > RESULT := FALSE;

    > >

    > > IF CoGetMalloc(MEMCTX_TASK, Allocator) = S_OK

    > > THEN BEGIN

    > > AddPrinterItemIDList := GetAddPrinterItem(Allocator);

    > > TRY

    > > IF AddPrinterItemIDList = NIL

    > > THEN RESULT := FALSE

    > > ELSE BEGIN

    > > ZeroMemory(@ShellExecuteInfo, SizeOf(TShellExecuteInfo));

    > >

    > > WITH ShellExecuteInfo DO

    > > BEGIN

    > > cbSize := SizeOf(TShellExecuteInfo);

    > > fMask := SEE_MASK_INVOKEIDLIST OR SEE_MASK_FLAG_NO_UI;

    > > lpIDList := AddPrinterItemIDlist;

    > > nShow := SW_SHOWDEFAULT

    > > END;

    > >

    > > ShellExecuteEx(@ShellExecuteInfo);

    > > RESULT := TRUE

    > > END

    > > FINALLY

    > > Allocator.Free(AddPrinterItemIDList)

    > > END

    > > END

    > > END {ExecuteAddPrinter};

    > >

    > >

    > > // See GetAddPrinterItem in Printers.CPP (line 428)

    > > FUNCTION TForm1.GetAddPrinterItem(CONST Allocator: IMalloc): pItemIDList;

    > > VAR

    > > DeskTopFolder : IShellFolder;

    > > EnumIDList : IEnumIDList;

    > > hOK : hResult;

    > > PrinterItemIDList: pItemIDList;

    > > PrintersFolder : IShellFolder;

    > > Retrieved : INTEGER;

    > > TargetItemIDList : pItemIDList;

    > > TempItemIDList : pItemIDList;

    > > BEGIN

    > > TargetItemIDList := NIL;

    > >

    > > IF Allocator <> NIL

    > > THEN BEGIN

    > >

    > > IF Succeeded(SHGetDesktopFolder(DeskTopFolder))

    > > THEN BEGIN

    > >

    > > PrinterItemIDList := GetPrinterItemIDList(DeskTopFolder);

    > > IF PrinterItemIDList <> NIL

    > > THEN BEGIN

    > > // Get the IShellFolder for Printers

    > > hOK := DeskTopFolder.BindToObject(PrinterItemIDList,

    > > NIL,

    > > IID_IShellFolder,

    > > Pointer(PrintersFolder));

    > > IF Succeeded(hOK)

    > > THEN BEGIN

    > > IF Succeeded(PrintersFolder.EnumObjects(0, SHCONTF_FOLDERS OR SHCONTF_NONFOLDERS,

    > > EnumIDList))

    > > THEN BEGIN

    > > // Get the first item's ItemIDList. This will be the item for adding a printer.

    > > hOK := EnumIDList.Next(1, TempItemIDList, Retrieved);

    > >

    > > IF (Retrieved > 0) AND Succeeded(hOK)

    > > THEN TargetItemIDList := ItemIDListsConcatenate(Allocator,

    > > PrinterItemIDList,

    > > TempItemIDList);

    > >

    > > END

    > >

    > > END

    > > END

    > >

    > > END;

    > > END;

    > >

    > > RESULT := TargetItemIDList

    > > END {GetAddPrinterItem};

    > >

    > >

    > > // See GetItemIDName in Printers.CPP (line 551)

    > > FUNCTION TForm1.GetItemIDName(CONST Folder: IShellFolder;

    > > CONST ItemIDList: pItemIDList;

    > > CONST Flags: INTEGER;

    > > CONST Name: pCHAR;

    > > CONST MaxNameLength: INTEGER): BOOLEAN;

    > > VAR

    > > p : PCHAR;

    > > StrRet: TStrRet;

    > > BEGIN

    > > RESULT := TRUE; // Be optimistic

    > > IF Succeeded(Folder.GetDisplayNameOf(ItemIDList, Flags, StrRet))

    > > THEN BEGIN

    > > CASE StrRet.uType OF

    > > STRRET_WSTR: WideCharToMultiByte(CP_ACP, 0, StrRet.pOleStr,

    > > -1, Name, MaxNameLength,

    > > NIL, NIL);

    > >

    > > STRRET_OFFSET:

    > > BEGIN

    > > p := pCHAR(ItemIDlist);

    > > INC(p, StrRet.uOffset);

    > > StrLCopy(Name, p, MaxNameLength)

    > > END;

    > >

    > > STRRET_CSTR: StrLCopy(Name, StrRet.cStr, MaxNameLength)

    > >

    > > ELSE

    > > RESULT := FALSE

    > > END

    > > END

    > > ELSE RESULT := FALSE

    > > END {GetItemIDName};

    > >

    > >

    > > // See GetPrintersPidl in Printers.CPP (line 406)

    > > FUNCTION TForm1.GetPrinterItemIDList(CONST DeskTopFolder: IShellFolder): pItemIDlist;

    > > VAR

    > > hOK : hResult;

    > > PrinterItemIDList: pItemIDList;

    > > BEGIN

    > > IF DeskTopFolder = NIL

    > > THEN RESULT := NIL

    > > ELSE BEGIN

    > > hOK := SHGetSpecialFolderLocation(0,

    > > CSIDL_PRINTERS, // Virtual folder of installed printers

    > > PrinterItemIDList);

    > > IF Failed(hOK)

    > > THEN RESULT := NIL

    > > ELSE RESULT := PrinterItemIDList

    > > END

    > > END {GetPrinterItemIDList};

    > >

    > >

    > > // See GetThisPrinter in Printers.CPP (line 485)

    > > FUNCTION TForm1.GetThisPrinter(CONST PrinterName: STRING;

    > > CONST Allocator: IMalloc): pItemIDlist;

    > > VAR

    > > Continue : BOOLEAN;

    > > DeskTopFolder : IShellFolder;

    > > EnumIDList : IEnumIDList;

    > > hOK : hResult;

    > > PrinterItemIDList: pItemIDList;

    > > PrintersFolder : IShellFolder;

    > > Retrieved : INTEGER;

    > > TargetItemIDList : pItemIDList;

    > > TempItemIDList : pItemIDList;

    > > TempString : ARRAY[0..255] OF CHAR;

    > > BEGIN

    > > TargetItemIDList := NIL;

    > >

    > > IF Allocator <> NIL

    > > THEN BEGIN

    > >

    > > IF Succeeded(SHGetDesktopFolder(DeskTopFolder))

    > > THEN BEGIN

    > >

    > > PrinterItemIDList := GetPrinterItemIDList(DeskTopFolder);

    > > IF PrinterItemIDList <> NIL

    > > THEN BEGIN

    > >

    > > // Get the IShellFolder for Printers

    > > hOK := DeskTopFolder.BindToObject(PrinterItemIDList,

    > > NIL,

    > > IID_IShellFolder,

    > > Pointer(PrintersFolder));

    > > IF Succeeded(hOK)

    > > THEN BEGIN

    > > IF Succeeded(PrintersFolder.EnumObjects(0, SHCONTF_FOLDERS OR SHCONTF_NONFOLDERS,

    > > EnumIDList))

    > > THEN BEGIN

    > > continue := TRUE;

    > > WHILE continue

    > > DO BEGIN

    > > hOK := EnumIDList.Next(1, TempItemIDList, Retrieved);

    > >

    > > // Check its name

    > > GetItemIDName(PrintersFolder, TempItemIDList, SHGDN_NORMAL,

    > > @TempString, SizeOf(TempString));

    > > continue := Succeeded(hOK) AND (Retrieved > 0) AND

    > > (StrIComp(TempString, pChar(PrinterName)) <> 0);

    > > END;

    > >

    > > IF (Retrieved > 0) AND Succeeded(hOK)

    > > THEN TargetItemIDList := ItemIDListsConcatenate(Allocator,

    > > PrinterItemIDList,

    > > TempItemIDList);

    > >

    > > END

    > >

    > > END

    > > END

    > > END

    > > END;

    > >

    > > RESULT := TargetItemIDList;

    > > END {GetThisPrinter};

    > >

    > >

    > > // See Pidl_Create in Printers.CPP (line 689)

    > > // Returns a pointer to the new ItemIDList, or NIL if a problem occurred.

    > > FUNCTION TForm1.ItemIDListCreate(CONST Allocator: IMalloc; CONST size: INTEGER): pItemIDList;

    > > VAR

    > > NewItemIDList: pItemIDList;

    > > BEGIN

    > > NewItemIDList := Allocator.Alloc(size);

    > >

    > > IF NewItemIDList <> NIL

    > > THEN ZeroMemory(NewItemIDList, size);

    > >

    > > RESULT := NewItemIDList

    > > END {ItemIDListCreate};

    > >

    > > // See Pidl_GetNextItem in Printers.CPP (line 710)

    > > // Returns a pointer to the next item in the ItemIDList (Microsoft's Pidl_GetNextItem)

    > > FUNCTION TForm1.ItemIDListGetNextItem(CONST ItemIDList: pItemIDList): pItemIDList;

    > > BEGIN

    > > IF ItemIDlist = NIL

    > > THEN RESULT := NIL

    > > ELSE RESULT := Pointer(INTEGER(ItemIDList) + ItemIDList.mkid.cb)

    > > END {ItemIDListGetNextItem};

    > >

    > >

    > > // See Pidl_GetSize in Printers.CPP (line 655)

    > > // Returns total number of bytes in an ItemIDList (Microsoft's Pidl_GetSize)

    > > FUNCTION TForm1.ItemIDListGetSize(CONST ItemIDList: pItemIDList): INTEGER; {size in bytes}

    > > VAR

    > > TempItemIDList: pItemIDList;

    > > BEGIN

    > > RESULT := 0;

    > > TempItemIDList := ItemIDList;

    > >

    > > IF TempItemIDList <> NIL

    > > THEN BEGIN

    > > WHILE (TempItemIDList.mkid.cb > 0) DO

    > > BEGIN

    > > INC(RESULT, TempItemIDList.mkid.cb);

    > > TempItemIDList := ItemIDListGetNextItem(TempItemIDList)

    > > END;

    > >

    > > // Requires a 16 bit zero value for the null terminator

    > > INC(RESULT, 2*SizeOf(BYTE))

    > > END

    > > END {ItemIDListGetSize};

    > >

    > >

    > > // See Pidl_Concatenate in Printers.CPP (line 612)

    > > // Creates a new ItemIDList with List1 appended to List2

    > > FUNCTION TForm1.ItemIDListsConcatenate(CONST Allocator: IMalloc;

    > > CONST List1, List2: pItemIDList): pItemIDlist;

    > > VAR

    > > List1Length : INTEGER;

    > > List2Length : INTEGER;

    > > NewItemIDList: pItemIDList;

    > > BEGIN

    > > List1Length := 0;

    > > // List1 can possibly be NIL if it points to the desktop. Since we only

    > > // need a sngle NIL terminator, we remove the extra 2 bytes from the size

    > > // of the first ItemIDList

    > > IF List1 <> NIL

    > > THEN List1Length := ItemIDListGetSize(List1) - 2*SizeOf(BYTE);

    > >

    > > List2Length := ItemIDListGetSize(List2);

    > >

    > > // Create a new ItemIDList that is the size of List1 and List2, then

    > > // copy List1 and List2 to the new list.

    > >

    > > NewItemIDList := ItemIDListCreate(Allocator, List1Length + List2Length);

    > >

    > > IF NewItemIDList <> NIL

    > > THEN BEGIN

    > > IF List1 <> NIL

    > > THEN CopyMemory(NewItemIDList, List1, List1Length);

    > >

    > > CopyMemory(Pointer(INTEGER(NewItemIDList) + List1Length),

    > > List2, List2Length)

    > > END;

    > >

    > > RESULT := NewItemIDList

    > > END {ItemIDListsConcatenate};

    > >

    > >

    > > // See OpenThisPrinter in Printers.CPP (line 233)

    > > FUNCTION TForm1.OpenThisPrinter(CONST PrinterName: STRING): BOOLEAN;

    > > VAR

    > > Allocator : IMalloc;

    > > PrinterItemIDList: pItemIDList;

    > > ShellExecuteInfo : TShellExecuteInfo;

    > > BEGIN

    > > RESULT := FALSE;

    > >

    > > IF CoGetMalloc(MEMCTX_TASK, Allocator) = S_OK

    > > THEN BEGIN

    > >

    > > PrinterItemIDList := GetThisPrinter(PrinterName, Allocator);

    > > TRY

    > > IF PrinterItemIDList = NIL

    > > THEN RESULT := FALSE

    > > ELSE BEGIN

    > > ZeroMemory(@ShellExecuteInfo, SizeOf(TShellExecuteInfo));

    > >

    > > WITH ShellExecuteInfo DO

    > > BEGIN

    > > cbSize := SizeOf(TShellExecuteInfo);

    > > fMask := SEE_MASK_INVOKEIDLIST OR SEE_MASK_FLAG_NO_UI;

    > > lpIDList := PrinterItemIDlist;

    > > nShow := SW_SHOWDEFAULT

    > > END;

    > >

    > > ShellExecuteEx(@ShellExecuteInfo);

    > > RESULT := TRUE

    > > END

    > > FINALLY

    > > Allocator.Free(PrinterItemIDList)

    > > END

    > > END

    > > END {OpenThisPrinter};

    > >

    > >

    > > // See OpenPrinterProperties in Printers.CPP (line 41)

    > > FUNCTION TForm1.OpenPrinterProperties(CONST PrinterName: STRING): BOOLEAN;

    > > VAR

    > > Allocator : IMalloc;

    > > PrinterItemIDList: pItemIDList;

    > > ShellExecuteInfo : TShellExecuteInfo;

    > > BEGIN

    > > RESULT := FALSE;

    > > IF CoGetMalloc(MEMCTX_TASK, Allocator) = S_OK

    > > THEN BEGIN

    > > PrinterItemIDList := GetThisPrinter(PrinterName, Allocator);

    > > TRY

    > > IF PrinterItemIDList = NIL

    > > THEN RESULT := FALSE

    > > ELSE BEGIN

    > > ZeroMemory(@ShellExecuteInfo, SizeOf(TShellExecuteInfo));

    > >

    > > WITH ShellExecuteInfo DO

    > > BEGIN

    > > fMask := SEE_MASK_INVOKEIDLIST OR SEE_MASK_FLAG_NO_UI OR SEE_MASK_NOCLOSEPROCESS;

    > > lpIDList := PrinterItemIDlist;

    > > lpVerb := 'Properties';

    > > nShow := SW_SHOWDEFAULT;

    > > cbSize := SizeOf(TShellExecuteInfo);

    > >

    > > END; //*******문제부분1

    > > ShellExecuteEx(@ShellExecuteInfo); <= 1

    > > showmessage('하하하하'); <= 1을 실행하고 확인이나취소를 했을때 실행

    > > RESULT := TRUE

    > > END

    > > FINALLY

    > > Allocator.Free(PrinterItemIDList);

    > >

    > > END;

    > > END;

    > > END; {OpenPrinterProperties}

    > >

    > > end.

    > >

    답변해주셔서 감사합니다.

    그런데 제가 올린소스에 응용해보니 잘되지 않는 군요

    저의 실력이 부족한것 같습니다....

    자세한 설명을 부탁드립니다..