主要放在重复这一块,重复的部分是一些二进制档,按MS自定义的方式去写这个重复的数据
假定现在已经获取了Imeassge
使用下面的代码打开Imeassge的相关属性
HRESULT hr;
SPropValue PropValue_RP = {0};
GUID guid = {0};
guid.Data1 = 0x00062002;
guid.Data4[0] = 0xC0;
guid.Data4[7] = 0x46;
ULONG type, id = 0;
ZeroMemory(&PropValue_RP , sizeof(SPropValue));
LPSPropTagArray lpSpropTag_RecurrencePattern = NULL;
MAPINAMEID NameID_RecurrencePattern = {&guid, MNID_ID, {NULL}}; //{GUID,ulKind,union{ID,strName}Kind}
NameID_RecurrencePattern.Kind.lID=0x8216; //RecurrencePattern
LPMAPINAMEID lpNameID_NameID_RecurrencePattern = &NameID_RecurrencePattern;
hr = lpMessage->GetIDsFromNames(1, &lpNameID_NameID_RecurrencePattern, NULL, &lpSpropTag_RecurrencePattern);
type = PT_BINARY ;
id = PROP_ID(lpSpropTag_RecurrencePattern->aulPropTag[0]); //0x8182---〉0x8021
PropValue_RP.ulPropTag = PROP_TAG(type, id);
WORD wTmp = pOutlookScheduler->Repeat;
BYTE tmp = ((BYTE)(wTmp >> 8));
int iiiii = sizeof(SPropValue);
hr = MAPIAllocateBuffer( 80/*sizeof(SPropValue)*/,
(LPVOID *)&PropValue_RP.Value.bin.lpb);
ZeroMemory(PropValue_RP.Value.bin.lpb , 80/*sizeof(SPropValue)*/);
现在就是要修改PropValue_RP.Value.bin.lpb 使得重复生效
修改的标准如下,分别制定了在不同的位置表明的是什么意思:
Pseudocode
----------
All position offsets are from the beginning of the 0x8216 MAPI ID. The
existence of this MAPI ID with nonzero length should signify a recurrence.
Constants:
week_table {
0x02 = Monday
0x04 = Tuesday
0x08 = Wednesday
0x10 = Thursday
0x20 = Friday
0x40 = Saturday
0x01 = Sunday
}
Bitwise OR of above makes multiple selection of days
month_table {
0x0000 = January
0x60AE = February
0xE04B = March
0x40FA = April
0x00A3 = May
0x6051 = June
0x20FA = July
0x80A8 = August
0xE056 = September
0xA0FF = October
0x00AE = November
0xC056 = December
}
switch on value of position 0x04
case 0x0A
daily_recurrence()
case 0x0B
weekly_recurrence()
case 0x0C
monthly_recurrence()
case 0x0D
yearly_recurrence()
sub daily_occurrence {
# There are 2 types of daily recurrences
# 1 - Every X days
# 2 - Every weekday (Mon-Fri)
# Each can have either an indefinite period, or end after Y
# recurrences
if position 0x16 == (0x23 or 0x22 or 0x21)
# This is type 1 above
X = value for MAPI Code: [UD:x0011]
if position 0x16 == 0x23
no ending period (indefinite)
elsif position 0x16 == (0x22 or 0x21)
Y = positions 0x1B 0x1A
# (i.e. if 0x1B = 0x03, and 0x1A = 0xE7, num = 0x03E7 = 999 occurrences)
elsif position 0x16 == 0x3E
# This is type 2 above
if position 0x1A == 0x23
no ending period (indefinite)
elsif position 0x1A == (0x22 or 0x21)
Y = positions 0x1F 0x1E
# (i.e. if 0x1F = 0x03, and 0x1E = 0xE7, num = 0x03E7 = 999 occurrences)
}
sub weekly_recurrence {
# Every X week(s) on Y day
# (Y is day of week, e.g. Monday)
# There can be an indefinite period, or end after Z recurrences
X = position 0x0E
Y = position 0x16 (according to week_table above)
if position 0x1A == 0x23
no ending period (indefinite)
elsif position 0x1A == (0x22 or 0x21)
Z = positions 0x1F 0x1E
# (i.e. if 0x1F = 0x03, and 0x1E = 0xE7, num = 0x03E7 = 999 occurrences)
}
sub monthly_recurrence {
# There are 2 types of monthly recurrences
# 1 - Day X of every Y month(s)
# 2 - The Xth Y of every Z month(s)
# (where X is First,Second,Third,Fourth,Last and
# Y is Dayname,Weekday,Weekend Day,Day (any))
#
# Each can have either an indefinite period, or end after N
# recurrences
if position 0x06 == 0x02
# This is type 1 above
X = position 0x16
Y = position 0x0E
if position 0x1A == 0x23
no ending period (indefinite)
elsif position 0x1A == (0x22 or 0x21)
N = positions 0x1F 0x1E
# (i.e. if 0x1F = 0x03, and 0x1E = 0xE7, num = 0x03E7 = 999 occurrences)
elsif position 0x06 == 0x03
# This is type 2 above
X = position 0x1A (0x01 = First ... 0x05 = Last)
Y = position 0x16 (according to week_table above)
# Y can also take the following special values not in week_table:
# 0x7F = any day (i.e. 2nd day of month)
# 0x3E = weekday (Mon-Fri)
# 0x41 = weekend day (Sat, Sun)
Z = position 0x0E
if position 0x1E == 0x23
no ending period (indefinite)
elsif position 0x1E == (0x22 or 0x21)
N = positions 0x23 0x22
# (i.e. if 0x23 = 0x03, and 0x22 = 0xE7, num = 0x03E7 = 999 occurrences)
}
sub yearly_recurrence {
# There are 2 types of yearly recurrences
# 1 - Every X Y
# (where X is month name, Y is day number)
# 2 - The Xth Y of Z
# (where X is First,Second,Third,Fourth,Last and Y
# Y is Dayname,Weekday,Weekend Day,Day (any) and Z is month name)
#
# Each can have either an indefinite period, or end after N
# recurrences
if position 0x06 == 0x02
# This is type 1 above
X = positions 0x0A 0x0B (according to month_table above)
Y = position 0x16
if position 0x1A == 0x23
no ending period (indefinite)
elsif position 0x1A == (0x22 or 0x21)
N = positions 0x1F 0x1E
# (i.e. if 0x1F = 0x03, and 0x1E = 0xE7, num = 0x03E7 = 999 occurrences)
elsif position 0x06 == 0x03
# This is type 2 above
X = position 0x1A (0x01 = First ... 0x05 = Last)
Y = position 0x16 (according to week_table above)
# Y can also take the following special values not in week_table:
# 0x7F = any day (i.e. 2nd day of month)
# 0x3E = weekday (Mon-Fri)
# 0x41 = weekend day (Sat, Sun)
Z = positions 0x0A 0x0B (according to month_table above)
if position 0x1E == 0x23
no ending period (indefinite)
elsif position 0x1E = (0x22 or 0x21)
N = positions 0x23 0x22
# (i.e. if 0x23 = 0x03, and 0x22 = 0xE7, num = 0x03E7 = 999 occurrences)
}
Details
-------
Daily Occurrences
-----------------
Position 0x04 = 0x0A always
Position 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F 0x10
--------------------------------------------------------------------
Every 1 day 0x00 0x00 0x00 0x00 0xA0 0x05 0x00
Every 2 days 0x00 0x00 0x00 0x00 0x40 0x0B 0x00
Every 3 days 0xA0 0x05 0x00 0x00 0xE0 0x10 0x00
Every 4 days 0x00 0x00 0x00 0x00 0x80 0x16 0x00
Every 16 days 0x80 0x16 0x00 0x00 0x00 0x5A 0x00
Every 999 days 0x60 0x1E 0x09 0x00 0x60 0xF3 0x15
0x16 =
(0x23 or 0x22) every X days
0x3E every weekday
X = value for MAPI Code: [UD:x0011]
Ending time logic:
If position 0x16 == 0x23
No end (indefinite)
elsif position 0x16 == 0x22
num of occurrences = 0x1B 0x1A
(i.e. if 0x1B = 0x03, and 0x1A = 0xE7, num = 0x03E7 = 999 occurrences)
elsif position 0x16 == 0x3E
if position 0x1A == 0x23
No end (indefinite)
elsif position 0x1A == 0x22
num of occurrences = 0x1F 0x1E
(i.e. if 0x1F = 0x03, and 0x1E = 0xE7, num = 0x03E7 = 999 occurrences)
Weekly Occurrences
------------------
Position 0x04 = 0x0B always
These byte positions seem to designate how often recurrence occurs
99 = max week interval
Position 0x0A 0x0B 0x0C 0x0E
--------------------------------------------
Every 1 week 0xC0 0x21 0x00 0x01
Every 2 weeks 0x20 0x49 0x00 0x02
Every 3 weeks 0x20 0x49 0x00 0x03
Every 9 weeks 0x40 0xBF 0x00 0x09
Every 10 weeks 0x60 0x35 0x01 0x0A
Every 99 weeks 0x20 0xAB 0x07 0x63
Every 1 week, these byte positions seem to indicate weekday
Position 0x16 0x2E 0x2F
------------------------------------
Monday 0x02 0x40 0xD3
Tuesday 0x04 0xE0 0xD8
Wednesday 0x08 0x80 0xDE
Thursday 0x10 0x20 0xE4
Friday 0x20 0xC0 0xE9
Saturday 0x40 0x60 0xEF
Sunday 0x01 0x00 0xF5
Logic:
Weekly Occurrence = Position 0x04 = 0x0B
Every X weeks on weekday Y
X = Position 0x0E
Y = Position 0x16
0x02 = Monday
0x04 = Tuesday
0x08 = Wednesday
0x10 = Thursday
0x20 = Friday
0x40 = Saturday
0x01 = Sunday
Ending time
Position 0x1A 0x1E 0x1F 0x32 0x33 0x34 0x35
--------------------------------------------------------------------
no end 0x23 0x0A 0x00 0xDF 0x80 0xE9 0x5A
1 occurrence 0x22 0x01 0x00 0xE0 0xD8 0xA3 0x0C
2 occurrences 0x22 0x02 0x00 0x40 0x00 0xA4 0x0C
9 occurrences 0x22 0x09 0x00 0xE0 0x13 0xA5 0x0C
10 occurrences 0x22 0x0A 0x00 0x40 0x3B 0xA5 0x0C
11 occurrences 0x22 0x0B 0x00 0xA0 0x62 0xA5 0x0C
231 occurrences 0x22 0xE7 0x00 0x20 0x39 0xC7 0x0C
232 occurrences 0x22 0xE8 0x00 0x80 0x60 0xC7 0x0C
998 occurrences 0x22 0xE6 0x03 0xC0 0x31 0x3D 0x0D
999 occurrences 0x22 0xE7 0x03 0x20 0x59 0x3D 0x0D
Ending time logic:
If position 0x1A == 0x23
No end (indefinite)
elsif position 0x1A == 0x22
num of occurrences = 0x1F 0x1E
(i.e. if 0x1F = 0x03, and 0x1E = 0xE7, num = 0x03E7 = 999 occurrences)
Ending date goes by same logic as above. Number of occurrences is calculated
by Outlook, and there is no end date value stored.
Monthly Recurrences
-------------------
Position 0x04 = 0x0C always
Position 0x04 0x0E 0x16 0x2E 0x2F
------------------------------------------------------------
6th, every 1 month 0x0C 0x01 0x06 0x00 0x4F
16th, every 1 month 0x0C 0x01 0x10 0xE0 0xD8
16th, every 2 month 0x0C 0x02 0x10 0xE0 0xD8
17th, every 1 month 0x0C 0x01 0x11 0x80 0xDE
28th, every 1 month 0x0C 0x01 0x1C 0x60 0x1C
31st, every 1 month 0x0C 0x01 0x1F 0x40 0x2D
0x06 = 0x02
0x16 = day of month
0x0E = every X month
Ending time logic:
If position 0x1A == 0x23
No end (indefinite)
elsif position 0x1A == 0x22
num of occurrences = 0x1F 0x1E
(i.e. if 0x1F = 0x03, and 0x1E = 0xE7, num = 0x03E7 = 999 occurrences)
Position 0x04 0x06 0x0E 0x16 0x1A
--------------------------------------------------------------------
Every 1 month, 3rd Tuesday 0x0C 0x03 0x01 0x04 0x03
Every 1 month, 4th Tuesday 0x0C 0x03 0x01 0x04 0x04
Every 1 month, last Tuesday 0x0C 0x03 0x01 0x04 0x05
Every 99 months, last Tuesday 0x0C 0x03 0x63 0x04 0x05
Every 2 months, 2nd Wednesday 0x0C 0x03 0x02 0x08 0x02
Every 2 months, 2nd day 0x0C 0x03 0x02 0x7F 0x02
Every 2 months, 2nd weekday 0x0C 0x03 0x02 0x3E 0x02
Every 2 months, 2nd weekendday 0x0C 0x03 0x02 0x41 0x02
0x06 = 0x03 when using Every X month, Yth Z day of week
0x16 = Z day of week (as above)
or
0x7F = any day (i.e. 2nd day of month)
0x3E = weekday (Mon-Fri)
0x41 = weekend day (Sat, Sun)
0x1A = Yth day (0x01 = First ... 0x05 = Last)
0x0E = every X month
Ending time logic:
If position 0x1E == 0x23
No end (indefinite)
elsif position 0x1E == 0x22
num of occurrences = 0x23 0x22
(i.e. if 0x23 = 0x03, and 0x22 = 0xE7, num = 0x03E7 = 999 occurrences)
Yearly Occurrences
------------------
Position 0x04 = 0x0D always
Position 0x04 0x0C 0x16 0x30
----------------------------------------------------
Every 1 year, 03-16 0x0D 0x01 0x10 0xA3
Every 1 year, 04-16 0x0D 0x01 0x10 0xA4
Every 1 year, 05-16 0x0D 0x01 0x10 0xA5
0x06 = 0x02
0x0A 0x0B = month
0x16 = day number
Ending time logic:
If position 0x1A == 0x23
No end (indefinite)
elsif position 0x1A == 0x22
num of occurrences = 0x1F 0x1E
(i.e. if 0x1F = 0x03, and 0x1E = 0xE7, num = 0x03E7 = 999 occurrences)
Position 0x04 0x1A 0x16 0x0A 0x0B 0x32 0x33 0x34
------------------------------------------------------------------------------------
1st Tuesday of January 0x0D 0x01 0x04 0x00 0x00 0x20 0x4F 0xA2
1st Tuesday of February 0x0D 0x01 0x04 0x60 0xAE 0x20 0xEC 0xAA
2nd Tuesday of March 0x0D 0x02 0x04 0xE0 0x4B 0x80 0xB1 0xA3
3rd Tuesday of March 0x0D 0x03 0x04 0xE0 0x4B 0x60 0xD8 0xAB
3rd Tuesday of April 0x0D 0x03 0x04 0x40 0xFA 0xC0 0x9D 0xA4
3rd Tuesday of May 0x0D 0x03 0x04 0x00 0xA3 0x40 0x3B 0xA5
2nd Tuesday of May 0x0D 0x02 0x04 0x00 0xA3 0x60 0x13 0xAD
1st Tuesday of June 0x0D 0x01 0x04 0x60 0x51 0x00 0x8A 0xA5
1st Tuesday of July 0x0D 0x01 0x04 0x20 0xFA 0xE0 0x4E 0xA6
1st Tuesday of August 0x0D 0x01 0x04 0x80 0xA8 0x60 0xEC 0xA6
1st Tuesday of Septemb 0x0D 0x01 0x04 0xE0 0x56 0x40 0xB1 0xA7
1st Tuesday of October 0x0D 0x01 0x04 0xA0 0xFF 0xC0 0x4E 0xA8
1st Tuesday of Novemb 0x0D 0x01 0x04 0x00 0xAE 0x40 0xEC 0xA8
1st Tuesday of Decemb 0x0D 0x01 0x04 0xC0 0x56 0x20 0xB1 0xA9
0x06 = 0x03 when using Every Xth Y day of Z month
0x1A = X
0x16 = Y day of week (as above)
or
0x7F = any day (i.e. 2nd day of month)
0x3E = weekday (Mon-Fri)
0x41 = weekend day (Sat, Sun)
0x0A 0x0B = Z month
0x0000 = January
0x60AE = February
0xE04B = March
0x40FA = April
0x00A3 = May
0x6051 = June
0x20FA = July
0x80A8 = August
0xE056 = September
0xA0FF = October
0x00AE = November
0xC056 = December
Ending time logic:
If position 0x1E == 0x23
No end (indefinite)
elsif position 0x1E == 0x22
num of occurrences = 0x23 0x22
(i.e. if 0x23 = 0x03, and 0x22 = 0xE7, num = 0x03E7 = 999 occurrences)
Notes
-----
Outlook only sends cancellation when deleting recurrence, not specific entry
最后Force save 一下就可以了
上面已经写很详细了,另外还有一些需要修改的地方,其中最麻烦的是写入开始时间
MS计算这个开始时间是计算今天到1601年1月1日总共多少天,然后算出这么多天是多少分钟,写入这个时间就可以了
在Daily重复模式下,时间是从0x2A这个位置开始写的
其他重复模式下是从0x2E这个位置开始的,直接将分钟memcpy到里面去就可以了
如果有需要的话就提问吧。
時間是以分鐘來表示的