Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Start printer spool manager?

Posted on 1999-01-08
9
Medium Priority
?
383 Views
Last Modified: 2010-04-06
 Create a shortcut for the designate printer. Example: Printer.lnk from A LaserJet Printer. Then, call
  ShellExecute(0, nil, 'Printer.lnk', nil, nil, SW_Show);
We can start the spool manager of this printer.
  How to directly start the manager without creating a shortcut?
0
Comment
Question by:delphi1
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 3
9 Comments
 
LVL 20

Expert Comment

by:Madshi
ID: 1355238
You could use SHGetSpecialFolderLocation(Application.Handle1,CSIDL_PRINTERS,pidl) to get the PItemIDList of the printer folder. Then you could bind this pidl to a IShellFolder interface to enumerate the content of the printer folder. Then you could use ShellExecuteEx to execute the pidl.

However, this is much more complicated then executing a shellLink.
BTW, how do you create this shellLink? With your program or manually with the win95 shell?

Regards, Madshi.
0
 

Author Comment

by:delphi1
ID: 1355239
 I create the shellLink manually. Otherwise, createing  a shortcut by program then execute it is also Ok, but not so good.
  I must start the printer manager, not just explore the printer folder. The printer folder may contain many printers. I like to execute the default printer manager. To get default printer name is easy.
  I know this PAQ http://www.experts-exchange.com/topics/comp/lang/delphi/Q.10114613 discussed on browse printer folder using SHGetSpecialFolderLocation and ShellExecuteEx to explore Windows95 special folder.

Regrads, Yang.
0
 
LVL 20

Expert Comment

by:Madshi
ID: 1355240
Yes, but the other question was about Dialup Network which has its own Guid string (like {xxxxxxx-xxxx-xxxx-xxxx-xxxxxx}). The printers don't have such a Guid string, so the solution we found for the other question won't help you at all.
Perhaps there is an easy solution for your problem. But using GetSpecialFolder and enumerating all printer (to find the printer you're searching) is the only way I know...   :-(

I asked how you create the shellLink, because - again - the only way to create a printer shortLink with a program is to use SHGetSpecialFolderLocation...   :-(

So, as I see it, either you have to live with your currently implemented solution (manually created shellLinks), or you'll have to look at SHGetSpecialFolder and all that stuff. Of course I would help you with that. I've some functions, that would make it easier for you. Hmmm. Which Delphi version are you using?

Regards, Madshi.
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 20

Expert Comment

by:Madshi
ID: 1355241
Yes, but the other question was about Dialup Network which has its own Guid string (like {xxxxxxx-xxxx-xxxx-xxxx-xxxxxx}). The printers don't have such a Guid string, so the solution we found for the other question won't help you at all.
Perhaps there is an easy solution for your problem. But using GetSpecialFolder and enumerating all printer (to find the printer you're searching) is the only way I know...   :-(

I asked how you create the shellLink, because - again - the only way to create a printer shortLink with a program is to use SHGetSpecialFolderLocation...   :-(

So, as I see it, either you have to live with your currently implemented solution (manually created shellLinks), or you'll have to look at SHGetSpecialFolder and all that stuff. Of course I would help you with that. I've some functions, that would make it easier for you. Hmmm. Which Delphi version are you using?

Regards, Madshi.
0
 

Author Comment

by:delphi1
ID: 1355242
I am now using Delphi4, not myself :-(
Can you give me more details, such as the functions what you said? Thank you very much!

Regard, Yang.
0
 
LVL 20

Accepted Solution

by:
Madshi earned 200 total points
ID: 1355243
unit uni1;

interface

uses Windows, ShlObj, ActiveX, ShellAPI, Forms, sysUtils;

implementation

const maxCard = high(cardinal);

function ExecuteContextMenuCommand(sf: IShellFolder; childPidl: PItemIDList; verb: string) : boolean;
var cm   : IContextMenu;
    cm2  : IContextMenu2;
    cm3  : IContextMenu3;
    ici  : TCMInvokeCommandInfo;
    pop1 : HMenu;
    c1   : cardinal;
begin
  result:=false;
  if sf.GetUIObjectOf(Application.handle,1,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:=Application.handle;
    lpVerb:=PChar(verb);
    nShow:=SW_SHOW;
  end;
  if verb='' then begin
    pop1:=CreatePopupMenu;
    try
      if succeeded(cm.QueryContextMenu(pop1,0,1,$7FFF,CMF_DEFAULTONLY)) then begin
        c1:=GetMenuDefaultItem(pop1,0,0);
        if c1<>0 then begin
          ici.lpVerb:=MakeIntResource(c1-1);
          result:=cm.InvokeCommand(ici)=NOERROR;
        end;
      end;
    finally DestroyMenu(pop1) end;
  end else result:=cm.InvokeCommand(ici)=NOERROR;
end;

procedure FreePidl(var pidl: PItemIDList);
var malloc : IMalloc;
begin
  if (pidl<>nil) and (SHGetMalloc(malloc)=NOERROR) then begin
    malloc.Free(pidl);
    pidl:=nil;
  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_NORMAL,sr)<>NOERROR then exit;
  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);
    else            result:='';
  end;
end;

function EnumObjects(sf: IShellFolder) : string; overload;
var el     : IEnumIDList;
    malloc : IMalloc;
    pidl1  : PItemIDList;
    c1     : cardinal;
begin
  result:='';
  if (sf=nil) or (SHGetMalloc(malloc)<>NOERROR) or (sf.EnumObjects(Application.handle,maxCard,el)<>NOERROR) then
    exit;
  el.Reset;
  while el.Next(1,pidl1,c1)=NOERROR do begin
    result:=result+#$D#$A+PidlToStr(sf,pidl1);
    ExecuteContextMenuCommand(sf,pidl1,'');
    malloc.Free(pidl1);
  end;
  Delete(result,1,2);
end;

function EnumObjects(pidl: PItemIDList) : string; overload;
var sf1,sf2 : IShellFolder;
begin
  result:='';
  if (pidl=nil) or (SHGetDesktopFolder(sf1)<>NOERROR) then exit;
  if pidl^.mkid.cb<>0 then begin
    if sf1.BindToObject(pidl,nil,IID_IShellFolder,pointer(sf2))<>NOERROR then exit;
    result:=EnumObjects(sf2);
  end else result:=EnumObjects(sf1);
end;

procedure EnumAllPrinters;
var pidl : PItemIDList;
begin
  if SHGetSpecialFolderLocation(INVALID_HANDLE_VALUE,CSIDL_PRINTERS,pidl)=NOERROR then
    try
      MessageBox(0,pchar(EnumObjects(pidl)),'All printers...',0);
    finally FreePidl(pidl) end;
end;

initialization
  EnumAllPrinters;
end.
0
 
LVL 20

Expert Comment

by:Madshi
ID: 1355244
Hmmm. Looks like I implemented an almost ready to use solution. Just try it out!!! Was a lot of work...  :-(

Regards, Madshi.
0
 

Author Comment

by:delphi1
ID: 1355245
Excellent solution! Thank you very very much.

Regards Young
0
 
LVL 20

Expert Comment

by:Madshi
ID: 1355246
No prob...   :-)
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
This tutorial will teach you the special effect of super speed similar to the fictional character Wally West aka "The Flash" After Shake : http://www.videocopilot.net/presets/after_shake/ All lightning effects with instructions : http://www.mediaf…
Want to learn how to record your desktop screen without having to use an outside camera. Click on this video and learn how to use the cool google extension called "Screencastify"! Step 1: Open a new google tab Step 2: Go to the left hand upper corn…
Suggested Courses

715 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question