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.
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
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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((Universal ProcPtr) LNewPatch,
trap, (trap & 0x0800) ? ToolTrap : OSTrap);
}
static void UnPatchLNew(void)
{
short trap = _Pack0;
NSetTrapAddress((Universal ProcPtr) 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(ListHandl e*)))
};
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((Proc Ptr)*patch Resource, uppPatchProcInfo, kM68kISA);
CallUniversalProc(patchCod e, 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(patchCod e, uppPatchProcInfo, kRemove, &gMyListHandle);
DisposeRoutineDescriptor(p atchCode);
}
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();
}
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((Universal
trap, (trap & 0x0800) ? ToolTrap : OSTrap);
}
static void UnPatchLNew(void)
{
short trap = _Pack0;
NSetTrapAddress((Universal
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,
| STACK_ROUTINE_PARAMETER(2,
};
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((Proc
CallUniversalProc(patchCod
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(patchCod
DisposeRoutineDescriptor(p
}
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();
}
Are you apposed to using a patch :/
If you are not I can give you an answer and code example.
Paul B