Link to home
Start Free TrialLog in
Avatar of dhirsch
dhirsch

asked on

Getting the File List's ListHandle from within CustomGetFile

If I'm in my Dialog hook function, called by CustomGetFile, how can I get the ListHandle for the File list that the Toolbox makes?  I need to be able to see & change which items are selected.
Avatar of Paul B
Paul B

Hi,
  Are you apposed to using a patch :/
If you are not I can give you an answer and code example.

Paul B
Avatar of dhirsch

ASKER

Paul-
  A patch is fine.  I know there's no easy way to get at it, because I've tried all the easy ways.
-Dave
ASKER CERTIFIED SOLUTION
Avatar of Paul B
Paul B

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of dhirsch

ASKER

This looks like what I needed.  I'll email you to discuss PPC implementation, which, sadly, I do need.
Hi,
Here is how it is done for PPC with Sample Code.

First the patch should be compiled with 68K and to generate a code resource of type 'patc' with id 0.
Add this resource to your PPC target.

Then main code then calls the patc resource using the Mixed Mode Mgr.

Here is the patch code:
/* File patch.c */
#include <Traps.h>
#include <Gestalt.h>
#include <A4Stuff.h>

#include "patch.h"

asm void LNewPatch(void);
static void PatchLNew(void);
static void UnPatchLNew(void);

static void InstallGlobals(void);
pascal void main(short remove, ListHandle* listaddres);

#if !GENERATINGPOWERPC
typedef pascal ListRef (*LNewProcPtr) (
      const Rect *rView,
      const ListBounds *dataBounds,
      Point cSize,
      short theProc,
      WindowRef theWindow,
      Boolean drawIt,
      Boolean hasGrow,
      Boolean scrollHoriz,
      Boolean scrollVert);

typedef  LNewProcPtr LNewUPP;

enum {
      uppLNewProcInfo = 0
};

#define NewLNewProc(proc) (LNewUPP)(proc)
#define CallLNewProc(proc, p1, p2, p3, p4, p5, p6, p7, p8, p9)      \
            (* (LNewProcPtr) (proc))(p1, p2, p3, p4, p5, p6, p7, p8, p9)

#else
      #error      only for 68K
#endif

LNewUPP gOldLNew=0;
ListHandle *gMyListHandlePtr = nil;


pascal void main(short remove, ListHandle* listaddres)
{
      long oldA4;
      Boolean installfailed;

      oldA4 = SetCurrentA4();

      if (remove) {
            UnPatchLNew();
      }
      else {
            gMyListHandlePtr = listaddres;
            PatchLNew();
            InstallGlobals();      // must be after patch installed!
      }
      SetA4(oldA4);
}

static void PatchLNew(void)
{
      short trap = _Pack0;
      
      gOldLNew = (LNewUPP)
                  NGetTrapAddress(trap, (trap & 0x0800) ? ToolTrap : OSTrap);

      NSetTrapAddress((UniversalProcPtr) LNewPatch,
                  trap, (trap & 0x0800) ? ToolTrap : OSTrap);

}

static void UnPatchLNew(void)
{
      short trap = _Pack0;

      NSetTrapAddress((UniversalProcPtr) gOldLNew,
                  trap, (trap & 0x0800) ? ToolTrap : OSTrap);
      
}



asm void LNewPatch(void)
{
                        bra.s      start

                        entry      static InstallGlobals
InstallGlobals:
                        lea            lstHandAddr, a0
                        move.l      gMyListHandlePtr, (a0)
                        lea            oldAddress, a0
                        move.l      gOldLNew, (a0)
                        rts

lstHandAddr:      dc.l      0
oldAddress:            dc.l      0
oldreturn:            dc.l      0

start:
                        cmpi.w      #68, 4(sp)            // LNew selector
                        beq            DoLNew

                        move.l      oldAddress,a0
                        jmp            (a0)                  // jump to old code

DoLNew:
                        lea            oldreturn,a0      // save return address
                        move.l      (sp),(a0)            

                        lea       Continue, a0      // where we want to return to
                        move.l      a0, (sp)            // put on stack

                        move.l      oldAddress,a0
                        jmp            (a0)                  // jump to old code

Continue:
                        move.l      lstHandAddr,a0
                        move.l      (sp),(a0)

                        move.l      oldreturn,a0      // get the old return address
                        jmp            (a0)                  // jump!!!
}

/* File patch.h */
enum {
      kInstall = 0,
      kRemove = 1
};

Here is the main for PPC
/* File main.c */

#include <StandardFile.h>
#include "patch.h"

void main(void);
void inittoolbox(void);

ListHandle gMyListHandle = nil;
long lasttime = 0;

pascal Boolean HookProc(short itemHit, DialogPtr theDialog, void* data);

enum {
      uppPatchProcInfo = kPascalStackBased
             | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(short)))
             | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(ListHandle*)))
};
      
void main(void)
{
      UniversalProcPtr patchCode;
      DlgHookYDUPP dlgHook;
      Handle patchResource;
      StandardFileReply reply;
      long responce;
      OSErr err = noErr;
      Point where;

      inittoolbox();

      patchResource = GetResource('patc', 0);
      if (patchResource) {
            HLock(patchResource);
            HNoPurge(patchResource);
            patchCode = NewRoutineDescriptor((ProcPtr)*patchResource, uppPatchProcInfo,  kM68kISA);
            CallUniversalProc(patchCode, uppPatchProcInfo, kInstall, &gMyListHandle);

            where.h = where.v = -1;

            dlgHook =  NewDlgHookYDProc(HookProc);

            gMyListHandle = nil;
            CustomGetFile(nil, -1, nil, &reply, 0, where, dlgHook, nil, nil, nil, nil);
            gMyListHandle = nil;

            CallUniversalProc(patchCode, uppPatchProcInfo, kRemove, &gMyListHandle);
            DisposeRoutineDescriptor(patchCode);
            
      }
      else {
            SysBeep(1);
      }
}

pascal Boolean HookProc(short itemHit, DialogPtr theDialog, void* data)
{
      Cell thecell, nextcell;
      Boolean result;

      if (gMyListHandle) {
            if (TickCount() - lasttime > 30) {
                  if ((itemHit == 100)) {
                        thecell.h = thecell.v = 0;
                        result = LGetSelect(true, &thecell, gMyListHandle);
                        if (result) {
                              nextcell = thecell;
                              result = LNextCell(false, true, &nextcell, gMyListHandle);
                              LSetSelect(false, thecell, gMyListHandle);
                              LSetSelect(true, nextcell, gMyListHandle);
                        }
                        else {
                              LSetSelect(false, thecell, gMyListHandle);
                              thecell.h = thecell.v = 0;
                              LSetSelect(true, thecell, gMyListHandle);
                        }
                        LAutoScroll(gMyListHandle);
                  }
                  lasttime = TickCount();
            }
      }
      if ((itemHit == ok) || (itemHit == cancel))
            return true;
      return false;
}

void inittoolbox(void)
{
      InitGraf(&qd.thePort);
      FlushEvents ( everyEvent, 0);
      InitFonts();
      InitWindows();
      InitMenus();
      TEInit();
      InitDialogs(nil);
      InitCursor();
}