Saturday, February 4, 2017

outlook addin to copy hyperlink in clipboard

Hello,

2017-02-05 21:41
Changed global variable definition for event bug

2017-02-05 20:00
Changed the way to create outlook bar and buttons to be more dynamic (array of bars, array of buttons in bar)



This outlook addin was compiled as "outlook addin" in visual studio 2013
It is signed, but you can change the certificate before recompiling

Tested on outlook 2013

This will add a toolbar with "classer et faire lien" (wich is not what it is doing, it only does the link)

When you press the button in complements,  it will generate a hyperlink to the message(s) selected or to the message actually open at the moment.

then you can paste the link in any other application as it will be an html outlook link.



------------------- vb.net visual studio 2013 -----------------------------

Imports System.Object
Imports System.IO
Imports System.Windows.Forms

Public Class ThisAddIn

    Const RegHtml As String = "HTML Format"

    Public WithEvents inspectors01 As Outlook.Inspectors

    Public Class glovar
        '=== this class have variables global to all the other classes
        Public Shared button00 As Office.CommandBarButton '=== in explorer, aka main windows
        Public Shared button01 As Office.CommandBarButton '=== in explorer, aka main windows
        Public Shared button02 As Office.CommandBarButton '=== in explorer, aka main windows

    End Class

'=== structure to pass to a function to create a toolbar in outlook

    Public Structure bar_param
        Dim bar_Exist01 As Integer   '=== if bar exist we do not recreate
        Dim bar_Caption01 As String   '=== name of bar
        Dim bar_inexplorer01 As Integer '=== create in main outlook window
        Dim bar_ininspector01 As Integer '=== create in message window
        Dim explorerorinspector01 As Object
        Dim buttons01 As but_param()

    End Structure

'=== strucutre to pass to a function to create a button in the bar we created just before

    Public Structure but_param
        Dim bar_obj As Object
        Dim but_exist01 As Integer
        Dim but_Caption01 As String
        Dim but_tooltip01 As String
        Dim but_onaction01 As String
        Dim but_face01 As Integer           '=== icon
        Dim but_inexplorer01 As Integer     '=== in main outlook window
        Dim but_ininspector01 As Integer    '=== in message window
        Dim but_bar01 As Object             '=== bar to add button to

    End Structure

    Private Sub ThisAddIn_Startup() Handles Me.Startup
        Dim inspector01 As Microsoft.Office.Interop.Outlook.Inspector
        inspectors01 = Me.Application.Inspectors

        Dim dummy As Integer

        dummy = add_bar_and_buttons(Globals.ThisAddIn.Application.ActiveExplorer)

        Dim objNet = CreateObject("WScript.Network")
        '=== get username logon from local machine
        Dim usenam As String = LCase(objNet.UserName)

    End Sub

    Private Sub ThisAddIn_Shutdown() Handles Me.Shutdown
        'outlookaddin1 = Nothing
    End Sub

    'Dim bar01 As Office.CommandBar '=== in explorer
    'Dim bar03 As Office.CommandBar '=== in inspector

    Public Sub inspectors01_NewInspector(ByVal Inspector As Microsoft.Office.Interop.Outlook.Inspector) Handles inspectors01.NewInspector

        '=== a new inspector just openned (a new mail maybe?)
        Dim dummy As Integer
        'MsgBox("new inspector")
        dummy = add_bar_and_buttons(Inspector)

        'If logall = 1 Then file02.writeline(Now & " adding bar in inspector")

    End Sub


    Private Sub copierhyperlien01(ByVal ctrl As Office.CommandBarButton, ByRef Cancel As Boolean)

        '''''''''''''''''''''''''''''''''
        ' the mail is open in inspector
        '''''''''''''''''''''''''''''''''
        Dim inspector01 As Microsoft.Office.Interop.Outlook.Inspector
        inspector01 = Globals.ThisAddIn.Application.ActiveInspector

        Dim item01(0) As Object
        Dim item01ismailininspector = 0

        If Not inspector01 Is Nothing Then
            Try
                '=== check the actual openned item, if it does not exist, then there is no mail open at the moment
                item01(0) = inspector01.CurrentItem
                item01ismailininspector = 1
            Catch ex As Exception
                '=== no item is openned, we create one later
                item01(0) = Nothing
            End Try
        Else
            '=== no inspector, that mean there is no item opened
        End If

        Dim itemcnt = 0

        If item01ismailininspector = 0 Then
            ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
            ' get all selected items in explorer (not inspector, wich would be an open item)
            ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
            '=== selected items in explorer window
            Dim explorer01 = Globals.ThisAddIn.Application.ActiveExplorer
            Dim selection01 = explorer01.Selection

            For Each item02 In selection01
                ReDim Preserve item01(itemcnt)
                item01(itemcnt) = item02
                itemcnt = itemcnt + 1
            Next
            itemcnt = itemcnt - 1
            'MsgBox(selection01.Count)

        Else
            '=== the email is open right now in inspector
            '=== we have only one email to process
        End If

        Dim link01 As String = ""

        For i = 0 To itemcnt

            If TypeOf item01(i) Is Outlook.MailItem Then
                link01 = link01 & "<a href=""outlook:" & item01(i).EntryID & """>" & _
                "LIEN OUTLOOK From: " & item01(i).SenderName & _
                " Sujet: " & item01(i).Subject & _
                " Date: " & item01(i).ReceivedTime & _
                " Categorie: " & item01(i).categories & _
                "</a><br>"
            ElseIf TypeOf item01(i) Is Outlook.TaskItem Then
                link01 = link01 & "<a href=""outlook:" & item01(i).EntryID & """>" & _
                "LIEN OUTLOOK From: " & item01(i).Owner & _
                " Sujet: " & item01(i).Subject & _
                " Date due: " & item01(i).DueDate & _
                " Categorie: " & item01(i).categories & _
                "</a><br>"
            ElseIf TypeOf item01(i) Is Outlook.ReportItem Then
                link01 = link01 & "<a href=""outlook:" & item01(i).EntryID & """>" & _
                "LIEN OUTLOOK From: OUTLOOK" & _
                " Sujet: " & item01(i).Subject & _
                " Date: " & item01(i).CreationTime & _
                " Categorie: " & item01(i).categories & _
                "</a><br>"
            ElseIf TypeOf item01(i) Is Outlook.ContactItem Then
                link01 = link01 & "<a href=""outlook:" & item01(i).EntryID & """>" & _
                "LIEN OUTLOOK From: " & item01(i).FullNameAndCompany & _
                " Categorie: " & item01(i).categories & _
                "</a><br>"
                '" Date: " & message.CreationTime & _
                '" Sujet: " & message.Subject & _
            Else
                link01 = link01 & "ERREUR - Un item dans votre sélection est... étrange - pas de lien dans le presse-papier<br>"
            End If

        Next

        '=== convert link to html ready to be put in clipboard
        Dim dummy = SetHtml_put_in_clipboard(link01)

        'MsgBox("You clicked: " + ctrl.Caption + vbCrLf + "link01: " + link01)
        '=== put link01 in clipboard



        '=== futur search for client contract number to move the mail to a client contract folder

        'Dim txt02 = mail01(itemcnt).HTMLBody

        '=== warning if a whole groupe was selected (selection of a whole day by accident)

        '=== get subject and search 999000 (id)

        '=== if no id found, ask for an id to be able to move the email in a folder

        '=== get email content and search for 999000 (999 = client, 000 = project)

        '=== search public folder for this id number (999000) 999 = client 000 = project

        '=== if no public folder, search in inbox folder

        '=== if noinbox folder, create one

        '=== move a copy of the email in deleted items

        '=== move the email in public folder or inbox folder



    End Sub

    Function SetHtml_put_in_clipboard(ByVal NewVal As String) As Boolean

        '=== source: html string
        '=== destination: html data block for clipboard

        Dim n As String
        Dim o As Object
        Dim p As Object
        Dim q As Object
        Dim r As String
        Dim i As Integer
        Dim s As String

        '=== replace all special caracters 128+ ascii with a code for html code
        i = 1
        While i < Len(NewVal)
            s = Mid(NewVal, i, 1)
            r = Asc(s)
            If r > 128 Then
                NewVal = Replace(NewVal, s, "&#" & Trim(CStr(r)) & ";")
                i = i + 3 + Len(Trim(CStr(r)))
            Else
                i = i + 1
            End If
        End While

        '=== build html structure for clipboard
        n = "Version:0.9" & vbCrLf
        n = n & "StartHTML:00000000" & vbCrLf
        n = n & "EndHTML:00000000" & vbCrLf
        n = n & "StartFragment:00000000" & vbCrLf
        n = n & "EndFragment:00000000" & vbCrLf
        n = n & "StartSelection:00000000" & vbCrLf
        n = n & "EndSelection:00000000" & vbCrLf
        n = n & "<html><body>" & vbCrLf
        n = n & "<!--StartFragment-->" & vbCrLf
        n = n & NewVal & vbCrLf
        n = n & "<!--EndFragment-->" & vbCrLf
        n = n & "</BODY></HTML>" & vbCrLf

        'Version: vv version number of the clipboard. Starting version is 0.9.
        'StartHTML: bytecount from the beginning of the clipboard to the start of the context, or -1 if no context.
        'EndHTML: bytecount from the beginning of the clipboard to the end of the context, or -1 if no context.
        'StartFragment: bytecount from the beginning of the clipboard to the start of the fragment.
        'EndFragment: bytecount from the beginning of the clipboard to the end of the fragment.
        'StartSelection: bytecount from the beginning of the clipboard to the start of the selection.
        'EndSelection: bytecount from the beginning of the clipboard to the end of the selection.

        '=== once the string is done, we can chek where are the chekpoints
        '=== then write it in the string itself, padding with "0"
        q = "<html>"
        p = Trim(CStr(InStr(LCase(n), q) - 1))
        o = StrDup(8 - Len(p), "0") & p
        n = Replace(n, "StartHTML:00000000", "StartHTML:" & o, 1, 1)

        q = ""
        p = Trim(CStr(Len(n)))
        o = StrDup(8 - Len(p), "0") & p
        n = Replace(n, "EndHTML:00000000", "EndHTML:" & o, 1, 1)

        q = "<!--startfragment-->"
        p = Trim(CStr(InStr(LCase(n), q) + Len(q) - 1))
        o = StrDup(8 - Len(p), "0") & p
        n = Replace(n, "StartFragment:00000000", "StartFragment:" & o, 1, 1)

        q = "<!--endfragment-->"
        p = Trim(CStr(InStr(LCase(n), q) - 1))
        o = StrDup(8 - Len(p), "0") & p
        n = Replace(n, "EndFragment:00000000", "EndFragment:" & o, 1, 1)

        Dim dataObject = New DataObject()

        dataObject.SetData(DataFormats.Html, n)
        'dataObject.SetData(DataFormats.Text, NewVal)
        'dataObject.SetData(DataFormats.UnicodeText, NewVal)

        Clipboard.SetDataObject(dataObject, 1)

        Return 0

    End Function
    Function add_bar_and_buttons(inspectororexplorer01 As Object)

        Dim buttoncnt = 0
        Dim but_param01() As but_param

        buttoncnt = 0

        ReDim Preserve but_param01(buttoncnt)
        but_param01(buttoncnt).but_exist01 = 0
        but_param01(buttoncnt).but_Caption01 = "Aide Help"
        but_param01(buttoncnt).but_tooltip01 = "Aide sur ce addin"
        but_param01(buttoncnt).but_onaction01 = "aide01"
        but_param01(buttoncnt).but_face01 = 5432
        but_param01(buttoncnt).but_inexplorer01 = 1
        but_param01(buttoncnt).but_ininspector01 = 1

        buttoncnt = buttoncnt + 1
        ReDim Preserve but_param01(buttoncnt)
        but_param01(buttoncnt).but_exist01 = 0
        but_param01(buttoncnt).but_Caption01 = "Classer Item"
        but_param01(buttoncnt).but_tooltip01 = "Classer cet(ces) item dans un dossier de projet 999000"
        but_param01(buttoncnt).but_onaction01 = "classeritem01"
        but_param01(buttoncnt).but_face01 = 5432
        but_param01(buttoncnt).but_inexplorer01 = 1
        but_param01(buttoncnt).but_ininspector01 = 1

        buttoncnt = buttoncnt + 1
        ReDim Preserve but_param01(buttoncnt)
        but_param01(buttoncnt).but_exist01 = 0
        but_param01(buttoncnt).but_Caption01 = "Copier Hyperlien"
        but_param01(buttoncnt).but_tooltip01 = "Copier un lien vers cet item dans le presse papier"
        but_param01(buttoncnt).but_onaction01 = "copierhyperlien01"
        but_param01(buttoncnt).but_face01 = 5432
        but_param01(buttoncnt).but_inexplorer01 = 1
        but_param01(buttoncnt).but_ininspector01 = 1

        '=== toolbar
        Dim toolbarcnt = 0
        Dim bar_param01(toolbarcnt) As bar_param

        bar_param01(toolbarcnt).bar_Exist01 = 0
        bar_param01(toolbarcnt).bar_Caption01 = "Courriel01"
        bar_param01(toolbarcnt).bar_inexplorer01 = 1
        bar_param01(toolbarcnt).bar_ininspector01 = 1
        bar_param01(toolbarcnt).explorerorinspector01 = inspectororexplorer01
        bar_param01(toolbarcnt).buttons01 = but_param01

        '=== add a toolbar object in outlook explorer (main window) or inspector (message)
        '=== with a structure as parameter, we can add as many arguments we want before calling this function without modifying all the line that use it

        '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
        ' toolbar(s)
        '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
        Dim toolbar_Add As Office.CommandBar
        'Dim toolbar_Add As Microsoft.Office.Core.CommandBar
        'MsgBox("add bar and buttons called")
        For bartot01 = 0 To toolbarcnt

            Dim bars01 As Object

            Try
                bars01 = inspectororexplorer01.CommandBars
            Catch ex As Exception
                '=== no bars at all in customs bars in outlook
                'MsgBox("failed to get explorer bars or inspector bars")
            End Try

            If Not bars01 Is Nothing Then

                '=== check if in all bars in a bar with same name exist
                For Each bar01 In bars01
                    If Trim(LCase(bar01.Name)) = Trim(LCase(bar_param01(bartot01).bar_Caption01)) Then
                        bar_param01(bartot01).bar_Exist01 = 1
                        toolbar_Add = bar01
                    End If
                Next

                '=== add tolbar if not already there
                If bar_param01(bartot01).bar_Exist01 = 0 Then
                    '=== we are in outlook main window
                    toolbar_Add = inspectororexplorer01.CommandBars.Add(bar_param01(bartot01).bar_Caption01)
                End If

                '=== make toolbar visible
                If Not toolbar_Add Is Nothing Then
                    'MsgBox("bar added")
                    toolbar_Add.Name = bar_param01(bartot01).bar_Caption01
                    toolbar_Add.Visible = True
                    If bar_param01(bartot01).bar_Exist01 = 0 Then
                        toolbar_Add.Position = Office.MsoBarPosition.msoBarTop
                    End If

                    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
                    ' button(s)
                    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
                    For buttot01 = 0 To buttoncnt

                        'Dim button_Add As Office.CommandBarButton
                        '=== add a button in a toolbar
                        '=== the bar to add the button to is in the parameters structure

                        Dim button02 As Office.CommandBarButton
                        Dim dontadd01 As Integer = 0

                        '=== delete all buttons in bar
                        For Each button02 In toolbar_Add.Controls 'but_param01(buttot01).but_bar01.Controls
                            '=== no more delete all, we simply delete old buttons we dont want anymore
                            If LCase(but_param01(buttot01).but_Caption01) = LCase(button02.Caption) Then
                                dontadd01 = 1
                                Exit For
                            End If
                            If button02.Caption = "a effacer" Then
                                'button02.Delete()
                            End If
                        Next

                        '=== button add

                        If dontadd01 <> 1 Then
                            button02 = inspectororexplorer01.CommandBars(toolbar_Add.Name).Controls.Add(Type:=Office.MsoControlType.msoControlButton, Before:=1)

                            If Not button02 Is Nothing Then
                                With button02
                                    'buttons(depnum, 0)

                                    .Caption = but_param01(buttot01).but_Caption01
                                    .TooltipText = but_param01(buttot01).but_tooltip01
                                    .Enabled = True
                                    .Visible = True
                                    .OnAction = but_param01(buttot01).but_onaction01
                                    '.OnAction = "!<" &  & ">"
                                    .Tag = but_param01(buttot01).but_Caption01
                                    .Style = Office.MsoButtonStyle.msoButtonIconAndCaption
                                    .FaceId = but_param01(buttot01).but_face01

                                    'Dim Icon01 = LoadPicture("C:\_outlook\icon.bmp")
                                End With
                                '=== add event only in explorer (not in inspector)
                                'Microsoft.Office.Interop.Outlook.Inspector
                                'Globals.ThisAddIn.Application.ActiveExplorer
                                If TypeOf inspectororexplorer01 Is Outlook.Explorer Then
                                    If but_param01(buttot01).but_Caption01 = but_param01(2).but_Caption01 Then
                                        '=== copy hyerlink to open item or selected item(s)
                                        glovar.button02 = button02
                                        AddHandler glovar.button02.Click, AddressOf copierhyperlien01
                                        'MsgBox("event added")
                                    End If

                                    If but_param01(buttot01).but_Caption01 = but_param01(1).but_Caption01 Then
                                        '=== copy item in contract folder
                                        '=== delete item (send to deleted items)
                                        glovar.button01 = button02
                                        AddHandler glovar.button01.Click, AddressOf classeritem01
                                    End If

                                    If but_param01(buttot01).but_Caption01 = but_param01(0).but_Caption01 Then
                                        '=== help about this addin
                                        glovar.button00 = button02
                                        AddHandler glovar.button00.Click, AddressOf aide01
                                    End If

                                Else
                                    '=== no event definition
                                End If
                            Else
                                '=== button not created
                            End If
                        Else
                            '=== the button was already there
                        End If
                    Next
                Else
                    '=== toolbar not created
                End If
            Else
                '=== there was no toolbars anywhere?
            End If

            '=== there was no inspectors (message) or explorer opened at the startup of outlook
        Next

        Return 0
    End Function
    Private Sub aide01(ByVal ctrl As Office.CommandBarButton, ByRef Cancel As Boolean)
        Dim msg01 As String = ""
        msg01 = msg01 & "Aide Help" & vbCrLf & vbCrLf
        msg01 = msg01 & "Par: Serge Fournier (sergefournier@hotmail.com)" & vbCrLf
        msg01 = msg01 & "The version is in DLL properties" & vbCrLf & vbCrLf
        msg01 = msg01 & "(C) 2017-02-05" & vbCrLf
        MsgBox(msg01)

    End Sub

    Private Sub classeritem01(ByVal ctrl As Office.CommandBarButton, ByRef Cancel As Boolean)
        'Microsoft.Office.Interop.Outlook.Inspector
        'Globals.ThisAddIn.Application.ActiveExplorer
        MsgBox("classer item")
        '''''''''''''''''''''''''''''''''
        ' the mail is open in inspector
        '''''''''''''''''''''''''''''''''
        Dim inspector01 As Microsoft.Office.Interop.Outlook.Inspector
        inspector01 = Globals.ThisAddIn.Application.ActiveInspector

        Dim item01(0) As Object
        Dim item01ismailininspector = 0

        If Not inspector01 Is Nothing Then
            Try
                '=== check the actual openned item, if it does not exist, then there is no mail open at the moment
                item01(0) = inspector01.CurrentItem
                item01ismailininspector = 1
            Catch ex As Exception
                '=== no item is openned, we create one later
                item01(0) = Nothing
            End Try
        Else
            '=== no inspector, that mean there is no item opened
        End If

        Dim itemcnt = 0

        If item01ismailininspector = 0 Then
            ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
            ' get all selected items in explorer (not inspector, wich would be an open item)
            ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
            '=== selected items in explorer window
            Dim explorer01 = Globals.ThisAddIn.Application.ActiveExplorer
            Dim selection01 = explorer01.Selection

            For Each item02 In selection01
                ReDim Preserve item01(itemcnt)
                item01(itemcnt) = item02
                itemcnt = itemcnt + 1
            Next
            itemcnt = itemcnt - 1
            'MsgBox(selection01.Count)

        Else
            '=== the item is open right now in inspector
            '=== we have only one item to process: item01(0)
        End If


        For i = 0 To itemcnt

            If TypeOf item01(i) Is Outlook.MailItem Then
                Dim item02 As Outlook.MailItem
                item02 = item01(i)
                '=== look for any project code in item object 999000 (client 999, project 000)
                Dim object01 As String
                object01 = item02.Subject

                Dim projectid01 As String
                projectid01 = find_projet(object01, "######")

                MsgBox("projectid01: " & projectid01)

                '=== look for any project code in item content

            ElseIf TypeOf item01(i) Is Outlook.TaskItem Then

            ElseIf TypeOf item01(i) Is Outlook.ReportItem Then

            ElseIf TypeOf item01(i) Is Outlook.ContactItem Then

            End If




        Next

    End Sub
    Private Function find_projet(text01 As String, mask01 As String) As String
        Dim projectid01 As String = ""
        If Len(text01) >= Len(mask01) Then
            Dim found01 = 0
            Dim char01 As String
            Dim char02 As String
            Dim totfound01 As Integer = 0
            Dim i As Integer = 0
            While totfound01 < Len(mask01) And i < Len(text01)

                char01 = Mid(text01, i + 1, 1)
                Dim i2 As Integer = 0
                While totfound01 < Len(mask01) And i2 < Len(mask01)

                    char02 = Mid(mask01, i2 + 1, 1)
                    '=== find number sequence for project id
                    If char02 = "#" Then
                        If InStr(char01, "0123456789") <> 0 Then
                            totfound01 = totfound01 + 1
                            projectid01 = projectid01 & char01
                        Else
                            totfound01 = 0
                            projectid01 = ""
                        End If
                        i2 = i2 + 1
                    End If
                End While
                i = i + 1
            End While

        Else
            projectid01 = ""
        End If

        Return projectid01
    End Function
End Class

Wednesday, January 18, 2017

Dynamic web interface in cplusplus CPP visual studio 2013



2017-03-08
For visual studio 2017 community
1.
bug: #include "stdio.h"
Go in setup ("C:\Program Files (x86)\Microsoft Visual Studio\Installer\vs_installer.exe")
In second tab, add MFC support
Change include folders path in project:
C:\Program Files (x86)\Windows Kits\10\Include\10.0.14393.0\ucrt;C:\Program Files %28x86%29\Windows Kits\10\Lib\10.0.14393.0\ucrt\x86;$(IncludePath)

2.
Download and install the windows 10 sdk
https://dev.windows.com/en-US/downloads/windows-10-sdk

3.
ucrtd.lib bug
libraries include path:
C:\Program Files (x86)\Windows Kits\10\Lib\10.0.14393.0\ucrt\x86


2017-01-22
Configured to compile as Release
(check comment in code: Troubleshooting)
added include "windows.h" for innerhtml to work


2017-12-20
Events stopped working :(
After a reboot, it worked again
So maybe i need to free some event before closing internet explorer

2017-12-19
Corected management of left menu to exit any input form
Passed the vector as pointers, not global variables anymore

-----

This is CPP using internet explorer as an interface

Tested in windows 10

Requis:
Visual studio 2013

Warning:
not optimized at all, no release of variables (i will add later)


// ConsoleApplication1.cpp

// visual studio 2013 cpp console application

// Troubleshooting:
/* Project  "project" Properties->Configuration Properties->C / C++->Advanced->Show Includes : YES(/ showIncludes) */
// Project  "project" Properties->Configuration Properties->General->Project Defaults->Use of MFC : Use MFC in a shared DLL

// #undef True
// #undef False

#include "stdafx.h"
#include "stdio.h"
#include "afx.h"
#include <string>
#include <malloc.h>
#include <iostream>
#include <vector>
#include "Windows.h"

#include "Exdisp.h"
#import "shdocvw.dll"
#include <MsHTML.h>
#include <afxdisp.h>

#include <cassert>


//#define _AFXDLL C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\atlmfc\include\afx.h
//C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\atlmfc\include\afx.h 24 1 ConsoleApplication1


using std::cout;
using std::wcout;

bool WaitTillLoaded(int nTimeout);
int writeln01(IHTMLDocument2* phtmldoc1, std::wstring string01);
int create_web_main(
std::vector<std::wstring>* arrbutnam,
std::vector<std::wstring>* arrbutdes,
std::vector<std::wstring>* arrdepnam,
std::vector<std::wstring>* arrdepcol);
// name of button on left frame (also ID)
// description or caption
// sector (sectors have a space between them)
// button color of a sector

IHTMLDocument2* gethtmele(IHTMLDocument2* phtmldoc2, std::wstring frame01);
void doevents();
std::string getdefaultbrowserpath();
void clrfra(IHTMLDocument2* fra);

HWND m_hWnd; // handle for this console application
IWebBrowser2* pbrowser; // internet explorer object
IHTMLDocument2* flef; // frame left document html
IHTMLDocument2* fmid;
IHTMLDocument2* fbot;
IHTMLDocument2* pHtmlDoc; // main itnernet explorer windows html content
bool iexploreclosed = FALSE; // internet explorer still exist (was not closed), an event will manage this in the futur
IHTMLElement* findhtmlelement(IHTMLDocument2* fra, std::wstring type01, std::wstring name01);

std::vector<std::wstring>  dynforgen(IHTMLDocument2 *fra, std::wstring *title01,
std::vector<std::wstring>* destmp,
std::vector<std::wstring>* namtmp,
std::vector<std::wstring>* deftmp,
std::vector<std::wstring>* typtmp,
std::vector<std::wstring>* errtmp,
std::vector<std::wstring>* buttmp);

std::wstring resbutlef;
std::wstring resbutmid;
std::wstring resbutbot;
std::wstring resbut; // can be result from middle frame or bottom frame

std::wstring reskeylef;
std::wstring reskeymid;
std::wstring reskeybot;

//std::vector<std::wstring> destmp; // text displayed in front of the input field
//std::vector<std::wstring> namtmp; // name of variable for programming purpose (ID we fetch to get content)
//std::vector<std::wstring> deftmp; // default value (the fill will be pre filled with this value)
//std::vector<std::wstring> typtmp; // type of data: textbox password
//std::vector<std::wstring> errtmp; // text to display after the form "facultatif" blue text "error" red text are special keywords
//std::vector<std::wstring> buttmp; // ok and cancel (usually)

//STDMETHODIMP CEventHandler::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)

class CEventHandler : public IDispatch
{
public:
STDMETHODIMP QueryInterface(REFIID riid, void **ppvObject);
STDMETHODIMP_(ULONG) AddRef();
STDMETHODIMP_(ULONG) Release();

STDMETHODIMP GetTypeInfoCount(UINT *pctinfo);
STDMETHODIMP GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo);
STDMETHODIMP GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId);
STDMETHODIMP Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr);

CEventHandler(IHTMLWindow2 *pWindow2);

public:
LONG         m_cRef;
IHTMLWindow2 *m_pWindow2;
};
BOOL PutEventHandler(IHTMLDocument2 *pDocument2, IHTMLElement *pElement);
// ==================================
// MAIN
// ==================================
int _tmain(int argc, _TCHAR* argv[])
{
doevents();

// get console application handle to manage event in it
m_hWnd = FindWindow(NULL, L"ConsoleApplication1");

// IE 9.0.8112.16421: IEXPLORE.EXE
// Chrome 21.0.1180.60 m : Google Chrome
// Firefox 10.0.2 : FIREFOX.EXE
// Safari 3.2.2 : Safari.exe
// Opera 12.01 : Opera

// get default web browser path
std::string defaultbrowserpath01;
defaultbrowserpath01 = getdefaultbrowserpath();
//cout << defaultbrowserpath01;

HRESULT hr;
int dummy;

// these vectors contain data to dynamically generate buttons in left side frame
std::vector<std::wstring> arrbutnam; // name of button on left frame (also ID)
std::vector<std::wstring> arrbutdes; // description or caption
std::vector<std::wstring> arrdepnam; // sector (sectors have a space between them)
std::vector<std::wstring> arrdepcol; // button color of a sector

///////////////// project name
std::wstring project01 = L"test";

if (project01 == L"test")
{
// buttons specific to one project
arrbutnam.push_back(L"test");
arrbutdes.push_back(L"test button");
arrdepnam.push_back(L"TEST");
arrdepcol.push_back(L"cccccc");
}

// buttons in all of the project
arrbutnam.push_back(L"clrframes");
arrbutdes.push_back(L"Clear Frames");
arrdepnam.push_back(L"OTHER");
arrdepcol.push_back(L"cccccc");

arrbutnam.push_back(L"info");
arrbutdes.push_back(L"Information/Help");
arrdepnam.push_back(L"OTHER");
arrdepcol.push_back(L"cccccc");

arrbutnam.push_back(L"quit01");
arrbutdes.push_back(L"Quit");
arrdepnam.push_back(L"ALL");
arrdepcol.push_back(L"cccccc");

// create internet explorer windows and 3 frames: flef, fmid, fbot

dummy = create_web_main(&arrbutnam, &arrbutdes, &arrdepnam, &arrdepcol);

///////////////////////////////////////////////////////
// main LOOP
///////////////////////////////////////////////////////
//wcout <<L"\n\nwaiting for events, button click etc.";

// html form input parameters
std::vector<std::wstring> destmp; // description
std::vector<std::wstring> namtmp; // name of variable for programming purpose (ID we fetch to get content)
std::vector<std::wstring> deftmp; // default value (the fill will be pre filled with this value)
std::vector<std::wstring> typtmp; // type of data: textbox password
std::vector<std::wstring> errtmp; // text to display after the form "facultatif" blue text "error" red text are special keywords
std::vector<std::wstring> buttmp; // ok and cancel (usually)

do
{

if (resbutlef == L"test")
{
//Sleep(50);
clrfra(fmid);
clrfra(fbot);
resbutlef = L"";
resbutmid = L"";
resbutbot = L"";

dummy = writeln01(fbot, resbutlef);
dummy = writeln01(fbot, L"<br><br>");

// clear vectors
destmp.clear(); namtmp.clear(); deftmp.clear(); typtmp.clear(); errtmp.clear(); buttmp.clear();
// data to dynamically generate a input form
destmp.push_back(L"First name");
namtmp.push_back(L"text01");
deftmp.push_back(L"value 0");
typtmp.push_back(L"textbox");
errtmp.push_back(L"Enter first name please");

destmp.push_back(L"Last name");
namtmp.push_back(L"text02");
deftmp.push_back(L"value 1");
typtmp.push_back(L"textbox");
errtmp.push_back(L"Enter last name please");

buttmp.push_back(L"OK"); buttmp.push_back(L"Cancel");

std::wstring title01 = L"Test input";
// dynamic input form html generation
std::vector<std::wstring> results01; // will contain what is entered in html textboxes

results01 = dynforgen(fmid, &title01, &destmp, &namtmp, &deftmp, &typtmp, &errtmp, &buttmp);

if (resbut == L"OK")
{

clrfra(fmid);
for (int i = 0; i < results01.size(); i++)
{
dummy = writeln01(fbot, results01[i] + L"<br>");
}

dummy = writeln01(fbot, L"<br><br>FIN");
resbutlef = L"";
}
else
{
// cancel or a left button frame was pressed
clrfra(fmid);
// keep resbutlef with the value, so the action we did on left frame will execute in next loop
}
resbutmid = L"";
resbut = L"";
}

// common buttons
if (resbutlef == L"clrframes")
{
clrfra(fmid);
clrfra(fbot);
resbutlef = L"";
resbutmid = L"";
resbutbot = L"";
}

// info
if (resbutlef == L"info")
{
clrfra(fmid);
clrfra(fbot);
resbutlef = L"";
resbutmid = L"";
resbutbot = L"";

std::wstring arrhtm[] = {
L"INFORMATION / HELP",
L"SkynetCpp BETA",
L"2017-01-15",
L"-----",
L"Dynamic web interface to manage C++ programs",
L"By: sergefournier(@)hotmail.com",
L"Free to distribute",
L"----------",
L"Troubleshooting in visual studio 2013: in properties of the cpp console application, SELECT: use mfc in s shared DLL",
L"Troubleshooting in visual studio 2013 debug mode: copy this file near the .exe: mfc120ud.dll (windows 10)",
L""};

for (size_t i = 0; i < arrhtm[i].length(); i++)
{
dummy = writeln01(fbot, arrhtm[i]);
dummy = writeln01(fbot, L"<br>");
}

}
doevents();
} while (resbutlef != L"quit01");

// close internet explorer
//Sleep(50); // trying to prevent iexplore crash
pbrowser->Quit();
pbrowser->Release();

return 0;
}

IHTMLDocument2* gethtmele(IHTMLDocument2* phtmldoc2, std::wstring frame01)
{
// get frame object document to write in html frames
bool bSearch = true;
int hr;

// https://github.com/SeleniumHQ/selenium/blob/master/cpp/iedriver/DocumentHost.cpp
CComQIPtr<IHTMLFramesCollection2> frames;

hr = phtmldoc2->get_frames(&frames);
if (SUCCEEDED(hr) && (frames != NULL))
{
// get howmany frames
long length = 0;
hr = frames->get_length(&length);

if (SUCCEEDED(hr) && length > 0)
{
CComVariant frame_identifier = NULL;
frame_identifier = frame01.c_str();

CComVariant frame_holder = NULL;
hr = frames->item(&frame_identifier, &frame_holder);
if (SUCCEEDED(hr))
{
/// get frame content
IHTMLWindow2* interim_result;
hr = frame_holder.pdispVal->QueryInterface<IHTMLWindow2>(&interim_result);

if (SUCCEEDED(hr))
{
IDispatch* pIHTMLDoc;
hr = interim_result->get_document((IHTMLDocument2 **)&pIHTMLDoc);

if (SUCCEEDED(hr))
{
IHTMLDocument2* frameele = NULL;
hr = pIHTMLDoc->QueryInterface(IID_IHTMLDocument2, (void**)&frameele);
if (SUCCEEDED(hr))
{
//int dummy = writeln01(frameele, L"TEST222");
return frameele;
}
else
{
wcout << L"\n";
cout << "ERROR getting IHTMLDocument2";
}
}
else
{
wcout << L"\n";
cout << "ERROR getting pointer to IHTMLDocument2";
}
}
else
{
wcout << L"\n";
cout << "ERROR getting window pointer";
}
}
else
{
wcout << L"\n";
cout << "ERROR did not find any frame named: ";
wcout << frame01;
}
}
else
{
wcout << L"\n";
cout << "ERROR get_length(&length) - number of frames is 0)";
}
}
else
{
wcout << L"\n";
cout << "ERROR get_frames(&frames) - no frame collection found";
}

}
int create_web_main(std::vector<std::wstring>* arrbutnam,
std::vector<std::wstring>* arrbutdes,
std::vector<std::wstring>* arrdepnam,
std::vector<std::wstring>* arrdepcol)
{
// vector https://msdn.microsoft.com/en-us/library/9xd04bzs.aspx

int dummy;

//cout<< arrbutnam[0];

if (SUCCEEDED(OleInitialize(NULL)))
{
CoCreateInstance(CLSID_InternetExplorer, NULL, CLSCTX_LOCAL_SERVER, IID_IWebBrowser2, (void**)&pbrowser);
if (pbrowser)
{
VARIANT vEmpty;
VariantInit(&vEmpty);

BSTR bstrURL = SysAllocString(L"about:blank");

HRESULT hr = pbrowser->Navigate(bstrURL, &vEmpty, &vEmpty, &vEmpty, &vEmpty);
if (SUCCEEDED(hr))
{
pbrowser->put_Left(20);
pbrowser->put_Top(10);
pbrowser->put_Height(1000); // 1080
pbrowser->put_Width(1900); // 1920

int test = 0;
if (test == 1)
{
pbrowser->put_Left(700);
pbrowser->put_Top(10);
pbrowser->put_Height(1000); // 1080
pbrowser->put_Width(1200); // 1920

}

pbrowser->put_AddressBar(VARIANT_TRUE);
pbrowser->put_MenuBar(VARIANT_FALSE);
pbrowser->put_ToolBar(VARIANT_FALSE);
// pHtmlDoc->put_title(BSTR("SkyNet30"));
// pHtmlDoc->put_URL(BSTR("www.google.com"));
// pHtmlDoc->execCommand(BSTR("RELOAD"));
pbrowser->put_Visible(VARIANT_TRUE);

if (WaitTillLoaded(12)) /// wait 12 tick of 250 ms to expire
{
// printf("\nready in time");
HRESULT hr;
IDispatch* pHtmlDocDispatch = NULL;
pHtmlDoc = NULL;

// Retrieve the document object.
hr = pbrowser->get_Document(&pHtmlDocDispatch);
if (SUCCEEDED(hr) && (pHtmlDocDispatch != NULL))
{
hr = pHtmlDocDispatch->QueryInterface(IID_IHTMLDocument2, (void**)&pHtmlDoc);

if (SUCCEEDED(hr) && (pHtmlDoc != NULL))
{
//printf("\ngot a DOC");

// internet explorer interface will use 3 frames
std::wstring arrhtm[] = {
L"<HTML>",
L"<HEAD><TITLE>SkynetCPP</TITLE>",
L"<meta content=\"text/html; charset=utf-8\" http-equiv=\"Content-Type\">",
L"<meta http-equiv=\"X-UA-Compatible\" content=\"IE=8\">",
L"</HEAD>",
L"<FRAMESET id='main' COLS=\"13%, *\">",
L"<FRAME SRC=\"About:Blank\" NAME=\"flef\" id=\"flef\">",
L"<frameset id='main2' rows=\"30%,70%\">",
L"<FRAME SRC=\"About:Blank\" NAME=\"fmid\" id=\"fmid\">",
L"<FRAME SRC=\"About:Blank\" NAME=\"fbot\" id=\"fbot\">",
L"</FRAMESET>",
L"</frameset>",
L"</HTML>" };

for (size_t i = 0; i < arrhtm[i].length(); i++)
{
dummy = writeln01(pHtmlDoc, arrhtm[i]);
}

pbrowser->Refresh();

// IHTMLDocument2* flef;
flef = gethtmele(pHtmlDoc, L"flef");
//IHTMLDocument2* fmid;
fmid = gethtmele(pHtmlDoc, L"fmid");
//IHTMLDocument2* fbot;
fbot = gethtmele(pHtmlDoc, L"fbot");

/////////////////////////////// buttons generation (html) in left frame

std::wstring departement;
std::wstring lasdep;
std::wstring html;

for (int i = 0; i < (*arrbutnam).size(); i++)
{
html = L"<input type=\"button\" style=\"height:50px;font-size:14px;width:100%;white-space: normal;\" id=\"" + (*arrbutnam)[i] + L"\" name=\"" + (*arrbutnam)[i] + L"\" value=\"" + (*arrbutdes)[i] + L"\"";
int i2 = i;

if (i>(*arrdepnam).size())
i2 = (*arrdepnam).size();
else
departement = (*arrdepnam)[i2];

if (departement != lasdep)
{
lasdep = departement;
dummy = writeln01(flef, L"<br>" + departement + L"<br>");
}
html += L" style=\"background-color: #" + (*arrdepcol)[i2] + L"; color: #000000;\"><br>";
dummy = writeln01(flef, html);
}

// find input elements in frame
// define event for that button
bool success01 = FALSE;
IHTMLElement* pElem = NULL;
for (int i = 0; i < (*arrbutnam).size(); i++)
{
pElem = findhtmlelement(flef, L"INPUT", (*arrbutnam)[i]);
success01 = PutEventHandler(flef, pElem);
//wcout << "event ";
}

//OleUninitialize(); // cant do that, or event stop working
return 0;
} // hr = pHtmlDocDispatch->QueryInterface(IID_IHTMLDocument2
} // hr = pbrowser->get_Document(&pHtmlDocDispatch);
} // waittill loaded (not always working)
} // HRESULT hr = pbrowser->Navigate(
} //CoCreateInstance(CLSID_InternetExplorer
//OleUninitialize();
}
else
{
// oleinitialize failed
wcout << L"\n";
wcout << L"failed ole initialize";
}
}

// GOOD FULL CODE
// http://eternalwindows.jp/browser/mshtml/mshtml07.html
CEventHandler::CEventHandler(IHTMLWindow2 *pWindow2)
{
m_cRef = 1;
m_pWindow2 = pWindow2;
}

STDMETHODIMP CEventHandler::QueryInterface(REFIID riid, void **ppvObject)
{
*ppvObject = NULL;

if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IDispatch))
*ppvObject = static_cast<IDispatch *>(this);
else
return E_NOINTERFACE;

AddRef();

return S_OK;
}

STDMETHODIMP_(ULONG) CEventHandler::AddRef()
{
return InterlockedIncrement(&m_cRef);
}

STDMETHODIMP_(ULONG) CEventHandler::Release()
{
if (InterlockedDecrement(&m_cRef) == 0) {
delete this;
return 0;
}

return m_cRef;
}

STDMETHODIMP CEventHandler::GetTypeInfoCount(UINT *pctinfo)
{
*pctinfo = 0;

return S_OK;
}

STDMETHODIMP CEventHandler::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
{
return E_NOTIMPL;
}

STDMETHODIMP CEventHandler::GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
{
return E_NOTIMPL;
}

STDMETHODIMP CEventHandler::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
// event called when you press a html input button in html frame
BSTR          bstr;
IHTMLEventObj *pEventObj;
IHTMLElement  *pElement;
BSTR id01;
BSTR frame02;
std::wstring frame11;

m_pWindow2->get_event(&pEventObj);
pEventObj->get_srcElement(&pElement);
pElement->get_tagName(&bstr);
pElement->get_id(&id01); // name of button that was pressed
m_pWindow2->get_name(&frame02);

frame11 = frame02;

//wcout<< frame01;

//MessageBoxW(NULL, bstr, L"bouton presse", MB_OK);

//BSTR to std::wstring:
// given BSTR bs
assert(id01 != nullptr);
std::wstring ws(id01, SysStringLen(id01));

//std::wstring to BSTR :
// given std::wstring ws
//assert(!ws.empty());
//BSTR bs = SysAllocStringLen(ws.data(), ws.size());

//MessageBox(NULL, TEXT("test"), TEXT("OK"), MB_OK);
if (frame11 == L"flef")
resbutlef = id01;
if (frame11 == L"fmid")
resbutmid = id01;
if (frame11 == L"fbot")
resbutbot = id01;

SysFreeString(bstr);
pElement->Release();
pEventObj->Release();

return S_OK;
}
void doevents()
{
MSG Msg;
BOOL bRet;
//HICON
//analog DoEvents() v VB
if (PeekMessage(&Msg, m_hWnd, 0, 0, PM_NOREMOVE))
{
if ((bRet = GetMessage(&Msg, m_hWnd, 0, 0)))
DispatchMessage(&Msg);
}
}
BOOL PutEventHandler(IHTMLDocument2* pDocument2, IHTMLElement* pElement)
{
// generate event handler associated with a html button in internet explorer frame

//wcout << L"\nstart puteventhandler";

//BSTR           bstrId;
VARIANT        var;
//IHTMLElement   *pElement;
//IHTMLDocument2 *pDocument2;
IHTMLWindow2   *pWindow2;
HRESULT hr;
IHTMLDocument3* pDocument3;

// bstrId = SysAllocString(L"test");
//hr = pDocument3->getElementById(bstrId, &pElement);

hr = pDocument2->QueryInterface(IID_PPV_ARGS(&pDocument3));
if (SUCCEEDED(hr) && pDocument3 != NULL)
{
//pDocument3->QueryInterface(IID_PPV_ARGS(&pDocument2));
hr = pDocument2->get_parentWindow(&pWindow2);
if (SUCCEEDED(hr) && pWindow2 != NULL)
{
var.vt = VT_DISPATCH;
var.pdispVal = new CEventHandler(pWindow2);
if (pElement != NULL)
{
hr = pElement->put_onclick(var);
if (SUCCEEDED(hr))
{
//MessageBox(NULL, TEXT("test"), TEXT("OK"), MB_OK);

//SysFreeString(bstrId);
var.pdispVal->Release();
pWindow2->Release();
//pDocument2->Release();
pElement->Release();

return TRUE;
}
else
{
wcout << L"\nERROR PutEventHandler event not defined";
return FALSE;
}
}
else
{
wcout << L"\nERROR PutEventHandler pElement is NULL";
return FALSE;
}


}
else
{
wcout << L"\nERROR PutEventHandler getting pWindow2";
return FALSE;
}
}
else
{
wcout <<L"\nERROR PutEventHandler IHTMLDocument3";
return FALSE;
}
}


IHTMLElement* findhtmlelement(IHTMLDocument2 *fra, std::wstring type01, std::wstring name01)
{
bool bSearch = true;
HRESULT hr;

// scan doc object collection in html document
IHTMLElementCollection* pColl = NULL;
hr = fra->get_all(&pColl);
if (SUCCEEDED(hr) && (pColl != NULL))
{
// Obtained the Anchor Collection...
long nLength = 0;
pColl->get_length(&nLength);

for (int i = 0; i < nLength && bSearch; i++)
{
COleVariant vIdx((long)i, VT_I4);
IDispatch* pElemDispatch = NULL;
IHTMLElement * pElem = NULL;

hr = pColl->item(vIdx, vIdx, &pElemDispatch);

if (SUCCEEDED(hr) && (pElemDispatch != NULL))
{
hr = pElemDispatch->QueryInterface(IID_IHTMLElement, (void**)&pElem);

if (SUCCEEDED(hr) && (pElem != NULL))
{
BSTR bstrTagName;
std::wstring sTempTagName = L"";
hr = pElem->get_tagName(&bstrTagName);
if (SUCCEEDED(hr) && (bstrTagName != NULL))
{

// conversion error
sTempTagName = bstrTagName;
//SysFreeString(bstrTagName);

BSTR bstrtagid = NULL;
hr = pElem->get_id(&bstrtagid);
if (bstrtagid != NULL)
{

std::wstring stemptagid = L"";

stemptagid = bstrtagid;

if ((sTempTagName == type01) && (stemptagid == name01))
{
//wcout << L"\n Type wanted: ";
//wcout << type01;
//wcout << L"   Name wanted: ";
//wcout << name01;

//pElemDispatch->Release();
return pElem;
}
} // get_id(&bstrtagid) (id of button)
} // if get_tagname
} //if (SUCCEEDED(hr) && (pElem != NULL))
} //if (SUCCEEDED(hr) && (pElemDispatch != NULL))
} //for (int i = 0; i < nLength && bSearch; i++)
} //if (SUCCEEDED(hr) && (pColl != NULL))
}

std::string getdefaultbrowserpath()
{
// get executable path to defaut browser (not working very well in windows 10)
// modified from http://www.codeproject.com/internet/urlnewwindow.asp
std::string page;
std::wstring wstrBrowser01;
std::string str01;

HKEY hKey = NULL;

// get defaut internet browser
if (RegOpenKeyEx(HKEY_CLASSES_ROOT, TEXT("http\\shell\\open\\command"), 0, KEY_READ, &hKey) == ERROR_SUCCESS)
{
DWORD cbData = 0;
if (RegQueryValueEx(hKey, NULL, NULL, NULL, NULL, &cbData) == ERROR_SUCCESS && cbData > 0)
{
// command key is present
TCHAR* browsername01 = new TCHAR[cbData];
if (browsername01 != NULL)
{

if (RegQueryValueEx(hKey, NULL, NULL, NULL, (LPBYTE)browsername01, &cbData) == ERROR_SUCCESS)
//if (RegQueryValueEx(hKey, NULL, NULL, NULL, reinterpret_cast<LPBYTE>(&browsername01[0]), &cbData) == ERROR_SUCCESS)
{
wstrBrowser01 = browsername01;
// wcout << wstrBrowser01;
}
delete[] browsername01;
}
}
RegCloseKey(hKey);
}
else
{
//printf("\r\nERROR could not read regkey");
}

// get path of executable and remove stuff around it
if (wstrBrowser01.length() > 0)
{
std::string::size_type nStart = wstrBrowser01.find('"', 0);

// if first is a quote, then exe path is in quotes, so find the second quote
if (nStart == 0)
{
std::string::size_type nEnd = wstrBrowser01.find('"', 1);
if (nStart != nEnd && nEnd != std::string::npos)
{
wstrBrowser01 = wstrBrowser01.substr(nStart + 1, nEnd - nStart - 1);
}
}
// otherwise if no quotes, 2nd point is the first space after the last backslash
else
{
std::string::size_type nIndex = wstrBrowser01.rfind('\\', wstrBrowser01.length() - 1);
if (nIndex != std::string::npos)
{
std::string::size_type nSpace = wstrBrowser01.find(' ', nIndex);
if (nSpace != std::string::npos)
{
wstrBrowser01 = wstrBrowser01.substr(0, nSpace);
}
}
}

std::wstring wcommand01 = L"\"";
wcommand01 += wstrBrowser01;
wcommand01 += L"\"";
std::string arg01 = "\"";
arg01 += "www.google.ca";
arg01 += "\"";

std::string command01(wcommand01.begin(), wcommand01.end());

//printf("\n");
//printf("default browser: ");
//printf(command01.c_str());

// HINSTANCE hinst01 = ShellExecuteW(NULL, L"open", LPCWSTR(wcommand01.c_str()), NULL, NULL, SW_HIDE);
//HINSTANCE hinst01 = ShellExecuteA(NULL, "Open", LPCSTR(command01.c_str()), LPCSTR(arg01.c_str()), NULL, 3);
//printf("\n");
//cout << hinst01;

// link handle to application

// COleVariant loc(L"about:blank");
// m_explorer.Navigate2("about:blank", NULL, NULL, NULL, NULL);
// IDispatch* pHtmlDoc = m_explorer.get_Document();
return command01.c_str();
}
else
{
//printf("\r\n\r\nERROR strBrowser01.length is 0");


}
}


int writeln01(IHTMLDocument2* phtmldoc1, std::wstring string01)
{
// write wstring to a html frame
SAFEARRAYBOUND bounds[] = { { 1, 0 } }; //Array Contains 2 Elements starting from Index ‘0’
SAFEARRAY* safearray01 = SafeArrayCreate(VT_VARIANT, 1, bounds); //Create a one-
long lIndex[1];
VARIANT var;
lIndex[0] = 0; // index of the element being inserted in the array
var.vt = VT_BSTR; // type of the element being inserted

//var.bstrVal = ::SysAllocStringLen(L"<br>The<br>First String", 16); // the value of the element being inserted
var.bstrVal = ::SysAllocStringLen(string01.c_str(), string01.length()); // the value of the element being inserted
HRESULT hr = SafeArrayPutElement(safearray01, lIndex, &var); // insert the element
//if (WaitTillLoaded(0)== TRUE)
//{
phtmldoc1->writeln(safearray01);
//}

return 0;
}

bool WaitTillLoaded(int nTimeout)
{
// wait till internet explorer is ready to receive stuff
READYSTATE result;
DWORD nFirstTick = GetTickCount();

do
{
pbrowser->get_ReadyState(&result);

if (result != READYSTATE_COMPLETE)
{
Sleep(100);
}
if (nTimeout > 0)
{
if ((GetTickCount() - nFirstTick) > nTimeout)
{
break;
}
}
} while (result != READYSTATE_COMPLETE);

if (result == READYSTATE_COMPLETE)
{
//cout << "true";
return TRUE;
}
else
{
//cout << "false";
return FALSE;
}
}

std::vector<std::wstring> dynforgen(IHTMLDocument2* fra, std::wstring *title01,
std::vector<std::wstring>* destmp,
std::vector<std::wstring>* namtmp,
std::vector<std::wstring>* deftmp,
std::vector<std::wstring>* typtmp,
std::vector<std::wstring>* errtmp,
std::vector<std::wstring>* buttmp)
{
std::vector<std::wstring> olderrtmp;
olderrtmp = (*errtmp);

// html content
int dummy;
int deffoc;
std::wstring col;
std::wstring type01;
std::wstring wname01;
std::string name01;
IHTMLWindow2 *window01;
BSTR framename01;
std::wstring wframename01;
BSTR text01;
std::wstring wvalue01;
std::vector<std::wstring> results01;

// get windows of the frame document
fra->get_parentWindow(&window01);
// get frame name to be able to manage any button pressed if the bottom or mid frame is used
window01->get_name(&framename01);
wframename01 = framename01;

// do all the input process with inner html
IHTMLElement *p = NULL;
// get inner html body
fra->get_body(&p);
if (p)
{
BOOL valid01 = FALSE;
resbut = L"";
do
{
//wcout<< L"\n restarting inputs";

clrfra(fra); // clear frame

std::wstring h = L"";

// title with bigger letters
h = L"<h3><span class=SpellE>" + *title01 + L"</span></h3>";

for (int i = 0; i < (*destmp).size(); i++)
{
// focus on first empty field
deffoc = 0;
if ((*deftmp)[i] == L"")
{
if ((*errtmp)[i] != L"falcultatif")
{
h += L"<BODY onLoad=\"document.form01." + (*namtmp)[i] + L".focus()\">";
deffoc = 1;
}
}
}

if (deffoc == 0)
{
// if no empty field just focus on first element
h += L"<BODY onLoad=\"document.form01." + (*namtmp)[0] + L".focus()\">";
}

h += L"<div class=MsoNormal align=center style='text-align:center'>";
h += L"</div>";

h += L"<form name=form01>";

for (int i = 0; i < (*namtmp).size(); i++)
{
h += (*destmp)[i] + L": ";

h += L"<input type=\"" + (*typtmp)[i] + L"\" ";
h += L"id=" + (*namtmp)[i] + L" ";
h += L"NAME=\"" + (*namtmp)[i] + L"\" ";
h += L"size=\"" + (*deftmp)[i] + L"\" ";
h += L"value=\"" + (*deftmp)[i] + L"\" ";
h += L"onKeypress=\"return event.keyCode!=13\"";

if ((*errtmp)[i].find(L"ERROR"))
col = L"blue";
else
col = L"red";
h += L"&nbsp; <b><span style='color:" + col + L"'>&nbsp" + (*errtmp)[i] + L"</span></b><br style='mso-special-character:line-break'>";
}
h += L"<![if !supportLineBreakNewLine]><br style='mso-special-character:line-break'>";
h += L"<![endif]></p>";

for (int i = 0; i < (*buttmp).size(); i++)
{
// ok button and cancel button
type01 = L"button";
h += L"<input type=\"" + type01 + L"\" id=\"" + (*buttmp)[i] + L"\" name=\"" + (*buttmp)[i] + L"\" ";
h += L"value=\"&nbsp;" + (*buttmp)[i] + L"&nbsp;\">";
h += L"&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp";
//html = L"<input type=\"button\" style=\"height:50px;font-size:14px;width:100%;white-space: normal;\" "
//"id=\"" + arrbutnam[i] + L"\" name=\"" + arrbutnam[i] + L"\" value=\"" + arrbutdes[i] + L"\"";
}

h += L"</div>";
h += L"</form>";
h += L"</body>";
h += L"</html>";

h += L"";

//std::wstring to BSTR //given std::wstring h
BSTR bs = SysAllocStringLen(h.c_str(), h.size());
p->put_innerHTML(bs);

// define events for OK and Cancel buttons
for (int i = 0; i < (*buttmp).size(); i++)
{
bool success01 = FALSE;
IHTMLElement* pElem = NULL;
//wcout << L"\n" + buttmp[i];

pElem = findhtmlelement(fra, L"INPUT", (*buttmp)[i]);
success01 = PutEventHandler(fra, pElem);

}

// wait for ok, cancel or anything on left frame to exit this section
if (wframename01 == L"fmid")
{
resbutmid = L"";
reskeymid = L"";
}
if (wframename01 == L"fbot")
{
resbutbot = L"";
reskeybot = L"";
}
do
{
// the form can be in two frames, so we get button result from any and put it in a generic button variable
doevents();
if (wframename01 == L"fmid")
resbut = resbutmid;
if (wframename01 == L"fbot")
resbut = resbutbot;

//wcout <<L"\n resbutlef: ";
Sleep(50);
// loop until ok or cancel os pressed OR a button in left menu is used to exit the input sequence
} while ((resbut != L"Cancel") && (resbut != L"OK") && (resbutlef.size() == 0));

doevents();

// get value entered in web form and put them in a vector as strings
if ((resbut != L"Cancel") && (resbutlef.size() == 0))
{

type01 = L"INPUT";
// result vector wstring
results01.clear();
int validcnt01 = 0;

for (int i = 0; i < (*namtmp).size(); i++)
{
wname01 = (*namtmp)[i];
// pelem = findhtmlelement(fra, type01, name01);

// convert wstring to BSTR
//assert(!wname01.empty());
BSTR bstrname01 = NULL;
bstrname01 = SysAllocStringLen(wname01.c_str(), wname01.size());

// get inputtext html elements (textbox) element by name
IHTMLInputTextElement* peleminput = NULL;

//_variant_t varName(bstrname01); // textbox id / name
//_variant_t varIdx(0L);
// change to:
//COleVariant vIdx((long)i, VT_I4);
COleVariant varName(bstrname01); // textbox id / name
COleVariant varIdx(0L);
HRESULT hr;
IDispatch* pElemDisp = NULL;

IHTMLElementCollection* pcoll = NULL;
hr = fra->get_all(&pcoll);
if (SUCCEEDED(hr) && (pcoll != NULL))
{
hr = pcoll->item(varName, varIdx, &pElemDisp);
if (SUCCEEDED(hr) && (pElemDisp != NULL))
{
// get inputtext html elements (textbox) content
hr = pElemDisp->QueryInterface(IID_IHTMLInputTextElement, (void**)&peleminput);
if (SUCCEEDED(hr))
{
peleminput->get_value(&text01);
if (text01 != NULL)
{
wvalue01 = text01; // convert to wstring
validcnt01++; // result is longer than 1 char, so it is probably valid
(*errtmp)[i] = olderrtmp[i]; //put initial text
}
else
{
wvalue01 = L"";
(*errtmp)[i] = L"ERROR must enter one character";
}
results01.push_back(wvalue01);
(*deftmp)[i] = wvalue01;
}
}
}
}

// validate all results must be at least 1 char long
//errtmp[i] ERROR text must be in it to be RED

if (validcnt01 == (*namtmp).size())
valid01 = TRUE;
else
valid01 = FALSE;
//wcout <<L"\n";
//wcout << validcnt01;
}
doevents();
} while ((valid01 == FALSE) && (resbut != L"Cancel") && (resbutlef.size() == 0)); // validate the string, if not valid, remake form and input again
doevents();
} // get body

// reset button and keys states
if (wframename01 == L"fmid")
{
resbutmid = L"";
reskeymid = L"";
}

if (wframename01 == L"fbot")
{
resbutbot = L"";
reskeybot = L"";
}

return results01;
}


void clrfra(IHTMLDocument2 *fra)
{
// clear bottom html frame
BSTR bstrContent = NULL;
IHTMLElement *p = NULL;

fra->get_body(&p);
int ii = 20;
if (p)
{

do
{
doevents();

try
{
p->put_innerHTML(L"");
//p->get_innerHTML(&bstrContent);
ii = 0;
}
catch (int e)
{
Sleep(50);
ii--;
}
} while (ii > 0);
p->Release();
}
}