Excellent idea. The scheme you presented looks real good. I would
like to suggest some changes. Instead of using a feature, I would
prefer to use the clipboard. It seems more natural (coming from a
Windows world) to me. Above all the publishing app can just set the
clipboard and release the memory. The memory management for the data
then passes on to the clipboard. The publishing app could have a
"Copy Link", or a "Copy record" menu. Similarly the receiving app
could have a "Paste link" and "Paste record" menu. This also avoids
a pickup lists for links. Off course you can paste only one at a time.
Your scheme for launching the app to show the linked record seems OK
to me. However I could not figure out, from the creator ID alone, how
to get the Local ID and Card number of the linked app. Many apps and
their databases share the same Creator id. Accordingly I have
modified the link structure and the routines.
It would be nice if the source app can notify all other apps, that
there is a link in the clipboard. In response possible recipient apps
can enable their "Paste link" menu. Couldn't find a simple way to do
it. Probably have to use SysBroadcastActionCode with a custom launch
code. Doesn't sound like the "Palm Zen" thing ;).
************ WARNING: Untested code ahead ***************
typdef struct {
CharPtr Header; //identifies a link info
DWord LinkCreator; //identifies the source app
UInt CardNo;
LocalID DBID;
ULong UniqueID;
ULong ExtraInfoSize; //allows safe navigation
BYTE ExtraInfo[1]; //actually more than 1
} LinkStructure;
typdef struct {
CharPtr Header; //identifies a link info
DWord LinkCreator; //identifies the source app
UInt CardNo;
LocalID DBID;
ULong RecordSize;
ULong ExtraInfoSize;
BYTE Data[1]; //actually more than 1
} PasteStructure;
//to distinguish a link info from other data
#define LINK_START "LinkStart"
#define LINK_END "LinkEnd"
#define THIS_LINK_CREATOR 'ZZZZZ' //or whatever else
Boolean CopyRecordToClipboard(VoidPtr RecordP, ULong
ReccordSize, VoidPtr ExtraInfoP = NULL, ULong ExtraInfoSize =0 )
{
Err lReturn;
PasteStructure *uPasteP;
VoidPtr DataP = NULL;
ULong DataSize =sizeof(PasteStructure) + RecordSize + ExtraInfoSize;
VoidHand DataH = MemHandleNew(DataSize);
if (DataH)
DataP = MemHandleLock(DataH);
if (Datap)
{
uPasteP = (PasteStructure *) DataP;
uPasteP->Header= LINK_START;
uPasteP->LinkCreator = THIS_LINK_CREATOR;
MemMove( (VoidPtr) uPasteP->Data, RecordP, RecordSize);
MemMove( (VoidPtr) uPasteP->(Data + RecordSize), ExtraInfoP,
ExtraInfoSize);
lReturn = SysCurAppDatabase( &(uPasteP->CardNo), &(uPasteP-
>DBID));
if (0 == lReturn)
{
lReturn = ClipboardAddItem(clipboardText, DataP, DataSize);
}
}
if (DataP)
MemHandleUnlock(DataH);
if (DataH)
MemHandleFree(DataH);
return (0 == lReturn);
}
Boolean CopyLinkToClipboard(ULong UniqueID, VoidPtr ExtraInfoP =
NULL,
ULong ExtraInfoSize = 0)
{
Err lReturn;
LinkStructure *uLinkP;
VoidPtr DataP = NULL;
ULong DataSize = sizeof(LinkStructure) + ExtraInfoSize;
VoidHand DataH = MemHandleNew(DataSize);
if (DataH)
DataP = MemHandleLock(DataH);
if (Datap)
{
uLinkP = (LinkStructure *) DataP;
uLinkP->Header= LINK_START;
uLinkP->LinkCreator = THIS_LINK_CREATOR;
MemMove( (VoidPtr) uLinkP->Data, ExtraInfoP, ExtraInfoSize);
lReturn = SysCurAppDatabase( &(uLink.CardNo), &(uLink.DBID));
if (0 == lReturn)
{
uLinkP->UniqueID = UniqueID;
lReturn = ClipboardAddItem(clipboardText, DataP, DataSize);
}
}
if (DataP)
MemHandleUnlock(DataH);
if (DataH)
MemHandleFree(DataH);
return (0 == lReturn);
}
In the app receiving the link:
//The handle DataHP is to be freed by the caller
Boolean GetLinkFromClipboard(LinkStructure **uLinkP, VoiHand *DataHP)
{
Err lReturn = 1;
VoidHand ClipDataH = 0, DataH = 0 ;
VoidPtr ClipDataP = NULL, DataP = NULL;
Word DataLength;
*uLinkP = NULL;
*DataHP= 0;
ClipDataH = ClipboardGetItem(clipboardText, &DataLength);
if (ClipDataH)
ClipDataP = MemHandleLock(ClipDataH);
if(ClipDataP)
{
LinkStructure *Ptr = (LinkStructure *) ClipDataP;
if ( 0 != StrCompare(Ptr->LinkHeader, LINK_START))
{
return 0;
}
}
if (DataLength >0)
DataH = MemHandleNew(DataLength);
if (DataH)
DataP = MemHandleLock(DataH);
if (DataP)
{
MemMove(DataP, ClipDataP, DataLength);
*uLinkP = (LinkStructure *) DataP;
*DataHP = DataH;
lReturn = MemHandleUnlock(ClipDataH);
//clipboard frees it's own handle
}
return (0 == lReturn);
}
The GetRecordFromClipboard routine shall be identical. The app can
save the record data in its own DB. For editing, it shall pass the
record data to the creator app, while launching the app.
This is just an idea, improvements are most welcome.
Cheers!
-Sugho-
>Date: 13 Apr 1999 23:19:32 -0700
>From: "C. E. Steuart Dewar" <[EMAIL PROTECTED]>
>Subject: Universal Linking Mechanism
>A proposal for all palm developers... It would be very useful to
>havesome
>kind of published, universal mechanism that would link records
>together from
>various applications. I have been thinking about this for Datebk3 >-
someone
>wants to put a drawing in associated with an appointment, for
>example.How
>could I implement this?
>..............
______________________________________________________
Get Your Private, Free Email at http://www.hotmail.com