Solved

Start printer spool manager?

Posted on 1999-01-08
9
370 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
 
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
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 

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

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

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…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…
This tutorial demonstrates a quick way of adding group price to multiple Magento products.

758 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

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now