COMate - control COM objects via automation - OBSOLETE!

Developed or developing a new product in PureBasic? Tell the world about it.
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Post by Kwai chang caine »

Hello SROD

I just GO to know your great works for the OLE :oops:
It's thanks to KIFFI who help me for a question for LOTUS

He create for me a beginning of code to pilot LOTUS.
In Fact i have just added 2 lines :oops:

I want to translate this VB code who works fine in my job

Code: Select all

Option Explicit
'---------- API -----------
'pour faire passer au premier plan
Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long
'pour ouvrir la fenetre
Private Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long
'pour verifier si la Lotus est ouvert
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
    
Dim sSrvr As String  'the mail server for the current user
Dim MailDbName As String 'THe current users notes mail database name
Dim UserName As String 'The current users notes name

Dim retval As Variant  'Holds return value for functions handle

'---------------- fonction ouverture de session Notes -----------
Function CreateNotesSession() As Boolean
    Const notesclass$ = "NOTES"
    Const SW_SHOWMAXIMIZED = 3 'plein ecran
    Const SW_SHOWMMINIZED = 2 'reduire
    Const SW_SHOWWINDOW = 1 'fenetre
    Const SW_SHOW = 5
    
    Dim Lotus_Session As Object
    Dim rc&
    Dim lotusWindow&
    
    lotusWindow = FindWindow(notesclass, vbNullString)
    If lotusWindow Then
    Set Lotus_Session = CreateObject("Notes.NotesSession")
    sSrvr = Lotus_Session.GETENVIRONMENTSTRING("MailServer", True)
    MailDbName = Lotus_Session.GETENVIRONMENTSTRING("MailFile", True)
    UserName = Lotus_Session.UserName
    
    DoEvents
    'Ouverture de Lotus Notes
    retval = Shell("C:\Program Files\Notes\notes.exe =h:\notes\notes.ini", vbMaximizedFocus)
    
    'verifier que Lotus est bien ouvert (recupere le handle)
    lotusWindow = FindWindow(notesclass, vbNullString)
    If lotusWindow <> 0 Then
        rc = ShowWindow(lotusWindow, SW_SHOW)
        rc = SetForegroundWindow(lotusWindow)
        CreateNotesSession = True
    Else
         CreateNotesSession = False
    End If
   Else
    MsgBox "Votre Lotus Notes est fermé !"
    CreateNotesSession = False
End If
End Function

Sub CreateMailandAttachFileAdr(Optional IsSubject As String = "", Optional SendToAdr As String, Optional CCToAdr As String, Optional BCCToAdr As String = "", Optional Attach1 As String = "", Optional Attach2 As String = "", Optional body As String = "")
Const EMBED_ATTACHMENT As Integer = 1454
Const EMBED_OBJECT As Integer = 1453
Const EMBED_OBJECTLINK As Integer = 1452

Dim s As Object ' use back end classes to obtain mail database name
Dim db As Object '
Dim doc As Object ' front end document
Dim beDoc As Object ' back end document
Dim workspace As Object ' use front end classes to display to user
Dim bodypart As Object '
Dim bodyAtt As Object '
Dim lbsession As Boolean

lbsession = CreateNotesSession
If Not lbsession Then End

    'cree la session Lotus Notes
    Set s = CreateObject("Notes.Notessession")
    'se connecte a sa database
    Set db = s.getDatabase(sSrvr, MailDbName)
    If db.ISOPEN = True Then
        'database deja ouvert
    Else
        Call db.Openmail
    End If
    'cree un document memo
    Set beDoc = db.CreateDocument
    beDoc.Form = "Memo"
    
    'construction du mail
    Set bodypart = beDoc.CREATERICHTEXTITEM("Body")
    'beDoc.From = "Moi" 'inutile
    beDoc.SendTo = SendToAdr
    beDoc.CopyTo = CCToAdr
    beDoc.BlindCopyTo = BCCToAdr
    beDoc.Subject = IsSubject
    '-----------------------------------------
    'Remarque si destinataire multiple il suffie de mettre un tableau d'e-mail dans SendTo (CopyTo,BlindCopyTo)
    'exemple :
    'Dim recip(25) as variant
    'recip(0) = "emailaddress1"
    'recip(1) = "emailaddress2" e.t.c
    'beDoc.sendto = recip
    '----------------------------------------
    ' documents joint 1
    If Len(Attach1) > 0 Then
        If Len(Dir(Attach1)) > 0 Then
           Set bodyAtt = bodypart.EmbedObject(EMBED_ATTACHMENT, "", Attach1, Dir(Attach1))
        End If
    End If

    ' documents joint 2
    If Len(Attach2) > 0 Then
        If Len(Dir(Attach2)) > 0 Then
            Call bodyAtt.EmbedObject(EMBED_ATTACHMENT, "", Attach2, Dir(Attach2))
        End If
    End If
        
    'Affichage du mail dans Lotus Notes
    'Set workspace = CreateObject("Notes.NotesUIWorkspace")
   ' Call workspace.EditDocument(True, beDoc).FieldSetText("Body", body)
    
    'Envoie le mail
    beDoc.PostedDate = Now()
    beDoc.SEND 0, SendToAdr
    
    Set s = Nothing

End Sub
Private Sub envoyer_Click()
    CreateMailandAttachFileAdr Msujet.Text, Mto.Text, Mcc.Text, Mbcc.Text, MdocJoint1.Text, MdocJoint2.Text, Mbody.Text
End Sub
Kiffi write to me this:

Code: Select all

IncludeFile "COMate.pbi"

Procedure SendNotesMail(Subject.s, Attachment.s, BodyText.s, SendTo.s, cc.s = "", BCC.s = "", SaveIt.l = #False) 
  
  ; Set up the objects required for Automation into lotus notes 
  Protected Maildb.COMateObject ; The mail database 
  Protected UserName.s ;The current users notes name 
  Protected MailDbName.s ;THe current users notes mail database name 
  Protected MailDoc.COMateObject ;The mail document itself 
  Protected AttachME.COMateObject ;The attachment richtextfile object 
  Protected Session.COMateObject ;The notes session 
  Protected EmbedObj.COMateObject ;The embedded object (Attachment) 
  Protected intAttach.l 
  Protected intAttachments.l 
  Protected strAttachmentName.s 
  
  ; Start a session to notes 
  Session = COMate_CreateObject("Notes.NotesSession") 
  
  ; Get the sessions username and then calculate the mail file name 
  ; You may or may not need this as for MailDBname with some systems you 
  ; can pass an empty string 
  UserName = Session\GetStringProperty("UserName") 
  MailDbName = Left(UserName, 1) + Right(UserName, (Len(UserName) - FindString(UserName, " ", 1))) + ".nsf" 
  
  ; Open the mail database in notes 
  Maildb =  Session\GetObjectProperty("GetDatabase('', '" + MailDbName + "')") 
  
  IsOpen = Maildb\GetIntegerProperty("IsOpen") 
  
  If IsOpen 
    ; Already open for mail 
  Else 
    Maildb\Invoke("OPENMAIL") 
  EndIf 
  
  ; Set up the new mail document 
  MailDoc = Maildb\GetObjectProperty("CREATEDOCUMENT") 
  
  MailDoc\SetProperty("Form = 'Memo'") 
  MailDoc\SetProperty("SendTo = '" + SendTo + "'") 
  MailDoc\SetProperty("CopyTo = '" + cc + "'") 
  MailDoc\SetProperty("BlindCopyTo = '" + BCC + "'") 
  MailDoc\SetProperty("Subject = '" + Subject + "'") 
  MailDoc\SetProperty("Body = '" + BodyText + "'") 
  MailDoc\SetProperty("SAVEMESSAGEONSEND = '" + Str(SaveIt) + "'") 

  ;intAttachments = dhCountTokens(Attachment, ",") ; --> dhCountTokens??? 
  
  MailDoc\SetProperty("PostedDate = " + FormatDate("%dd/%mm/%yyyy", Date()) + " " + FormatDate("%hh:%ii:%ss", Date())) ; Added by Kcc
  MailDoc\SetProperty("SEND 0," + SendTo) ; Added by Kcc
       
EndProcedure

SendNotesMail("Essai", "", "Coucou", "Adress@Free.fr", "", "", #False)
But the line that i added not works obviously :oops:
ImageThe happiness is a road...
Not a destination
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Try

Code: Select all

MailDoc\SetProperty("PostedDate = '" + FormatDate("%dd/%mm/%yyyy", Date()) + " " + FormatDate("%hh:%ii:%ss", Date()) + "'") ; Added by Kcc 
The second line of yours looks completely wrong because when you are setting a property there needs to be an '=' present!!!

Try

Code: Select all

MailDoc\Invoke("SEND(0, '" + SendTo + "')") ; Added by Kcc 
Must admit that I am not sure about these lines because I do not have access to the relevant control(s). If they do not work then you'll have to use some OLE viewer to look at the method / property parameters.
I may look like a mule, but I'm not a complete ass.
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Post by Kwai chang caine »

Yes !!! that's works fine and the first time 8)

What a merveillous works you are do 8)
Like for PureDishelper i'm very impressive 8)

Obviously, you must know that i have another question :oops:
You begin to know me :oops:

I don't have understand the difference between "invoke" and "SetProperty" :roll:

Also i can't translate this line :oops:

Code: Select all

' documents joint 1 
    If Len(Attach1) > 0 Then 
        If Len(Dir(Attach1)) > 0 Then 
           Set bodyAtt = bodypart.EmbedObject(EMBED_ATTACHMENT, "", Attach1, Dir(Attach1)) 
        End If 
    End If 

    ' documents joint 2 
    If Len(Attach2) > 0 Then 
        If Len(Dir(Attach2)) > 0 Then 
            Call bodyAtt.EmbedObject(EMBED_ATTACHMENT, "", Attach2, Dir(Attach2)) 
        End If 
    End If 
        
    'Affichage du mail dans Lotus Notes 
    Set workspace = CreateObject("Notes.NotesUIWorkspace") 
    Call workspace.EditDocument(True, beDoc).FieldSetText("Body", body) 
ImageThe happiness is a road...
Not a destination
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

I don't have understand the difference between "invoke" and "SetProperty"
Well, in a nutshell, COM objects expose both methods (subroutines) and properties. Use "invoke" when calling one of these methods in which you do not care about any return value.

A COM property generally allows you to access a 'private' member variable of the object in question. For example a 'car' object might expose a 'color' property. In this case you would use something like (COMate) MyCarObject\GetIntegerProperty("color") to retrieve the color value of the given car instance. To set the color of that same instance you would use MyCarObject\SetProperty("color = ...") etc. Notice the '=' in the COMate command string when setting a property value - it is like setting a variable in PB.

As for your code, I am reluctant to have a go at the translation although it does look simple enough. I would need to know what the Dir() function does?
I may look like a mule, but I'm not a complete ass.
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Post by Kwai chang caine »

Well, in a nutshell, COM objects expose both methods (subroutines) and properties. Use "invoke" when calling one of these methods in which you do not care about any return value.
It's a litle bit like SUB and FUNCTION in VB

A SUB don't need return value, so it's INVOKE
Exemple:

Code: Select all

Private Sub Open()
[...]
End Sub
Open
The SUB execute all the code in her no return any value


A FUNCTION need return value, so it's GETPROPERTY

Code: Select all

Private Function Inc(a)
 a = a + 1
End Function
b = 1 
Count = Inc b 
Then Count = 2

Have i understand ??? :roll:

In VB, If File exist then DIR(File.txt) return the name of the file of the file.txt else dir return ""
For example

Code: Select all

Dir("c:\AUTOEXEC.BAT") return AUTOEXEC.BAT
Dir("AUTOEXEC.BAT") return ""
Is it your question ???
ImageThe happiness is a road...
Not a destination
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Okay, translating the following :

Code: Select all

' documents joint 1 
    If Len(Attach1) > 0 Then 
        If Len(Dir(Attach1)) > 0 Then 
           Set bodyAtt = bodypart.EmbedObject(EMBED_ATTACHMENT, "", Attach1, Dir(Attach1)) 
        End If 
    End If 
will look something like (I am assuming that EMBED_ATTACHMENT is a constant??? I've called it #EMBED_ATTACHMENT!)

Code: Select all

; documents joint 1 
    Define bodyAtt.COMateObject
    If Len(Attach1) > 0 Then 
        If FileSize(Attach1) > 0
             bodyAtt = bodypart\GetObjectProperty(" + Str(#EMBED_ATTACHMENT) +", '', '" + Attach1 + "', '" + Attach1 + "')")
        EndIf 
    EndIf 
I am unsure about this because I must admit that the VB looks a bit screwy in this case.

Note the use of double apostrophe's in the command string : '' (not double quotes!)
I may look like a mule, but I'm not a complete ass.
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Post by Kwai chang caine »

I am assuming that EMBED_ATTACHMENT is a constant???
Yes, in the top VB code it's write

Code: Select all

Const EMBED_ATTACHMENT As Integer = 1454 
Const EMBED_OBJECT As Integer = 1453 
Const EMBED_OBJECTLINK As Integer = 1452 
Then i have added

Code: Select all

 #EMBED_ATTACHMENT = 1454 ; Added by KCC
  #EMBED_OBJECT = 1453 ; Added by KCC
  #EMBED_OBJECTLINK = 1452 ; Added by KCC
And i have an error about "bodypart"
Then i have added

Code: Select all

  Define bodypart.COMateObject ; Added by KCC
So, the last code who don't works obviously, because i have an error (read error at adress 0) :cry: is

Code: Select all

IncludeFile "COMate.pbi" 

Procedure SendNotesMail(Subject.s, Attachment1.s, BodyText.s, SendTo.s, cc.s = "", BCC.s = "", SaveIt.l = #False) 
  
  #EMBED_ATTACHMENT = 1454 ; Added by KCC
  #EMBED_OBJECT = 1453 ; Added by KCC
  #EMBED_OBJECTLINK = 1452 ; Added by KCC
  
  ; Set up the objects required for Automation into lotus notes 
  Protected Maildb.COMateObject ; The mail database 
  Protected UserName.s ;The current users notes name 
  Protected MailDbName.s ;THe current users notes mail database name 
  Protected MailDoc.COMateObject ;The mail document itself 
  Protected AttachME.COMateObject ;The attachment richtextfile object 
  Protected Session.COMateObject ;The notes session 
  Protected EmbedObj.COMateObject ;The embedded object (Attachment) 
  Protected intAttach.l 
  Protected intAttachments.l 
  Protected strAttachmentName.s 
  
  ; Start a session to notes 
  Session = COMate_CreateObject("Notes.NotesSession") 
  
  ; Get the sessions username and then calculate the mail file name 
  ; You may or may not need this as for MailDBname with some systems you 
  ; can pass an empty string 
  UserName = Session\GetStringProperty("UserName") 
  MailDbName = Left(UserName, 1) + Right(UserName, (Len(UserName) - FindString(UserName, " ", 1))) + ".nsf" 
  
  ; Open the mail database in notes 
  Maildb =  Session\GetObjectProperty("GetDatabase('', '" + MailDbName + "')") 
  
  IsOpen = Maildb\GetIntegerProperty("IsOpen") 
  
  If IsOpen 
    ; Already open for mail 
  Else 
    Maildb\Invoke("OPENMAIL") 
  EndIf 
  
  ; Set up the new mail document 
  MailDoc = Maildb\GetObjectProperty("CREATEDOCUMENT") 
  
  MailDoc\SetProperty("Form = 'Memo'") 
  MailDoc\SetProperty("SendTo = '" + SendTo + "'") 
  MailDoc\SetProperty("CopyTo = '" + cc + "'") 
  MailDoc\SetProperty("BlindCopyTo = '" + BCC + "'") 
  MailDoc\SetProperty("Subject = '" + Subject + "'") 
  MailDoc\SetProperty("Body = '" + BodyText + "'") 
  MailDoc\SetProperty("SAVEMESSAGEONSEND = '" + Str(SaveIt) + "'") 

 ; documents joint 1 
  Define bodyAtt.COMateObject 
  Define bodypart.COMateObject ; Added by KCC
 
  If Len(Attachment1) > 0  
   If FileSize(Attachment1) > 0 
    bodyAtt = bodypart\GetObjectProperty(Str(#EMBED_ATTACHMENT) + ", '', '" + Attachment1 + "', '" + Attachment1 + "')") 
   EndIf 
  EndIf 
  
  MailDoc\SetProperty("PostedDate = '" + FormatDate("%dd/%mm/%yyyy", Date()) + " " + FormatDate("%hh:%ii:%ss", Date()) + "'") 
  MailDoc\Invoke("SEND(0, '" + SendTo + "')")   
        
EndProcedure 

SendNotesMail("Essai", "c:\File.txt", "Coucou", "Adress@free.fr", "", "", #False)
ImageThe happiness is a road...
Not a destination
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Post by Kwai chang caine »

And it's the same thing for

Code: Select all

  bodyAtt = bodypart\GetObjectProperty(Str(#EMBED_ATTACHMENT) + ", '', '" + Attachment1 + "', '" + Attachment1 + "'") 
ImageThe happiness is a road...
Not a destination
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Post by Kwai chang caine »

I try to translate

Code: Select all

Set workspace = CreateObject("Notes.NotesUIWorkspace") 
Call workspace.EditDocument(True, beDoc).FieldSetText("Body", body) 
To

Code: Select all

Define workspace.COMateObject
workspace = COMate_CreateObject("Notes.NotesUIWorkspace")*
workspace\SetProperty("EditDocument(True, beDoc) . FieldSetText('Body', body)")
or

Code: Select all

Define workspace.COMateObject
workspace = COMate_CreateObject("Notes.NotesUIWorkspace")
workspace\Invoke("EditDocument(True, beDoc) . FieldSetText('Body', body)") 
And no works too :cry:
ImageThe happiness is a road...
Not a destination
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Post by Kwai chang caine »

I try also this, and no better, i can't mix Object and string :cry:

Code: Select all

Define workspace.COMateObject 
workspace = COMate_CreateObject("Notes.NotesUIWorkspace")
workspace\Invoke("EditDocument(-1," + MailDoc + "). FieldSetText('Body', body)")
ImageThe happiness is a road...
Not a destination
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

bodyAtt = bodypart\GetObjectProperty(Str(#EMBED_ATTACHMENT) + ", '', '" + Attachment1 + "', '" + Attachment1 + "')")
Of course it crashes, bodyPart has not been initialised - it is an empty object! There is something missing in your code.

Kwai, please read the COMate manual - I spent a long time on it and it will answer many of your questions.
Define workspace.COMateObject
workspace = COMate_CreateObject("Notes.NotesUIWorkspace")*
workspace\SetProperty("EditDocument(True, beDoc) . FieldSetText('Body', body)")
Your translation has 101 mistakes in it, but before that, does 'True' equate to a boolean true? If so use #True or #True AS boolean, and what on earth is beDoc?
I may look like a mule, but I'm not a complete ass.
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Post by Kwai chang caine »

Well i go to try to read the COMate doc :wink:

Before i have try a last chance, and i again loose :D

Code: Select all

Define workspace.COMateObject 
workspace = COMate_CreateObject("Notes.NotesUIWorkspace")
workspace\Invoke("EditDocument(" + Str(#True) + "," + Str(MailDoc) + "). FieldSetText('Body', body)")
ImageThe happiness is a road...
Not a destination
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Kwaï chang caïne wrote:

Code: Select all

Define workspace.COMateObject 
workspace = COMate_CreateObject("Notes.NotesUIWorkspace")
workspace\Invoke("EditDocument(" + Str(#True) + "," + Str(MailDoc) + "). FieldSetText('Body', body)")
What is the body variable? I cannot see it in your code? Assuming it is a string variable......

Code: Select all

Define workspace.COMateObject 
workspace = COMate_CreateObject("Notes.NotesUIWorkspace")
workspace\Invoke("EditDocument(#True AS boolean, " + Str(MailDoc) + " AS COMate object)\FieldSetText('Body', '" + body + "')")
I may look like a mule, but I'm not a complete ass.
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Post by Kwai chang caine »

Yes body is a variable who countain the text of the message
Look at

Code: Select all

Sub CreateMailandAttachFileAdr(Optional IsSubject As String = "", Optional SendToAdr As String, Optional CCToAdr As String, Optional BCCToAdr As String = "", Optional Attach1 As String = "", Optional Attach2 As String = "", Optional body As String = "") 
My error is i have not swap with "BodyText" :oops:
ImageThe happiness is a road...
Not a destination
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Post by Kwai chang caine »

I have replace with "Bodytext"

Code: Select all

  Define workspace.COMateObject 
  workspace = COMate_CreateObject("Notes.NotesUIWorkspace") 
  workspace\Invoke("EditDocument(#True AS boolean, " + Str(MailDoc) + " AS COMate object)\FieldSetText('Body', '" + BodyText + "')")
It don't works too.
I'm so sad :cry:
ImageThe happiness is a road...
Not a destination
Post Reply