Solved

Start printer spool manager?

Posted on 1999-01-08
9
377 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
  • 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
Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

 
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 50 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: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering 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

Suggested Solutions

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
Microsoft Active Directory, the widely used IT infrastructure, is known for its high risk of credential theft. The best way to test your Active Directory’s vulnerabilities to pass-the-ticket, pass-the-hash, privilege escalation, and malware attacks …
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

830 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