首页  编辑  

启动默认打印机管理程序

Tags: /超级猛料/Print.打印/   Date Created:

为默认打印机创建一个快捷方式后,用ShellExecute运行可以启动默认

打印机管理程序。如果不创建快捷方式,如何直接启动。

感谢http://www.experts-exchange.com/Q.10115433, 以下代码ShowPrintSpool可以实现:

function ExecuteContextMenuCommand(hParent: THandle; sf: IShellFolder; childPidl: PItemIDList;

 verb: string = ''; propPage: string = ''; pidlCount: UInt = 1): Boolean;

var

 cm, cm2, cm3: IContextMenu;

 ici: TCMInvokeCommandInfo;

 pop : HMenu;

 c: Cardinal;

begin

 Result := False;

 if sf.GetUIObjectOf(hParent, pidlCount, childPidl, IID_IContextMenu,nil, Pointer(cm)) <> NOERROR then Exit;

 try

   cm2 := cm as IContextMenu2;

   cm := cm2;

   try

     cm3 := cm as IContextMenu3;

     cm := cm3;

   except

   end;

 except

 end;

 ZeroMemory(@ici, sizeOf(ici));

 with ici do

 begin

   cbSize := sizeOf(TCMInvokeCommandInfo);

   fMask := CMIC_MASK_FLAG_NO_UI;

   hWnd := hParent;

   lpVerb := PChar(verb);

   lpParameters := PChar(propPage); //'Settings';

   nShow := SW_SHOW;

 end;

 if verb <> '' then

   Result := cm.InvokeCommand(ici) = NOERROR

 else

 begin

   pop := CreatePopupMenu;

   try

     if Succeeded(cm.QueryContextMenu(pop, 0, 1, $7FFF, CMF_DEFAULTONLY)) then

     begin

       c := GetMenuDefaultItem(pop, 0, 0);

       if c <> 0 then

       begin

         ici.lpVerb := MakeIntResource(c - 1);

         Result := cm.InvokeCommand(ici) = NOERROR;

       end;

     end;

   finally

     DestroyMenu(pop)

   end;

 end

end;

function PidlToStr(sf: IShellFolder; childPidl: PItemIDList): string;

var

 sr: _StrRet;

begin

 Result := '';

 if (sf = nil) or (childPidl = nil) then Exit;

 sr.uType := STRRET_CSTR;

 if sf.GetDisplayNameOf(childPidl,SHGDN_FORPARSING,sr) = NOERROR then

   case sr.uType of

     STRRET_CSTR   : Result := string(sr.cStr);

     STRRET_OFFSET : Result := string(PChar(Cardinal(childPidl) + sr.uOffset));

     STRRET_WSTR   : Result := string(sr.pOleStr);

   end;

end;

function DefaultPrinterDevice: string;

var

 Device, Driver, Port: array [0..255] of Char;

 Mode: THandle;

begin

 Device := '';

 with Printer do

   if Printers.Count > 0 then

     GetPrinter(Device, Driver, Port, Mode);

 Result := Device;

end;

procedure ShowPrintSpool;

var

 pidl1, pidl2: PItemIDList;

 sf1, sf2: IShellFolder;

 malloc: IMalloc;

 el: IEnumIDList;

 c: Cardinal;

 sDefaultPrinter: string;

begin

 if (SHGetSpecialFolderLocation(INVALID_HANDLE_VALUE, CSIDL_PRINTERS, pidl1) = NOERROR) and

   (SHGetMalloc(malloc) = NOERROR) then

   try

     if (pidl1^.mkid.cb <> 0) and (SHGetDesktopFolder(sf1) = NOERROR) and

       (sf1.BindToObject(pidl1, nil, IID_IShellFolder, Pointer(sf2)) = NOERROR) and

       (sf2.EnumObjects(Application.Handle, High(Cardinal), el) = NOERROR) then

     begin

       sDefaultPrinter := DefaultPrinterDevice;

       el.Reset;

       while el.Next(1, pidl2, c) = NOERROR do

       begin

         if PidlToStr(sf2, pidl2) = sDefaultPrinter then

           ExecuteContextMenuCommand(Application.Handle, sf2, pidl2);

         malloc.Free(pidl2);

       end;

     end;

   finally

     malloc.Free(pidl1);

   end;

end;