Suppres userproperty printing

Add-in Express™ Support Service
That's what is more important than anything else

Suppres userproperty printing
 
Tim Smet




Posts: 37
Joined: 2015-10-06
Hi,

I have no problems adding a few userproperties to an outlook mailitem object using Mailitem.userproperties.add but the problem is that outlook seems to print these added user properties when printing the mailitem.

I have found a stackoverflow item here http://stackoverflow.com/questions/701508/suppressing-outlook-field-printing that has a solution in dot net for this. I understand the code but i'm having problems changing it to delphi code. my main problem is the InvokeMember line, i guess i need to use userproperty.invoke in delphi but i'm not certain what the parameters should be.

So basically i'm asking how this code would look like in delphi:

static void SuppressUserPropertyPrinting(Outlook.MailItem message)
{
    try
    {   // Late Binding in .NET: https://support.microsoft.com/en-us/kb/302902
        Type userPropertyType;
        long dispidMember = 107;
        long ulPropPrintable = 0x4; // removes PDO_PRINT_SAVEAS
        string dispMemberName = String.Format("[DispID={0}]", dispidMember);
        object[] dispParams;

        if (message.UserProperties.Count == 0) return; // no props found (exit)

        // marks all user properties as suppressed
        foreach (Outlook.UserProperty userProperty in message.UserProperties.Cast<Outlook.UserProperty>())
        {
            if (userProperty == null) continue; // no prop found (go to next)
            userPropertyType = userProperty.GetType(); // user property type

            // Call IDispatch::Invoke to get the current flags
            object flags = userPropertyType.InvokeMember(dispMemberName, BindingFlags.GetProperty, null, userProperty, null);
            long lFlags = long.Parse(flags.ToString()); // default is 45 - PDO_IS_CUSTOM|PDO_PRINT_SAVEAS|PDO_PRINT_SAVEAS_DEF (ref: http://msdn.microsoft.com/en-us/library/ee415114.aspx)

            // Remove the hidden property Printable flag
            lFlags &= ~ulPropPrintable; // change to 41 - // PDO_IS_CUSTOM|PDO_PRINT_SAVEAS_DEF (ref: http://msdn.microsoft.com/en-us/library/ee415114.aspx)

            // Place the new flags property into an argument array
            dispParams = new object[] { lFlags };

            // Call IDispatch::Invoke to set the current flags
            userPropertyType.InvokeMember(dispMemberName, BindingFlags.SetProperty, null, userProperty, dispParams);
        }
    }
    catch { } // safely ignore if property suppression doesn't work
}


so that i can prevent outlook from printing the userproperties i added to my mail items.

Thanks
Posted 12 Jan, 2017 11:34:56 Top
Andrei Smolin


Add-in Express team


Posts: 18817
Joined: 2006-05-11
Hello Tim,

function TAddInModule.SuppressUserPropertyPrinting(mailItem: _MailItem) : HResult;
const
  propID: integer = 107;
  removePrinterFlag: integer = $4;
var
  props: UserProperties;
  prop: UserProperty;
  i: integer;
  res: OleVariant;
  disp : TDispParams;
  flags: Integer;
  dispIDs: array[0..0] of TDispID;

  args: array [0..0] of TVariantArg;
begin
  disp.rgvarg := @args;
  disp.rgdispidNamedArgs := @dispIDs;

  props := mailItem.UserProperties;
  if props.Count > 0 then begin
    for i := 1 to props.Count do begin
       prop := props.Item(i);

       disp.cNamedArgs:= 0;
       disp.cArgs:= 0;
       Result:= prop.Invoke(propID, GUID_NULL, SysLocale.DefaultLCID, DISPATCH_PROPERTYGET, disp, @res, nil, nil);

       if TVarData(res).VType = varInteger then begin
         flags := TVarData(res).VInteger;

         args[0].vt := VT_INT;
         args[0].intVal := flags and (not removePrinterFlag);
         disp.cArgs := 1;
         disp.cNamedArgs := 1;
         dispIDs[0]:= DISPID_PROPERTYPUT;
         Result:= prop.Invoke(propID, GUID_NULL, SysLocale.DefaultLCID, DISPATCH_PROPERTYPUT, disp, nil, nil, nil);
       end;

       prop := nil;
    end;
  end;
  props := nil;
end;



Andrei Smolin
Add-in Express Team Leader
Posted 13 Jan, 2017 08:02:42 Top
Tim Smet




Posts: 37
Joined: 2015-10-06
Hi Andrei,

Thank you very much, i now know how to use it.

this is the function i created based on your code. It removes the printflag from a userproperty and works in outlook 2016 still have to test older outlook versions:


function TAddInModule.RemoveUserPropertyPrintFlag(
  var aUserProperty: UserProperty): Boolean;
const
  propID: integer = 107;
  removePrinterFlag: integer = $4;
var
  res: OleVariant;
  disp : TDispParams;
  flags: Integer;

  dispIDs: array[0..0] of TDispID;
  args: array [0..0] of TVariantArg;
begin
   Result := False;
   disp.cNamedArgs:= 0;
   disp.cArgs:= 0;
   if aUserProperty.Invoke(propID, GUID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, disp, @res, nil, nil) = S_OK then
   begin
     if TVarData(res).VType = varInteger then
     begin
       flags := TVarData(res).VInteger;
       args[0].vt := VT_INT;
       args[0].intVal := flags and (not removePrinterFlag);
       disp.cArgs := 1;
       disp.cNamedArgs := 1;
       dispIDs[0]:= DISPID_PROPERTYPUT;
       disp.rgdispidNamedArgs := @dispIDs;
       disp.rgvarg := @args;
       Result:= aUserProperty.Invoke(propID, GUID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT, disp, nil, nil, nil) = S_OK;
     end;
   end;
end;



Thanks again you helped us a lot with this issues
Posted 13 Jan, 2017 08:48:36 Top
Andrei Smolin


Add-in Express team


Posts: 18817
Joined: 2006-05-11
You are welcome!


Andrei Smolin
Add-in Express Team Leader
Posted 13 Jan, 2017 09:03:56 Top