Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: IdIMAP41 problem with setup flag to seen



Permlink Replies: 1 - Last Post: Jul 13, 2017 12:25 PM Last Post By: Remy Lebeau (Te... Threads: [ Previous | Next ]
duf _

Posts: 28
Registered: 7/2/06
IdIMAP41 problem with setup flag to seen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jul 13, 2017 11:21 AM
I can not handle setting the message flag to read status. I am using such code and messages are still loaded by the program as unread. Please advise what to do more to notify the mail server that the message is already read and I do not want to reload it, and best to remove it

if ( IdIMAP41->SelectMailBox("INBOX") && IdIMAP41->StatusMailBox("INBOX", IdIMAP41->MailBox) )
			 ile = IdIMAP41->MailBox->UnseenMsgs; //TotalMsgs;
 
  for ( short int j = ile; j > 0; --j )
  {
	if ( !IdIMAP41->GetUID( j, UID ) ) { ShowMessage( L"Błąd odczytu UID wiadomości" ); break; }
 
	IdMessage2->Clear();
	IdIMAP41->UIDRetrieve( StrToInt(UID), IdMessage2 );
	 
	if ( IdIMAP41->UIDRetrieveFlags( StrToInt(UID), Flags ) )
	{
		//if ( Flags.Contains(mfSeen) ) continue;
		IdIMAP41->UIDStoreFlags(UID, sdAddSilent, TIdMessageFlagsSet() << mfSeen);
		if ( Flags.Contains(mfSeen) ) Memo1->Lines->Add(L"Wiadomość odczytana");
	}
 
	IdIMAP41->UIDDeleteMsg(UID);
  }
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: IdIMAP41 problem with setup flag to seen
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jul 13, 2017 12:25 PM   in response to: duf _ in response to: duf _
duf _ wrote:

ile = IdIMAP41->MailBox->UnseenMsgs; //TotalMsgs;

for ( short int j = ile; j > 0; --j )

This loop is just plain wrong.

First off, why are you using "short int"? That limits you to 32767 max
messages. You should be using "int" instead, which is the type that
the UnseenMsgs property uses.

Second, message sequence numbers are 1-based and relative to the
beginning of the mailbox, but you are assuming that all of the unseen
messages are only at the end of the mailbox. But worse, you are using
the UnseenMsgs value instead of the TotalMsgs value as the index to
start looping at, so you are not even starting at the end of the
mailbox. You are starting at some random index instead. So, you are
likely not even accessing the corrent messages to begin with.

The correct solution is to use the (UID)SearchMailBox() method instead
of the StatusMailBox() method. You can search for just unseen
messages, and it will return a list of matching sequence numbers
(SearchMailBox()) or UIDs (UIDSearchMailBox()).

IdIMAP41->UIDRetrieve( StrToInt(UID), IdMessage2 );

if ( IdIMAP41->UIDRetrieveFlags( StrToInt(UID), Flags ) )

When retreiving a message using (UID)Retrieve(), the server implicitly
sets the message's "Seen" flag. That is dictated by the IMAP protocol
specification. So, you should not need to set the "Seen" flag manually
in this situation. If the message flags actually change due to the
implicit setting of "Seen", the new flags are included in the retreival
output.

The (UID)RetrievePeek() methods, on the other hand, do not implicitly
set the "Seen" flag. Peeking a message does not set the flag,
retreiving the message does.

IdIMAP41->UIDStoreFlags(UID, sdAddSilent, TIdMessageFlagsSet() <<
mfSeen);

IdIMAP41->UIDDeleteMsg(UID);

Why are you bothering to set the "Seen" flag at all if you are just
going to delete the message immediately afterwards?

Also, note that (UID)DeleteMsg() simply marks the message for deletion,
but it is not actually deleted until ExpungeMailBox() is called.

With all of that said, try something more like this instead:

if ( IdIMAP41->SelectMailBox("INBOX") )
{
    TIdIMAP4SearchRec sr[1];
    sr[0].SearchKey = skUnseen;
 
    if ( IdIMAP41->UIDSearchMailBox( EXISTINGARRAY(sr) ) )
    {
        int ile = IdIMAP41->MailBox->SearchResult.Length;
 
        for ( int j = 0; j < ile; ++j )
        {
	      String UID = IdIMAP41->MailBox->SearchResult[j];
 
            IdMessage2->Clear();
	      if ( IdIMAP41->UIDRetrieve( UID, IdMessage2 ) )
            {
                // use IdMessage2 as needed...
 
                IdIMAP41->UIDDeleteMsg( UID );
            }
        }
    }
}


--
Remy Lebeau (TeamB)
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02