[comp.sys.mac.programmer] Telling Finder to Open a Folder

thompson@uxf.cso.uiuc.edu (09/07/89)

I've been wanting to find a way to implement virtual folders from Finder for
 a while now, and believe I could do it, except: is there any way for
 a program to tell Finder to open a specific folder?  I need the program
 to exit to Finder and tell it to open a specific folder on the desktop,
 on top of any existing windows (just as if someone double-clicked on it).

Unfortunately, I can't for the life of me figure out how this could be done.
 Any suggestions?

- Mark Thompson                       "The University Neither Knows Nor
"The less I seek my source for some     Cares What I Am Saying -- Lucky
 definitive, closer I am to fine."      Them."
  University of Illinois at U-C
  INTERNET: thompson@uxf.cso.uiuc.edu
  USMAILNET: 202 E Springfield #3B, Champaign IL 61820

dwright@jarthur.Claremont.EDU (Dr. Banana) (10/08/89)

In article <1234600024@uxf.cso.uiuc.edu> thompson@uxf.cso.uiuc.edu writes:
>
>I've been wanting to find a way to implement virtual folders from Finder for
> a while now, and believe I could do it, except: is there any way for
> a program to tell Finder to open a specific folder?  I need the program
> to exit to Finder and tell it to open a specific folder on the desktop,
> on top of any existing windows (just as if someone double-clicked on it).

The code that follows (Pascal) should do the trick... The routine
uses/modifies undocumented Finder file information;  it should be compatible
with future versions of the system software...

******************

function OpenFolder ( path : str255 ) : OSErr;

VAR
  VInfo : HParamBlockRec;
  Info  : CInfoPBRec;
  volName : str255;
  err   : OSErr;
  next, target : longInt;
  i     : integer;

   function ScanChain (stopAt: longint; VAR next : longint) : boolean;
    VAR
      	Info : CInfoPBRec;
    Begin
	info.ioCompletion := nil;
	info.ioVRefNum := 0;
	info.ioFDirIndex := 0;
	while (next <> 0) and (next <> StopAt) do
	 begin
	  info.ioDrDirID := next;
	  info.ioNamePtr := nil;
	  err := PBGetCatInfo (@info, false);
	  if err <> noErr then 
	    begin
		OpenFolder := err;
		exit(OpenFolder)
	    end;	
	  if info.ioDrFndrInfo.frOpenChain = 0 then leave;
	  next := info.ioDrFndrInfo.frOpenChain;
	 end;
	if next = stopAt then
	  scanChain := true	{ Target folder was in list }
	else
	  scanChain := false;
    end;

begin  {Body of procedure OpenFolder}
  with info do begin
    ioCompletion := nil;
    ioVRefNum := 0;
    ioNamePtr := @path;
    ioFDirIndex := 0;
    ioDrDirID := 0;
  end;
  err := PBGetCatInfo (@info,false)  {Get folder info}
  if err <> noErr then
    begin
	openFolder := err;
	exit (openFolder);
    end;

  volName := copy (path, 1, pos (':', path)-1 );
  with vInfo do begin
	ioCompletion := nil;
	ioVRefNum := 0;
	ioNamePtr := @volName;
	ioVolIndex := 0;
  end;
  err := PBHGetVInfo (@vInfo,false);	{Get volume info}
  if err <> noErr then
    begin
	openFolder := err;
	exit (openFolder)
    end;

  next := vInfo.ioVFndrInfo[3];	{This points to 1st open folder}
  target := info.ioDrDirID;	{This points to target folder}
  if next <> 0 then
    begin
      if not ScanChain (target, next) then
 { If folder isn't already open, open it }
       begin
	info.ioNamePtr := @path;
	info.ioDrDirID := 0;
	info.ioDrFndrInfo.frOpenChain := 0;
	err := PBSetCatInfo (@info, false);	{Update folder info}
	if err <> noErr then
	  {...same as above...}

{ Get info for top folder: }
	info.ioNamePtr := nil;
	info.ioDrDirID := next;
	err := PBGetCatInfo (@info, false);
	if err <> noErr then ....

{ Point link at the target folder: }
	info.ioDrFndrInfo.frOpenChain := target;
	info.ioNameptr := nil;
	info.ioDrDirID := next;
	err := PBSetCatInfo (@info, false);
       end
     end
   else { Special case -- no folders are open }
     begin
	with vInfo do begin
	  ioVFndrInfo[3] := target;
	  ioVRefNum := 0;
	  ioNamePtr := @volName;
	  ioVolIndex := 0;
	end;
	err := PBSetVInfo (@vInfo,false);
	if err <> noErr then ....

	info.ioNamePtr := @path;
	info.ioVRefNum := 0;
	err := PBSetCatInfo (@info,false);
     end;
  OpenFolder := err;
end;	{OpenFolder}

*****************

Note that OpenFolder requires the FULL PATHNAME of the folder you wish to
open!
	Hope this helps....
			- Dan "("
-- 
   Dan Wright, Harvey Mudd College, CA:  dwright@jarthur.claremont.edu
  Opinions expressed are not those of HMC, its students, or even myself --
  Chalk 'em up to one 'ell of a nasty computer virus...

han@Apple.COM (Byron Han) (10/10/89)

In article <2347@jarthur.Claremont.EDU> dwright@jarthur.UUCP (Dr. Banana) writes
><deleted> The routine
>uses/modifies undocumented Finder file information;  it should be compatible
>with future versions of the system software...
>
WARNING - "using undocumented features" == "incompatible"

This has been reiterated _so many times_ by Apple in technical notes
and books.  Use undocumented features AT YOUR OWN RISK.  You WILL break.
-- 
+-----------------------------------------------------------------------------+
| Disclaimer: Apple has no connection with my postings.                       |
+-----------------------------------------------------------------------------+ 
Byron Han, CommToolbox Scapegoat      "How about *S-2 Overextended Edition?"
Apple Computer, Inc.                  -----------------------------------------
20525 Mariani Ave, MS27Y              Internet: han@apple.COM
Cupertino, CA 95014                   UUCP:{sun,voder,nsc,decwrl}!apple!han
------------------------------------  GENIE:BYRONHAN   CompuServe:72167,1664
ATTnet: 408-974-6450                  Applelink:HAN1   HAN1@applelink.apple.COM
-------------------------------------------------------------------------------