[comp.sys.mac.programmer] Resource Files

juana@dciem.dciem.dnd.ca (Juana Chang) (03/27/90)

Hi.  Would anyone help me with the following:

I'm trying to write string values from my application's resource file into
my program and then modify them and then write the modified values back to
the resource file.

At the moment I'm using:
GetIndString( string, strListID, index );   to get my string values, which
works .. BUT I'm having difficulty writing my modified string values back
into the resource file without a resource handle to these values.

Am I going about this the wrong way?

Please send me sample code on how to read string values and write string
values to an application's resource file.

Any help would be greatly appreciated!

Thanks.   :-)

 
_________________________________________________________________________
                          Eat any good books lately?
juana@dciem.dciem.dnd.ca
_________________________________________________________________________
-- 
_________________________________________________________________________
                          Eat any good books lately?
juana@dciem.dciem.dnd.ca
_________________________________________________________________________

aries@rhi.hi.is (Reynir Hugason) (03/30/90)

juana@dciem.dciem.dnd.ca (Juana Chang) writes:


>I'm trying to write string values from my application's resource file into
>my program and then modify them and then write the modified values back to
>the resource file.

This should do the trick:

( ------------------------------------------------------------------------ *)
(*	String manipulation unit :-)	 										*)
(*																			*)
(*	Here is a simple unit that handles modifications of STR# resources.		*)
(*																			*)
(*	Enjoy!																	*)
(* ------------------------------------------------------------------------ *)
(* Mimir Reynisson (Aries, inc.)							aries@rhi.hi.is	*)
(* DISCLAIMER: Who me???													*)
(* ------------------------------------------------------------------------ *)

UNIT Strings;

INTERFACE
	USES MemTypes, Resources, Memory, OSUtils, ToolUtils;

	CONST
		kIndexOutofRange = 100;

	{ creation and removal of STR# resources }

	PROCEDURE NewIndStringRes(id: INTEGER; stringName: STR255);
	PROCEDURE RmveIndStringRes(id: INTEGER);

	{ accessing, modifying & deleting STR# entries }

	PROCEDURE NewIndString(str: STR255; id: INTEGER);
	FUNCTION  ReturnIndString(id, index: INTEGER): STR255;
	PROCEDURE SetIndString(str: STR255; id, index: INTEGER);
	PROCEDURE RmveIndString(id, index: INTEGER);

	{ error result of last string operation }

	FUNCTION  GetStrError: INTEGER;

IMPLEMENTATION

	TYPE
		intPtr = ^INTEGER;
		intHdl = ^intPtr;

	VAR
		stringError: INTEGER;

	PROCEDURE NewIndStringRes(id: INTEGER; stringName: STR255);
		VAR
			resHdl: Handle;
		BEGIN
			stringError:=noErr;

			resHdl:=NewHandleClear(SizeOf(INTEGER));
			IF resHdl=NIL THEN
				BEGIN
					stringError:=MemError; EXIT(NewIndStringRes);
				END;

			AddResource(resHdl, 'STR#', id, stringName);	{create it}
			WriteResource(resHdl);							{write it}
			ReleaseResource(resHdl);						{& dispose of it}
		END;

	PROCEDURE RmveIndStringRes(id: INTEGER);
		VAR
			resHdl: Handle;
		BEGIN
			stringError:=noErr;

			resHdl:=GetResource('STR#',id);
			IF ResError=noErr THEN
				BEGIN
					RmveResource(resHdl);
					DisposHandle(resHdl);
					UpdateResFile(CurResFile);
				END;
		END;

	PROCEDURE NewIndString(str: STR255; id: INTEGER);
		VAR
			resHdl: Handle;
			strHdl: StringHandle;
		BEGIN
			stringError:=noErr;

			resHdl:=GetResource('STR#',id);
			IF resHdl=NIL THEN				{if getresource fails - abort}
				BEGIN
					stringError:=ResError; EXIT(NewIndString);
				END;

			HNoPurge(resHdl);						{make it unpurgeable}

			strHdl:=NewString(str);
			IF strHdl=NIL THEN
				BEGIN
					stringError:=MemError; HPurge(resHdl); EXIT(NewIndString);
				END;
			stringError:=HandAndHand(Handle(strHdl),resHdl);	{splice'm}

			DisposHandle(Handle(strHdl));		{& throw temp string away}

			IF stringError<>noErr THEN
				BEGIN
					HPurge(resHdl); EXIT(NewIndString);					
				END;
			intHdl(resHdl)^^:=intHdl(resHdl)^^+1;	{increase string counter}

			ChangedResource(resHdl);							{mark it}
			WriteResource(resHdl);								{write it}

			HPurge(resHdl);										{release it}
		END;

	FUNCTION ReturnIndString(id, index: INTEGER): STR255;
		VAR
			tempStr: STR255;
		BEGIN
			GetIndString(tempStr,id,index); ReturnIndString:=tempStr;
		END;

	PROCEDURE SetIndString(str: STR255; id, index: INTEGER);
		VAR
			resHdl: Handle;
			tempPtr: Ptr;
			i, ignore: INTEGER;
		BEGIN
			stringError:=noErr;

			resHdl:=GetResource('STR#',id);
			IF resHdl=NIL THEN					{if getresource fails - abort}
				BEGIN
					stringError:=ResError; EXIT(SetIndString);
				END;

			IF (intHdl(resHdl)^^ < index) | (index < 1) THEN
				BEGIN
					ReleaseResource(resHdl);
					stringError:=kIndexOutofRange;
					EXIT(SetIndString);
				END;

			HNoPurge(resHdl);							{make it unpurgeable}

			tempPtr:=Ptr(LongInt(@resHdl^^) + SizeOf(INTEGER));

			FOR i:=1 TO index-1 DO
				tempPtr:=Ptr(LongInt(tempPtr) + tempPtr^ + 1);

			{call munger to do string replacement}

			ignore:=Munger(	resHdl,
							LongInt(tempPtr) - LongInt(@resHdl^^),
							NIL,
							tempPtr^+1,
							@str,
							Length(str)+1
						);

			ChangedResource(resHdl);							{mark it}
			WriteResource(resHdl);								{write it}

			HPurge(resHdl);						{make it purgeable again}
		END;

	PROCEDURE RmveIndString(id, index: INTEGER);
		VAR
			resHdl: Handle;
			tempPtr: Ptr;
			i, ignore: INTEGER;
		BEGIN
			stringError:=noErr;

			resHdl:=GetResource('STR#',id);
			IF resHdl=NIL THEN					{if getresource fails - abort}
				BEGIN
					stringError:=ResError; EXIT(RmveIndString);
				END;

			IF (intHdl(resHdl)^^ < index) | (index < 1) THEN
				BEGIN
					ReleaseResource(resHdl);
					stringError:=kIndexOutofRange;
					EXIT(RmveIndString);
				END;

			HNoPurge(resHdl);							{make it unpurgeable}

			tempPtr:=Ptr(LongInt(@resHdl^^) + SizeOf(INTEGER));

			FOR i:=1 TO index-1 DO
				tempPtr:=Ptr(LongInt(tempPtr) + tempPtr^ + 1);

			{call munger to string deletion}

			ignore:=Munger(	resHdl,
							LongInt(tempPtr) - LongInt(@resHdl^^),
							NIL,
							tempPtr^+1,
							Ptr(-1),
							0
						);

			intHdl(resHdl)^^:=intHdl(resHdl)^^-1;	{decrease string counter}

			ChangedResource(resHdl);							{mark it}
			WriteResource(resHdl);								{write it}

			HPurge(resHdl);										{release it}
		END;

	FUNCTION GetStrError: INTEGER;
		BEGIN
			GetStrError:=stringError;
		END;
END.

uad1020@dircon.uucp (08/23/90)

I have been writing a program recently which has been
creating a lot of grief. I am using Think C 4.0 and
its Class Libraries. The program takes a text file and
extracts various sections from it which are assigned into
individual folders. In a folder are a number of files 
which are logically linked and each file has a data and 
resource fork. The data has the actual text that I hook
out and the resource fork has an index to its data fork.
This may well be a bad way of dealing with this situation
but it is not the problem. 

My problem is that when my application has to create a new 
folder (as it always checks before it tries to write to it), 
it has a strange repercussion a little later on. The part
of my application that writes the document back does two
stages ... firstly it creates an instance of CDataFile and 
writes that back to the correct place, and then straight
afterwards it writes its index details back to the resource
file. My problem is that it does this correctly except when
a folder has been created earlier ... instead it creates it
in the folder my application was in when the new folder was 
being created.

Um ... does that make sense? All my folders are in the right 
order and all my data files are in the right place. Are there
any known effects of PBDirCreate which could cause this?

Your help is very much appreciated.

Ian
-- 
/////////////////////////////////////////////////////////////////
// Ian Cottee ----- zobbo@cix.uucp                             //
//                  uad1020@dircon.uucp                        //
/////////////////////////////////////////////////////////////////