Link to home
Start Free TrialLog in
Avatar of wym
wym

asked on

C Notes API Add In Menu getting UID listing

I have a notes add-in menu for the Actions menu written in C using the Notes API.

I would like to be able to get a UID listing of all the notes I selected.  Unfortunately, I'm only able to get the NOTEID listing through the VIEWIXDATA structure.   Afterwards, I can call IDScan to get each individual NOTEID.  How can I do the same with UID?  

VIEWIXDATA *ViewData
DWORD    notes_scanned;  /* used in procedure IDScan() */
NOTEID   note_id;        /* gets NOTEIDs stored in ID table */

hSelectedList = ViewData->hSelectedList;
if (hSelectedList == NULLHANDLE)
    return (NOERROR);
while(IDScan(hSelectedList, (FLAG)(notes_scanned++==0L), &note_id))
{
//Save note_id here.
}

If I cannot get a UID listing through the viewixdata structure, is there someway I can work backwards given the servername, database, noteid to get the uid?
Avatar of qwaletee
qwaletee

Actually, this is the normal way Notes does things.  The noteID is an almost direct pointer to the note in the local copy of the database (it is an offset into an RRV of all notes in the DB).

The UID, or UNID, or UniversalID, or UNIVERSALNOTEID, or @DocumentUniqueID, is a 32-hex-digit key that identifies the note across all copies of the database, but it provides no way to retrieve the note itself.  Instead, you have to make a function call which looks up the UNID in a UNID-to-noteID index that is maintained in the database.  (Part of what fixup does is to check the integrity of this table, and rebuild it f necessary.)

So, almost all C API functions that latch onto documents or hold document lists, will use noteID.  There is a very good reason for this.  Since it is an RRV offset, a note list can be stored as a run length increment list, i.e., a list of starting note IDs and a mtaching list of how many sequential notes in the list there starting from that ID. A universal ID list would require storage of all the UNIDs in the list, individualy.

If you have the R5 C API reference localy installed, open this URL in teh Notes client: Notes:///85256A24005CC96E/852561BD0045E8E785255B3C005A57BB/85255D56004D3F6385255D28007A719B

It shows exactly how to use a VIEWIXDATA structure to retrieve all the notes in the list.

VIEWIXDATA *ViewData,
char    *szStaticText,
char    *szItemName1,
char    *szItemName2)
STATUS   error = NOERROR;
HANDLE   hSelectedList; /* handle to ID table of Selected notes */
DBHANDLE DbHandle;
DWORD    notes_scanned;  /* used in procedure IDScan() */
NOTEID   note_id;        /* gets NOTEIDs stored in ID table */
   
       
hSelectedList = ViewData->hSelectedList;
if (hSelectedList == NULLHANDLE)
    return (NOERROR);

DbHandle = ViewData->hNoteFile;
if (DbHandle == NULLHANDLE)
    return (NOERROR);

while(IDScan(hSelectedList, (FLAG)(notes_scanned++==0L), &note_id))
{
    if (error = ReadNote(DbHandle, note_id,
                            szStaticText,
                            szItemName1,
                            szItemName2))
    {
        return(error);
    }
}


The example assumes you are using VIEWIXDATA in an export routine, but it is essentially the same for your add-in.

To get the UNID, you must first get the note using the noteID, using the ReadNotes call.  then, use NSFGetNoteInfo against the note handle to retrieve the _NOTE_OID header member.  the OID contains the UNID.  See Notes:///85256A24005CC96E/852561BD0045E8E785255B3C005A57BB/85255D56004D3F6385255D28007A719B for a description of the OID.
ASKER CERTIFIED SOLUTION
Avatar of qwaletee
qwaletee

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 wym

ASKER

Great, I'm almost there but I'm having slight problems.  I get the first two members of OID and put them into a UNID like this:

NSFDbGetNoteInfo (hNoteFile, note_id, &main_oid, &lastmod_td, &note_class);
uid.File = main_oid.File;
uid.Note = main_oid.Note;

All I'm trying to do afterwards is sprintf them into a string but I'm only getting bits and pieces of the actual 32 bit Hex identifier.

char str_note_id[33];
sprintf(str_note_id, "%X%X", uid.Note, uid.File);
MessageBox(NULL, str_note_id, "", 0);

I only get  8 bit segments which are not in sequence and not padded with 0s.

Actual UNID:

0522CAF2DDB5B25F85256D91005DF663

My results:

5DF66385256D91

Unfortunately, I don't know how to trace through the dll because it's a notes add-in dll and I must resort to MessageBoxes...  How do I get the whole 32 bit UNID?


Avatar of wym

ASKER

Got it.  Found that there's an Innards field.

sprintf(str_note_id, "%8.8X%8.8X%8.8X%8.8X", uid.File.Innards[1], uid.File.Innards[0],  uid.Note.Innards[1], uid.Note.Innards[0]);
What you are really getting, I think, is 005DF66385256D91, which is two DWORDS:

005DF663 - 85256D91

You will note that these are the last eight and next to last eight hex characters of the UNID.  The reason you ost the zeroes is because they were at the start of the sprintf parameter, and sprintf drops leading zeroes.
Just wondering, why are you doing all this?
And why the grade B?