Attribute VB_Name = "MSAMain"
' UNICOM Systems Confidential
'
' MSAMain.bas - SA2001
'
' (c) Copyright UNICOM Systems 2009, 2019.  All Rights Reserved.

Option Explicit

' **** DEBUGGING NOTE - COMMENT OUT THE 'END' BELOW TO DEBUG WITHIN VISUAL BASIC ****
' ****                - It is commented with the same comment as above           ****

Public Declare Function SetBkColor Lib "gdi32" (ByVal hDC As Long, ByVal crColor As Long) As Long
Public Declare Function SetBkMode Lib "gdi32" (ByVal hDC As Long, ByVal nBkMode As Long) As Long
Public Declare Function CreatePen Lib "gdi32" (ByVal nPenStyle As Long, ByVal nWidth As Long, ByVal crColor As Long) As Long
Public Declare Function CreateSolidBrush Lib "gdi32" (ByVal crColor As Long) As Long
Public Declare Function SelectObject Lib "gdi32" (ByVal hDC As Long, ByVal hObject As Long) As Long
Public Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
Public Declare Function Rectangle Lib "gdi32" (ByVal hDC As Long, ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long


' slightly bigger than normal, not sure why just used the same value as in sadlg
Public Const MAX_PATH = 500
Public Const TOOLBARVERSION = 5    ' Up this version number if you want to force a toolbar file update

' Hardcoded theme settings for docking and toolbar system
Public Const DOCKINGTHEME = ThemeVisualStudio2005 ' ThemeOffice2003 no longer have buttons
Public Const TOOLBARTHEME = xtpThemeOffice2003 ' xtpThemeVisualStudio2008 ' xtpThemeOffice2003 ' appears blue; Office 2016 is grey but has a black status
Public Const TOOLBARANIMATION = xtpAnimateNone

' Pane IDs for docking system
' Tag format :-
'-   YYYY XXXX
'-   X's are numeric type identifier
'-   Y's are bit flags  (such as reuse this pane)
'-   X values (TAGIDs) :-
Public Const SADOCK_TAGID_NONE = 0             ' May be useful in the future
Public Const SADOCK_TAGID_DETAIL = 1           ' The Browser details (Properties pane)
Public Const SADOCK_TAGID_BROWSE = 2           ' The main browser (Explorer pane)
Public Const SADOCK_TAGID_FDISPLAY = 3         ' An frmDisplay pane (log window)
Public Const SADOCK_TAGID_FRAMEWORKGRID = 4    ' The framework grid
Public Const SADOCK_TAGID_FWK_BROWSER = 5      ' A Framework mini browser
Public Const SADOCK_TAGID_FWK_MTXBROWSER = 6   ' A Framework mini matrix browser
Public Const SADOCK_TAGID_FRAMEWORKEDIT = 7    ' The framework editor
Public Const SADOCK_TAGID_MATRIXBROWSER = 8    ' The matrix browser
Public Const SADOCK_TAGID_PICBROWSE = 9        ' The picture browser
Public Const SADOCK_TAGID_NEW_BROWSE = 10      ' The new main browser
Public Const SADOCK_TAGID_OBJECTHISTORY = 11   ' Object HISTORY
Public Const SADOCK_TAGID_DGMVISMGR = 12       ' Diagram Visualization manager
Public Const SADOCK_TAGID_FRMDGMPREVIEW = 13   ' Diagram Preview Pane
Public Const SADOCK_TAGID_REFERENCEBY = 14     ' Main References pane
Public Const SADOCK_TAGID_2NDREFERENCEBY = 15  ' References pane opened from main / other References pane

Public Const SADOCK_TAGID_USERDOCK = 100       ' An item unknown to SA - assume this is a user item
Public Const SADOCK_TAGID_USERBASE = 5000      ' The base for user dock TAGIDs    - Users see it as 1
Public Const SADOCK_TAGID_USERCEILING = 19999  ' ceiling for the user dock TAGIDs - Users see it as 15000

Public Const NEXTAVAILABLEDOCKIDSTART = 1
Public Const NEXTAVAILABLEDOCKIDEND = 32767

' THE FOLLOWING DECLARES ARE TEMPORARY AND SHOULD BE MOVED TO SAOBJX OR ISAIMF CALLS
Public Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long 'DEV_STRING
Public Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Long) As Long 'DEV_STRING
Public Declare Function FindWindowExNoClass Lib "user32" Alias "FindWindowExA" (ByVal hWndParent As Long, ByVal hwndChildAfter As Long, ByVal UseZero As Long, ByVal lpszWindow As String) As Long 'DEV_STRING

#If BIDI_DISABLED = False Then
' Use SAAppObj.ConvertFromLeftToRight

Public Const CONTEXTUAL_TEXT_DIRECTION = 3
Public Const RTL_TEXT_DIRECTION = 2
Public Const LTR_TEXT_DIRECTION = 1
#End If

Public Const HH_HELP_CONTEXT = &HF
Public Const HH_DISPLAY_TOPIC = 0

Public Const LOGMENUOPERATION = &H1     ' This is a menu operation
Public Const LOGBROWSEROPERATION = &H2  ' This is a browser operation
Public Const LOGOPERATIONSTART = &H100  ' Entering operation
Public Const LOGOPERATIONEND = &H200    ' Leaving operation
Public Const LOGGENERALOPERATION = &H4  ' General operation

' The following are windows api declares - These are OK
Public Declare Function OleCreatePictureIndirectMeta Lib "olepro32.dll" Alias "OleCreatePictureIndirect" (lpPictDesc As PICTDESCMETA, riid As GUID, ByVal fPictureOwnsHandle As Long, ipic As IPicture) As Long 'DEV_STRING
Public Declare Function OleCreatePictureIndirectBmp Lib "olepro32.dll" Alias "OleCreatePictureIndirect" (lpPictDesc As PICTDESCBMP, riid As GUID, ByVal fPictureOwnsHandle As Long, ipic As IPicture) As Long 'DEV_STRING
Public Declare Function MyCallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long 'DEV_STRING
Public Declare Function MyPostMessage Lib "user32" Alias "PostMessageA" (ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long 'DEV_STRING
Public Declare Function RegisterClipboardFormat Lib "user32.dll" Alias "RegisterClipboardFormatA" (ByVal lpszformat As String) As Integer 'DEV_STRING
Public Declare Function MySetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Long, ByVal lpfn As Long, ByVal hMod As Long, ByVal dwThreadId As Long) As Long 'DEV_STRING
Public Declare Function MyUnHookWindowsHookEx Lib "user32" Alias "UnhookWindowsHookEx" (ByVal hHook As Long) As Long 'DEV_STRING
Public Declare Function MyCallNextHookExMsg Lib "user32" Alias "CallNextHookEx" (ByVal hHk As Long, ByVal nCode As Long, ByVal wParam As Long, ByRef lParam As msg) As Long 'DEV_STRING
Public Declare Function MyCallNextHookExMsg2 Lib "user32" Alias "CallNextHookEx" (ByVal hHk As Long, ByVal nCode As Long, ByVal wParam As Long, ByRef lParam As mousemsg) As Long 'DEV_STRING
Public Declare Function MyCallNextHookExCWPSTRUCT Lib "user32" Alias "CallNextHookEx" (ByVal hHk As Long, ByVal nCode As Long, ByVal wParam As Long, ByRef lParam As CWPSTRUCT) As Long 'DEV_STRING
Public Declare Function MyCallNextHookExLong Lib "user32" Alias "CallNextHookEx" (ByVal hHk As Long, ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long 'DEV_STRING
Public Declare Function MyGetDlgItemText Lib "user32" Alias "GetDlgItemTextA" (ByVal hDlg As Long, ByVal nIDDlgItem As Long, ByVal lpString As String, ByVal nMaxCount As Long) As Long 'DEV_STRING
Public Declare Function MyGetCurrentThreadID Lib "kernel32" Alias "GetCurrentThreadId" () As Long 'DEV_STRING
Public Declare Sub CopyMem Lib "kernel32" Alias "RtlMoveMemory" (lpvDest As Any, lpvsource As Any, ByVal cbcopylength As Long) 'DEV_STRING
Public Declare Function lstrlenptr Lib "kernel32" Alias "lstrlenA" (p As Long) As Long 'DEV_STRING
Public Declare Function SendMessageLong Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long 'DEV_STRING
Public Declare Function GetDeviceCaps Lib "gdi32" (ByVal hDC As Long, ByVal lWhat As Long) As Long 'DEV_STRING
Public Declare Function GetVersionExA Lib "kernel32" (lpVersionInformation As OSVERSIONINFO) As Integer
Public Declare Function SetWindowLong Lib "user32" Alias _
   "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, _
   ByVal dwNewLong As Long) As Long
 
Public Declare Function CallWindowProc Lib "user32" _
   Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, _
   ByVal hWnd As Long, ByVal msg As Long, ByVal wParam As Long, _
   ByVal lParam As Long) As Long

Public Const GWL_WNDPROC = (-4)
Private Const WM_MOVE = &H3

Public Const WM_CONTEXTMENU = &H7B


Public Type OSVERSIONINFO
   dwOSVersionInfoSize As Long
   dwMajorVersion As Long
   dwMinorVersion As Long
   dwBuildNumber As Long
   dwPlatformId As Long
   szCSDVersion As String * 128
End Type


Global Const NONMODAL_WHILSTMODAL_ERROR = 401

' Listview constants
Global Const LVM_SETCOLUMNWIDTH = 4126
Global Const LVSCW_AUTOSIZE = -1
Global Const LVM_REDRAWITEMS = 4117

Public Declare Function MyGetFreeSystemResources Lib "rsrc32" Alias "_MyGetFreeSystemResources32@4" (ByVal iResource As Integer) As Integer 'DEV_STRING
Public Const GFSR_GDIRESOURCES = &H1
Public Const GFSR_SYSTEMRESOURCES = &H0
Public Const GFSR_USERRESOURCES = &H2

Public Declare Function GetGuiResources Lib "user32" (ByVal hProcess As Long, ByVal uiFlags As Long) As Long 'DEV_STRING
Public Const GR_GDIOBJECTS = 0          ' /* Count of GDI objects */
Public Const GR_USEROBJECTS = 1        ' /* Count of USER objects */

Public Const WH_MSGFILTER = -1
Public Const WH_KEYBOARD = 2
Public Const WH_GETMESSAGE = 3
Public Const WH_CALLWNDPROC = 4
Public Const HC_ACTION = 0
Public Const HC_NOREMOVE = 3
Public Const MSGF_DIALOGBOX = 0
Public Const MSGF_MENU = 2
Public Const PM_NOREMOVE = &H0
Public Const PM_REMOVE = &H1
Public Const PM_NOYIELD = &H2

Public Const XMLPARSEERROR = 1  ' vbObjectError constant for our saxmlx parser

'max limit of view browsers
Public Const MAX_VIEW_BROWSER = 20

Public Const SASDELETEOBJECT_FLAGS_NOUI = 1
Public Const SASDELETEOBJECT_FLAGS_MULTIPLE = 2

Public hDialogMessageHook As Long
Public hSendMessageHook As Long
Public hPostMessageHook As Long
Public hKeyboardMessageHook As Long
Public hCBTMessageHook As Long
Public hMouseMessageHook As Long

Public g_bNoAutoRefresh As Boolean 'no autorefresh when the encyclopedia is reopened or created
Public g_blnShowHiddenTools As Boolean  ' If set true all hidden tools are displayed in customzation
Public g_strVersion As String           ' The application version number - used by the toolbar
Private Const MAINOK = 0
Private Const MAINERR = 1
Private Const MAINEND = 2

' Used by FBrowserTabConfig.frm
Public gEncyBrowserTabsFileKnown As Boolean
Public gEncyBrowserTabsFileExists As Boolean
Public gEncyBrowserTabsTempFileName As String
Public gContentsChanged As Boolean
Public gCurrentActiveXMLFile As String
Public gEntireXMLFile As DOMDocument

Public m_blnLastKeyWasEaten As Boolean  ' For the Keyboard hook fudge

' Used by FGenericMDI and the menus for the Matrix editor
Public g_objCurrentMatrix As Object
' Used by FGenericMDI and the menus for the TAU editor
Public g_objCurrentTAU As Object
Public g_lngTAUddid As Long

' Used by MDIChild_ActivateDeactivateTests...
Public g_objLastActiveMDIForm As Object
Public g_objLastActiveDiagram As Object
Public g_hLastActiveDiagram As Long ' imf dgm hdl
Public g_objLastActiveWindow As Object
Public g_frmWithFocus As Form

' Used by MetaItem
Public g_strDgmSymConnTuplesStatusPrefix As String
Public g_colstrxmlDgmSymConnTuples As Collection

Public g_HMM_TaskPanel_NoAnim As Boolean

Type POINTAPI
        X As Long
        y As Long
End Type

Public Type GUID
   Data1 As Long
   Data2 As Integer
   Data3 As Integer
   Data4(7) As Byte
End Type

Type msg
    hWnd As Long
    message As Long
    wParam As Long
    lParam As Long
    time As Long
    pt As POINTAPI
End Type

Type mousemsg
    pt As POINTAPI
    hWnd As Long
    wHitTestCode As Long
    dwExtraInfo As Long
    dwMouseData As Long ' ref MOUSEHOOKSTRUCTEX; contains MOUSEHOOKSTRUCT which is the above, with this on the end
End Type

Type mousemsgll
    pt As POINTAPI
    mousedata As Long
    Flags As Long
    wHitTestCode As Long
    dwExtraInfo As Long
End Type

Public Type CWPSTRUCT
    lParam As Long
    wParam As Long
    message As Long
    hWnd As Long
End Type

Public Const SAMAXFONTNAMELEN = 1000

Public Const MAX_NAME_LENGTH = 81
Public Const MINFORMSIZE = 1000
Public Const MINRESIZESIZE = 50
Public Const MAXMETRICFIELD = 4000
Public Const MAXMEMO = 32768
Public Const MAXNAME = 81
Public Const MAXTYPENAME = 129
Public Const MAXPATH = 257
Public Const MAX_CONNECT_STRING = 1024
Public Const MAXPROPERTYNAME = 127 ' keep in synch with constant in design.h
Public Const MAXCONTROLLEGEND = 255     ' keep in synch with constant in design.h

' XML import collision options (copied from PortData.c)
Public Const OVERLAY_NEVER = 0
Public Const OVERLAY_RECORD = 1
Public Const OVERLAY_FIELD_IFDATA = 2
Public Const OVERLAY_FIELD_CLEAROK = 3

' Permission error types
Public Const PER_ERR_SUCCESS = 0      ' Success
Public Const PER_ERR_NOSUCHTYPE = 1   ' The type specified was not in the acceptable range of known types
Public Const PER_ERR_NOTFOUND = 2     ' No permission with the ID given was found in that type
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Public procOld As Long
Public SAShMenu As Long
Public InterceptCommandMessages As Boolean
Public Const MAXCOMMANDMESSAGE = 15000&
Public IgnorePaintMessages As Boolean
Public CurrentActiveBrowserTab As Long

Public VersionString As String
Public CommandLine As String         ' command line we pass to sadesign

Public CmdLineLog As Boolean
'Public CmdLineFlog As Boolean
Public CmdLineNoMenu As Boolean ' do not use the sheridan toolbar menu diddling
Public CmdLineTestMode As Boolean
Public CmdLineDgmActivate As Boolean
Public CmdLineNoRedraw As Boolean
Public CmdLineNoMenuTimer As Boolean
Public CmdLineNoUserMsg As Boolean
Public CmdLineTiming As Boolean
Public CmdBatchFile As Boolean
Public BatchFile As String
Public CmdLineNoOMStatusChecks As Boolean
Public CmdLineToolCheck As Boolean
Public CmdLineQAReporting As Boolean

Public CmdWSEnabled As Boolean
Public CmdLineRWSAMacros As Boolean
Public CmdLineMacroGen As Boolean ' Generate default event macros from files if not present.
Public CmdLineDDLGen As Boolean ' Generate default table and proc DDL.
Public CmdLineAllowDbase As Boolean ' Allow user to open dBase encyclopedias
Public CmdLineOracleVersion As Boolean ' Allow Oracle encyclopedias
Public CmdLinebADORepo As Boolean ' Temporary flag to allow ado and ui changes to be switch on
Public CmdLineMenuTestMode As Boolean ' -menutest used to test menu decoupling
Public CmdLineAutoLoadgen As Boolean ' start loadgen after ency open
Public blnCmdLinePermMapGen As Boolean  ' Destroy then Create ency on server specified in sa2001.ini to create default permission map for the Catalog Manager based on the default property set to be supplied with the installation - uses sa2001.ini: [PermMapGen]Server,Database
Public blnCmdLineFPSilent As Boolean 'Launch Focal Point sync silently
Public blnCmdLineQuiet As Boolean  ' start up with no UI if set.
Public CmdLineExportMacros As Boolean ' if set - VBA exports the macros to the EXE directory \MacroGen\ProjName  - or this path from the ini file "ExportMacrosPath"
Public CurrentViewsExplorerhWnd As Long 'to get the views explorer hwnd to force the focus
Public CmdLineEncyclopedia As String ' connection string of ency to open, should always be quoted if gaps
Public CmdLineWorkspaceID As Integer ' workspace to open ency in
Public CmdLineUniform As Boolean 'Turns on uniform selection
Public CmdLineOldPropertyGrid As Boolean 'Turns off new property grid
Public CmdLineUpgradeMode As Boolean ' suppress tips and other dialogs not neccessary to open an ency
Public CmdLineNoVBA As Boolean ' suppress load of VBA
Public CmdLineNoExtPrjs As Boolean ' suppress load of external projects
Public FocusViewsExplorerhWnd As Long ' To return the focus back to view explorer after closing an opened definition from explorer.
Public blnCmdLineFPExport As Boolean
Public blnCmdLineFPImport As Boolean
Public CmdLineFPProfile As String
Public CmdLineFPUser As String
Public CmdLineFPPassword As String
Public sFolderGUID As String
Public sProfilePath As String
Public sCmdLineExecuteMacroOnStart As String
Public sCmdLineExecuteMacroOnStartArg As String
' MG I didn't add ..OnEncyOpen because we can't assume SA should be shut down at that point
' With the above the macro is executed at the point when any default ency has been opened,
'so it accounts both for macros which will and will not open different encyclopedias

Public Const UIMODE_UNKNOWN = 0
Public Const UIMODE_NOISY = 1
Public Const UIMODE_QUIET = 2

' We assume the highest hardcoded ID in the ATB menu is 30499

Public Const MAXNONINTERNALTOOLID = 6999          ' maximum ID which is not invented on the fly

' Note that these constants are duplicated in ADO Access Control\DefaultCatalog\Process\Work.bas:
Public Const DRAWSYMLOW = 11000          ' normal symbol range
Public Const DRAWSYMHIGH = 13999

' Note that these constants are duplicated in ADO Access Control\DefaultCatalog\Process\Work.bas:
Public Const STEREODRAWSYMLOW = 14000      ' special sterotype symbol range
Public Const STEREODRAWSYMHIGH = 16999

' splash screen ID's
' Note: these id's must match the code in sa2001\bitmaps\source\form1.frm
'       which is the VB project used to build the bitmaps.rc file.
'Public Const SPLASHSYSTEMARCHITECT16 = 901
'Public Const SPLASHSUITE16 = 902
'Public Const SPLASHENVISION16 = 903
'Public Const SPLASHSYSTEMARCHITECT08 = 904
'Public Const SPLASHSUITE08 = 905
'Public Const SPLASHENVISION08 = 906

Public Const DRAWTOOLBARSUBIDSTART = 39001  ' one is used for tool created to support a stereotype or subtype droplist on the current toolbar
Public Const DRAWTOOLBARSUBIDEND = 59999    ' one is used for tool created to support a stereotype or subtype droplist on the current toolbar
Public Const NEXTINTERNALTOOLIDSTART = 60000   ' nice high range - clear of all else
Public Const NEXTINTERNALTOOLIDEND = 2147483640
' no IDs should be declared above this

Public NextInternalMacroToolID As Long  ' Next tool id for macros, to use (Use GetFreeMacroId() and FreeMacroId())

Public fMainForm As FSAMain
Public colFViewBrowseByhWnd As New Collection

Public bSetFocusToChild As Boolean
Public bResetMainWindowProc As Boolean
Public bShutDownInProgress As Boolean
Public bCancelShutDown As Boolean
Public bRequestShutDown As Boolean  ' used to request shutdown.
Public bRequestDelayedShutDown As Boolean  ' used to delay shutdown during startup.
Public bForceShutdown As Boolean ' used to force a shutdown during startup
Public bOpeningDiagram As Boolean   ' used to prevent active status logging during open
Public bSA2001Busy As Boolean ' used to prevent a second UI operation to occur, before the first completed

Public g_blnAttemptAutoLoadEncyPending As Boolean ' Set True if the app was started by an external activeX object - cleared when the Encyclopedia object is accessed
Public g_lngRefUsedToStartSA As Long        ' Set to the ObjPtr number of the Application object created by the external activeX object which launched SA - otherwise is 0
Public g_blnSAAppFullyStarted As Boolean    ' Set True when SA has completed MSAMain Main - successfully
Public g_blnInitMainAppThisTime As Boolean  ' Set True prior to creating our internal Application class in SAAppObj - otherwise False

Public ExitSystemResources As Integer
Public CriticalSystemResources As Integer
Public LowSystemResources As Integer

Public SAIMFAvailable As Boolean
Public SAInitialized As Boolean
Public SAValidAuditID As Boolean

Public SACancelState As Boolean ' set when panel 6 of the status line is clicked
                                ' read and also set from SAUI

' these are our exposed DCOM Objects
Public SAAppObj As Application
Public SAAppObjColl As New Collection   ' This is a collection of Application object ptrs who wish to receive events. Normally empty - unless an external app intantiates one of our Application objects

' from the INI file
Public sLastVersionString As String
Public bShowBrowserUserFilters As Boolean

' globals for use by the main frame
Public FSAMainLeft As Long
Public FSAMainTop As Long
Public FSAMainWidth As Long
Public FSAMainHeight As Long
Public FSAMain_State As Long    ' window state - maximised or normal

' globals for use by the display form
'Public FDisplayAlwaysOnTop As Boolean
Public FDisplayWordwrap As Boolean
Public FDisplayLeft As Long
Public FDisplayTop As Long
Public FDisplayHeight As Long
Public FDisplayWidth As Long

' globals for use by FBrowse and FDetails
Public bInitialShowBrowser As Boolean   ' If false the browser on is only possible
                                        ' via the menu options
Public bShowBrowser As Boolean          ' the browser can be shown (used in conjunction with the above)
Public bBrowserDisplayed As Boolean     ' the browser is currently displayed.
Public bBrowseClick As Boolean          ' browser tool click request

Public bEnableShowClassicBrowser As Boolean
Public bInitialShowClassicBrowser As Boolean
Public bShowClassicBrowser As Boolean          ' the classic browser can be shown (used in conjunction with the above)

Public bNewBrowserDisplayed As Boolean     ' the new browser is currently displayed.
Public bNewBrowseShowMin As Boolean        ' A request to the new browser was made, while minimized - show when restored.
Public bNewBrowseShowModal As Boolean ' set true if a new browser show attempt failed due to a modal dialog box
Public bNewBrowseClick As Boolean          ' browser tool click request

Public bBrowseDetailsClick As Boolean   ' browser details tool click request
Public g_bRefreshBrowser As Boolean       ' browser needs a refresh
Public bDetailOpen As Boolean
Public bRefByOpen As Boolean              'browser refby tool click request

Public bObjectHistoryOpen As Boolean ' object history window is displayed.
Public bDetailPicture As Boolean
Public bCheckEncyLocks As Boolean
Public bBrowseShowMin As Boolean        ' A request to the browser was made, while minimized - show when restored.
Public bBrowseShowModal As Boolean ' set true if a browser show attempt failed due to a modal dialog box
Public bBrowseMinOnUse As Boolean
Public bBrowseReadOnly As Boolean
Public bBrowseUserFilters As Boolean
Public bDetailsKnownOnly As Boolean
Public bDetailsFormatted As Boolean
Public bRequestHideBrowse As Boolean ' used to try and get round crash if we close the browser from a right click
Public gsEncyName As String  'Added to know if visualization should be enabled or not (12/14/2007)
Public bPreviewOpen As Boolean
Public bDVMOpen As Boolean

' globals for use by the toolbox code
Public bDisplayToolBox As Boolean
Public bToolBoxExists As Boolean
Public sToolboxBand As String
Public strDrawMenu As String
Public strMainMenu As String

Public Const WM_USER = &H400
Public Const MSGRestringSymbols = 2

' SA2001 IMF peek poke definitions
' keep in synch with definitions in sauipp.h
Public Const UIPP_bAutoDispToolbox = 100       '   /* DWORD - BOOL - lpA->bAutoDispToolbox */

' Macro Ini Settings
Public MacroLastPath As String
Public MacroOpenReadOnly As Boolean

' Currently hovered over tool id
Public ActiveHelpID As Long
Public ActiveToolName As String
Public ActiveToolUSCaption As String
Public F1HelpWaiting As Long
Public bShowIDOnly As Boolean
Public bShowToolNameOnly As Boolean
Public bShowUSCaptionOnly As Boolean

Public ExeDir As String

' String Localisation Service
Public XResObj As New SAXRes.Resource

' private declarations for use in this module
' Last window with the focus, when the app is deactivated. This is used to set the active window, when app is re-activated
Private hLastActiveWnd As Long

' Set in the SysMenuProc to any WM_COMMAND which IS in the ATB menu system
' This ensures we know about WM_COMMANDs from diagram popups which ARE also tools in the main menu system.
' The ATB system does NOT handle them so we need to determine in a timer if they were handled or not.
' When the right click diagram menu is done via ATB we can ditch this cheat
Public g_lngLastWM_COMMAND As Long

' used to track ency lock counts before and after external calls to make sure we don't leave open transactions
Private g_lEncyLockCount As Long

' QuickTips
Public TipsEnabled  As Boolean
Public TipsNextLine As Long
Public TipsCount As Long

Public Enum ePropertyName
    READ_ONLY = 1
    VBA_USER_FILTER = 2
End Enum

Private bDetailRefreshing As Boolean
Public Type LastSelectionDetailsType
    LastMajor As Long
    LastMinor As Long
    LastId As Long
End Type
Public LastSelectionDetails As LastSelectionDetailsType
Public bUpdateDetails As Boolean
Public bUpdateRefBy As Boolean
Public bEnableSave As Boolean
Public bDiagramSwitched As Boolean
Public bNoItemSelected As Boolean
Public bMultiItemsSelected As Boolean
Public bNotApplicableItemsSelected As Boolean

Private bReferencedByRefreshing As Boolean
Public LastSelectedRefById As Long

Public strIconBaseName As String    ' The Prefix for resources - enables the loading of different icons
                                    ' IconBase="ORG" for classic icons
                                    ' IconBase="BLU" for new rational blue icons
Public strUserId As String
Public strPassword As String
Public sRAMURL As String
Public sRAMUserId As String
Public sRAMPassword As String
Public g_strShellExecuteVerb As String ' Verb used to launch SAWizard ("open" by default,  "runas" for vista and up)
Public g_bIncludeJpegs As Boolean
Public g_BPMNTempPath As String
Public g_bDisplayOSLCHover As Boolean

Public g_startoslcproject As Object
Public g_dicPermVBMacroProjects As New Dictionary
Public g_dicTempVBMacroProjects As New Dictionary
Public g_dicTempVBMacroProjectsFNames As New Dictionary
Public g_dicTempVBMacroProjectsCOMProjects As New Dictionary
Public g_dicTempVBMacroProjectsCOMClasses As New Dictionary

Public bInContextMenuPopup As Boolean

Private strExePath As String
Private m_FsaDgmW2_PrevProc As Long

' no terminating \
Public Function GetExePath() As String
    'If Len(strExePath) = 0 Then
    '    strExePath = regQuery_A_Key(HKEY_LOCAL_MACHINE, "SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\SA2001.exe", "Path")
    'End If
    'GetExePath = strExePath
    GetExePath = App.Path
End Function

Public Sub ClearPreviewPane(Optional ByVal v_strRTFText As String)
End Sub


Public Sub ClearPropsPane()
End Sub


Public Sub DoActualNotApplicableItemUpdate()

    On Error GoTo ErrOut

    ClearRefByPane
    ClearPropsPane
    ClearPreviewPane SAXRes.GetLocalString(IDS_sa2001fdetailfrm_____naitem)
    bNotApplicableItemsSelected = False

StdExit:
    On Error GoTo 0
    Exit Sub
ErrOut:
    Err.Clear
    Resume StdExit
End Sub


Public Sub DoActualMultiItemUpdate()

    On Error GoTo ErrOut

    ClearPreviewPane SAXRes.GetLocalString(IDS_sa2001fdetailfrm_____multipleitems)
    ClearPropsPane
    ClearRefByPane
    bMultiItemsSelected = False


StdExit:
    On Error GoTo 0
    Exit Sub
ErrOut:
    Err.Clear
    Resume StdExit
End Sub


Public Sub DoActualNoItemUpdate()

    On Error GoTo ErrOut

    ClearPreviewPane SAXRes.GetLocalString(IDS_sa2001fdetailfrm_____noitems)
    ClearPropsPane
    ClearRefByPane
    bNoItemSelected = False


StdExit:
    On Error GoTo 0
    Exit Sub
ErrOut:
    Err.Clear
    Resume StdExit
End Sub


Public Sub DoUpdateSelection(ByVal v_lngMajor As Long, ByVal v_lngMinor As Long, ByVal v_lngID As Long)
    On Error GoTo ErrOut

    LastSelectionDetails.LastMajor = v_lngMajor
    LastSelectionDetails.LastMinor = v_lngMinor
    LastSelectionDetails.LastId = v_lngID

    bUpdateDetails = True

StdExit:
    On Error GoTo 0
    Exit Sub
ErrOut:
    Err.Clear
    Resume StdExit
End Sub


Public Sub ClearRefByPane()
    Dim lngPaneID As Long
    Dim objPane As Pane

    On Error GoTo ErrOut

    If bRefByOpen Then
        lngPaneID = fMainForm.Dock.FindLastPaneByType(SADOCK_TAGID_REFERENCEBY)
        Set objPane = fMainForm.Dock.GetPaneByID(lngPaneID)
        objPane.Title = SAXRes.GetLocalString(IDS_sa2001frevbrowserfrm_____referencedby)
    End If

StdExit:
    On Error GoTo 0
    Exit Sub
ErrOut:
    Err.Clear
    Resume StdExit
End Sub


Public Sub DoUpdateRefBy(ByVal v_lngID As Long)
    On Error GoTo ErrOut
       LastSelectedRefById = v_lngID
       bUpdateRefBy = True

StdExit:
    On Error GoTo 0
    Exit Sub
ErrOut:
    Err.Clear
    Resume StdExit
End Sub


Public Sub DoActualUpdateRefBy()
End Sub


Public Sub DoActualUpdateSelection()
End Sub


' We use this to drop a database because con.Execute 'Drop Database' doesn't always succeed
' ByVal Options because con.Execute resets the supplied value
Public Sub ConExecute(ByRef r_con As ADODB.Connection, ByVal v_strCommand As String, ByVal v_lngOptions As Long, ByVal v_strDatabaseName As String)
End Sub


Private Sub DestroyDatabase(ByVal v_strServerName As String, ByVal v_strDatabaseName As String)
End Sub


Private Sub GeneratePermissionMapFile()
End Sub


Private Function lVerifyMode() As Long
    Dim hDLL As Long
    Dim bNoisy As Boolean
    Dim bQuiet As Boolean
    Dim sCmdLine As String

    On Error GoTo ErrorExit

    lVerifyMode = UIMODE_UNKNOWN

    hDLL = LoadLibrary(GetExePath() & "\safull.dll") 'DEV_STRING

    If hDLL <> 0 Then
        bNoisy = True
        Call FreeLibrary(hDLL)
    End If

    hDLL = LoadLibrary(GetExePath() & "\saquiet.dll") 'DEV_STRING

    If hDLL <> 0 Then
        bQuiet = True
        Call FreeLibrary(hDLL)
    End If

    If bNoisy And Not bQuiet Then
        lVerifyMode = UIMODE_NOISY
    ElseIf bQuiet Then ' Ignore the Noisy DLL if Quiet DLL is present
        lVerifyMode = UIMODE_QUIET
    End If

    ' allow override for debugging
    If bQuiet Then ' Ignore the Noisy DLL if the Quiet DLL is present
        ' must set this global or the function call will not work
        ' CommandLine already set
        ' check command line and don't remove
        If InCommandLine("-enableui", False) Then 'DEV_STRING
            lVerifyMode = UIMODE_NOISY
        End If
    ElseIf bNoisy Then
        If InCommandLine("-disableui", False) Then 'DEV_STRING
            lVerifyMode = UIMODE_QUIET
        End If
    End If

ErrorExit:
    Exit Function
End Function


Sub Main()
    Dim lDlls As Long
    Dim lQuiet As Long
    Dim lRt As Long
    Dim lMode As Long

    On Error GoTo ErrorHandler
    g_bNoAutoRefresh = False
    CurrentViewsExplorerhWnd = 0
    g_bIncludeJpegs = False
    g_BPMNTempPath = ""
    g_bDisplayOSLCHover = True
    sRAMURL = "" 'DEV_STRING
    sRAMUserId = "" 'DEV_STRING
    sRAMPassword = "" 'DEV_STRING
    ' Version string - take from resources rather than the app info,  since that doesn't match the IBM numbering systems
    VersionString = SAXRes.FormatLocalString("{0}.{1}", SAXRes.GetLocalString(IDSVersionForDisplay), SAXRes.GetLocalString(IDSBuildNumber)) ' DEV_STRING

    CommandLine = command() & " " & GetIniSetting(SAXRes.GetLocalString(IDSProductIniSectionName), SAXRes.GetLocalString(IDSWININICommandline), "") ' DEV_STRING

    lMode = UIMODE_NOISY

    lRt = Main_Inner()

    If lRt = MAINEND Or (lMode = UIMODE_QUIET And lRt = MAINERR) Then
        End
    End If

    Exit Sub

ErrorHandler:
    Select Case Err.Number
        Case 429: 'Probable registry error
            FixPossibleRegError
            If lMode = UIMODE_NOISY Then
                MsgBox "A configuration problem has prevented System Architect from starting. An attempt will be made to try to correct this problem. Click OK and then wait a minute before attempting to restart System Architect. If this problem persists contact IBM customer support.", vbCritical, "System Architect" 'DEV_STRING DO NOT localize this!
            End If

        Case Else:
            If lMode = UIMODE_NOISY Then
                MsgBox Err.Description & vbCrLf & vbCrLf & "Code: " & Err.Number, vbCritical, "System Architect" 'DEV_STRING DO NOT localize this!
            End If
    End Select
    End 'Do not allow SA to load
End Sub

Private Sub FixPossibleRegError()

    'SAReg will re-register all of SA's COM components

    On Error Resume Next
    Shell GetExePath() & "\Support\SAReg.exe" 'DEV_STRING

End Sub

Sub WarmUpWPF()
End Sub

Function Main_Inner() As Long
    Dim X As Long
    Dim ioldMousePointer As Integer
    Dim errorflag As Boolean
    Dim MacroFileName As String
    Dim pos As String
    Dim Argument As String
    Dim shellCode As Long
    Dim lngPos As Long
    Dim strAppPath As String
    Dim osinfo As OSVERSIONINFO
    Dim strPath As String
    

    Main_Inner = MAINOK

    '***************************************************************************
    ' Set the app path for XRes. Note that for VB projects in debug App.Path is
    ' the project directory if saved otherwise it is the VB install path.
    ' Use GetExePath() instead
    '
    ' THIS CODE MUST GO IN BEFORE ANY CALLS TO SAXRES
    '
    ' The following project path must be the full path from chelsea
    strAppPath = App.Path
    lngPos = InStr(1, strAppPath, "\SA2001", vbTextCompare) 'DEV_STRING
    If lngPos > 0 Then
        strAppPath = Left$(strAppPath, lngPos) & "win32\bin" 'DEV_STRING
    End If
    SAXRes.SetStringtablePath strAppPath
    ' **************************************************************************

    ActiveHelpID = 0
    ActiveToolName = SA_VB_EmptyString
    ActiveToolUSCaption = SA_VB_EmptyString
    F1HelpWaiting = 0
    bShowIDOnly = False
    bShowToolNameOnly = False
    bShowUSCaptionOnly = False
    bSA2001Busy = True  ' Hold back the UI

    LogStartTimer

    If InCommandLine("-log", False) Then CmdLineLog = True 'DEV_STRING
    If GetIniSetting(SAXRes.GetLocalString(IDSProductIniSectionName), SAXRes.GetLocalString(IDSWININIVerboseLog), "N") = "Y" Then CmdLineLog = True  'DEV_STRING

    ExeDir = App.Path
    ChDrive ExeDir
    ChDir ExeDir

    LogMessage "********************************************************" 'DEV_STRING
    LogMessage SAXRes.GetLocalString(IDSProductAppName) & " Startup" 'DEV_STRING


    ' allow multi instance for lexus
    If Not blnCmdLineQuiet Then
        If App.PrevInstance Then
            ' we already have one copy running
            SAMessageBox SAXRes.GetLocalString(IDS_sa2001msamainbas_____theapplicationisalreadyrunningn) & SAXRes.GetLocalString(IDSProductName), vbCritical
            Main_Inner = MAINEND
            Exit Function
        End If
    End If


    NextInternalMacroToolID = NEXTINTERNALMACROIDSTART  ' Macro's are renumbered at SA startup

    ioldMousePointer = Screen.MousePointer
    Screen.MousePointer = vbHourglass

    SAInitialized = False
    SAIMFAvailable = False
    SAValidAuditID = False

    bShutDownInProgress = False

    If errorflag Then   ' failure to startup properly
        Main_Inner = MAINERR
        SAMessageBox SAXRes.GetLocalString(IDS_RunT_Sa2001Msamain____failedtocreatesaimfxobject), vbCritical
        Exit Function
    End If

    ' Check the existence of the Macro structure in the INI file
    ' (There should be at least one entry)

    ' set initial values of globals.
    bInitialShowBrowser = True
    bShowBrowser = True
    bDetailPicture = True      ' overidden by ini file
    bDetailsKnownOnly = True
    bDetailsFormatted = True
    bCheckEncyLocks = True
    bDisplayToolBox = True      ' SADesign calls into this via ToggleToolbox and SAUI
    bToolBoxExists = False

    bInitialShowClassicBrowser = False
    bEnableShowClassicBrowser = False
    bShowClassicBrowser = False

    sToolboxBand = BAND_DRAWTOOLBOX
    strDrawMenu = BAND_DRAWMENU
    strMainMenu = SAXRes.GetLocalString(IDS_uloc_____mainmenu)

    ' Read the INI settings
    LoadIniSettings

    LogMessage "VB commandline processing" 'DEV_STRING
    If InCommandLine("-NoOMStatusChecks", False) Then CmdLineNoOMStatusChecks = True 'DEV_STRING
    If InCommandLine("-ToolCheck", False) Then CmdLineToolCheck = True 'DEV_STRING
    If InCommandLine("-ExportMacro", True) Then CmdLineExportMacros = True 'DEV_STRING
    If InCommandLine("-QAReporting", False) Then CmdLineQAReporting = True 'DEV_STRING
    CmdWSEnabled = Not (InCommandLine("-WSOff", False))
    If InCommandLine("-RWSAMacros", True) Then CmdLineRWSAMacros = True 'DEV_STRING
    If InCommandLine("-JGCtesting", True) Then CmdLineTestMode = True 'DEV_STRING
    If InCommandLine("-Encyclopedia", False) Then 'DEV_STRING
        CmdLineEncyclopedia = GetCommandLineOperand("-Encyclopedia", True) 'DEV_STRING
    End If
    If InCommandLine("-WorkspaceID", False) Then 'DEV_STRING
        CmdLineWorkspaceID = val(GetCommandLineOperand("-WorkspaceID", True)) 'DEV_STRING
    Else
        CmdLineWorkspaceID = 0 ' no workspace (effectively workspace 0 or direct table access)
    End If
    'If InCommandLine("-nomenu", True) Then CmdLineNoMenu = True 'DEV_STRING
    CmdLineNoMenu = False   ' now set using -JGCTesting
    CmdLineDgmActivate = False
    CmdLineNoRedraw = False
    CmdLineNoMenuTimer = False
    CmdLineAllowDbase = False
    
    If InCommandLine("-nomsg", True) Then CmdLineNoUserMsg = True 'DEV_STRING
    If InCommandLine("-timing", False) Then CmdLineTiming = True 'DEV_STRING
    If InCommandLine("-batchfile", False) Then 'DEV_STRING
        CmdBatchFile = True
        BatchFile = GetCommandLineOperand("-batchfile", True) 'DEV_STRING
    End If
    If InCommandLine("-macrogen", True) Then 'DEV_STRING
        CmdLineMacroGen = True
        CmdLineRWSAMacros = True  ' Allow read write on auto loaded macros
    End If
    If InCommandLine("-ddlgen", True) Then 'DEV_STRING
        CmdLineDDLGen = True
    End If
    If InCommandLine("-fulldetails", True) Then 'DEV_STRING
        bDetailsKnownOnly = False
        bDetailsFormatted = False
    End If
    If InCommandLine("-allowd", False) Or InCommandLine("-allowdbase", False) Then 'DEV_STRING
        CmdLineAllowDbase = True
    End If
    If InCommandLine("-oracle2", False) Or InCommandLine("-oracle2version", False) Then 'DEV_STRING
        CmdLineOracleVersion = True
    End If
    CmdLinebADORepo = True
    If InCommandLine("-menutest", True) Then 'DEV_STRING
        CmdLineMenuTestMode = True
    End If
    ' don't remove from cmdline, sadesign needs it
    If InCommandLine("-autoloadgen", False) Then 'DEV_STRING
        CmdLineAutoLoadgen = True
    End If
    If InCommandLine("-permmapgen", True) Then 'DEV_STRING
        blnCmdLinePermMapGen = True
    End If
    If InCommandLine("-fpexport", False) Then 'DEV_STRING
        blnCmdLineFPExport = True
        CmdLineFPProfile = GetCommandLineOperand("-fpexport", False) 'DEV_STRING
        blnCmdLineFPSilent = True
    ElseIf InCommandLine("-fpimport", False) Then 'DEV_STRING
        blnCmdLineFPImport = True
        CmdLineFPProfile = GetCommandLineOperand("-fpimport", False) 'DEV_STRING
        blnCmdLineFPSilent = True
    End If
    If InCommandLine("-fpuser", False) Then 'DEV_STRING
        CmdLineFPUser = GetCommandLineOperand("-fpuser", False) 'DEV_STRING
        If InCommandLine("-fppassword", False) Then 'DEV_STRING
            CmdLineFPPassword = GetCommandLineOperand("-fppassword", False) 'DEV_STRING
        End If
        blnCmdLineFPSilent = True
    End If

    If Not InCommandLine("-NoUniform", False) Then CmdLineUniform = True  'DEV_STRING
    If InCommandLine("-OldPropertyGrid", False) Then CmdLineOldPropertyGrid = True 'DEV_STRING

    On Error GoTo ErrorHandler

    If CmdLineDDLGen And CmdLineMacroGen Then
        SAMessageBox SAXRes.GetLocalString(IDS_sa2001msamainbas_____cannotrunddlgenandmacrogenatthesametimentheddlgenwillbeignored), vbCritical
        CmdLineDDLGen = False
    End If

    If InCommandLine(SAXRes.GetLocalString(IDSWININIUpgradeMode), True) Then
        CmdLineUpgradeMode = True
    End If
    If InCommandLine("-novba", False) Then
        CmdLineNoVBA = True
    End If
    If InCommandLine("-noextprjs", False) Then
        CmdLineNoExtPrjs = True
    End If
    If InCommandLine("-ExecuteMacroOnStart", False) Then 'DEV_STRING
        sCmdLineExecuteMacroOnStart = GetCommandLineOperand("-ExecuteMacroOnStart", True) 'DEV_STRING
    End If
    If InCommandLine("-ExecuteMacroOnStartArg", False) Then 'DEV_STRING
        sCmdLineExecuteMacroOnStartArg = GetCommandLineOperand("-ExecuteMacroOnStartArg", True) 'DEV_STRING
    End If
    
    If SAAppObj Is Nothing Then
        g_blnInitMainAppThisTime = True    ' Do init the app this time - this is our reference
        LogMessage "Setting main application object" 'DEV_STRING
        Set SAAppObj = New Application    ' This is our Application object
        g_blnInitMainAppThisTime = False    ' Clear the flag

        ' permit the app to be started from outside
'    Else
'        ' cannot start from 'outside'
'        Screen.MousePointer = iOldMousePointer
'        MsgBox "app cannot be started by an external application" 'DEV_STRING
'        End
    End If
    If errorflag Then   ' failure to startup properly
        Main_Inner = MAINERR
        SAMessageBox SAXRes.GetLocalString(IDS_RunT_Sa2001Msamain____failedtocreateapplicationobject), vbCritical
        Exit Function
    End If

    LogMessage "Loading main form" 'DEV_STRING
    Set fMainForm = New FSAMain
    If errorflag Then   ' failure to startup properly
        Main_Inner = MAINERR
        SAMessageBox SAXRes.GetLocalString(IDS_RunT_Sa2001Msamain____failedtocreatemainwindow), vbCritical
        Set SAAppObj = Nothing
        Exit Function
    End If
    On Error GoTo 0
    If Not blnCmdLineQuiet Then
        Load fMainForm
        ' Make the toolbars look sensible when loading up
        'DisableAllToolBars fMainForm.ATB
        RedrawMenu  ' Do the redraw right now
        fMainForm.Hide
        ' removed the doevents - jgc 19/11/98 - seems to cause FormX on FDetails to give an error
        ' I tried to put it there to help the toolbar painting when a band was floating
        ' as it floats above the splash screen.
        'DoEvents        ' give painting time to catch up
    End If

    LogMessage "InterceptMessages = True" 'DEV_STRING
    InterceptCommandMessages = True
    SAShMenu = 0            ' ensure that this is zeroed

    LogMessage "setting up callbacks" 'DEV_STRING

    'Init_StatusLine_Procs   ' set up the callback addresses for Status line diddling

    If Not blnCmdLineQuiet Then
        LogMessage "Showing Main Form" 'DEV_STRING
        fMainForm.Show
    End If

    ' Setup the main menu procedure
'    procOld = SetWindowLong(fMainForm.hWnd, GWL_WNDPROC, AddressOf SysMenuProc)
    'hDialogMessageHook = MySetWindowsHookEx(WH_MSGFILTER, AddressOf DialogMessageHook, 0, MyGetCurrentThreadID())   ' Dialog and menu message hook
    'hPostMessageHook = MySetWindowsHookEx(WH_GETMESSAGE, AddressOf PostMessageHook, 0, MyGetCurrentThreadID())    ' Posted message hook
    'hSendMessageHook = MySetWindowsHookEx(WH_CALLWNDPROC, AddressOf SendMessageHook, 0, MyGetCurrentThreadID())   ' Sent message hook
    'hKeyboardMessageHook = MySetWindowsHookEx(WH_KEYBOARD, AddressOf KeyboardMessageHook, 0, MyGetCurrentThreadID())   ' Keyboard message hook
    'hCBTMessageHook = MySetWindowsHookEx(WH_CBT, AddressOf CBTMessageHook, 0, MyGetCurrentThreadID())   ' CBT message hook
    'hMouseMessageHook = MySetWindowsHookEx(WH_MOUSE, AddressOf MouseMessageHook, 0, MyGetCurrentThreadID())   ' Mouse message hook
    'bResetMainWindowProc = True

    If Not blnCmdLineQuiet Then
        DoEvents        ' give painting time to catch up
    End If

    'SAIMFAvailable = True       ' allow IMF calls from here on

    'FBrowse.LoadDiagList

    ' Request higher permissions in Vista\Win7
    osinfo.dwOSVersionInfoSize = 148
    GetVersionExA osinfo
    If (osinfo.dwMajorVersion >= 6) Then
        ' Using RunAs will force UAC to ask for Admin privilages
        g_strShellExecuteVerb = "runas"
    Else
        g_strShellExecuteVerb = "open"
    End If

    If False Then
    'If CmdLinebADORepo Then
        If Not CmdLineMacroGen And _
            Not CmdLineDDLGen And _
            Not blnCmdLinePermMapGen Then
            ' Macrogen doesn't want to open an ency

            On Error GoTo ErrorHandler
              ' If -adorepo is switched then we use the UI driven login and audit code
            If AuditRun(False) = 0 Then
                If g_lngRefUsedToStartSA <> 0 Or blnCmdLineQuiet Then
                    ' This was started by an external application - so don't load the ency, unless they
                    ' access they Encyclopedia object
                    g_blnAttemptAutoLoadEncyPending = True
                    LogMessage "Pending autoload of ency - will autoload if the initiator accesses Application.Encyclopedia" 'DEV_STRING
                Else
                    g_blnAttemptAutoLoadEncyPending = False

                    strPath = GetExePath()
                    If bOpenEncyOnStartup(strPath) = False _
                        And Len(sCmdLineExecuteMacroOnStart) = 0 Then
                        Call bBrowseOpenEncy(strPath)
                    End If
                End If
            Else
                bForceShutdown = True
                Main_Inner = MAINERR
                Unload fMainForm
                Exit Function
            End If
            LogMessage "Audit Run finished" 'DEV_STRING

        ElseIf blnCmdLinePermMapGen Then
            If AuditRun(False) = 0 Then
                On Error GoTo FailPermMapGen
                GeneratePermissionMapFile
                On Error GoTo 0
                ' Close down SA2001
                bRequestShutDown = True ' request shutdown here
            End If

        End If
    End If

    fMainForm.DoneLoading
    'If Len(sCmdLineExecuteMacroOnStart) = 0 Then
    '    AttemptRecovery
    'End If

    ' Initialise temp folder for storage of udl files by the open encyclopedia wizard,
    'until we are sure that no code remains that depends upon them...
    ' tomp - don't create this in quiet mode, or if you do it better be unique per instance
    'objSAFileUtils.SA_File_ConstructFolderPath objSAFileUtils.SA_File_GetFolderLocation(0, SASF_SALocalAppData) & "Temp UDL Files" 'DEV_STRING

    'If Not fMainForm.ActiveDiagram Is Nothing Then
    '    If Not (TypeOf fMainForm.ActiveDiagram Is FSADgmWnd Or TypeOf fMainForm.ActiveDiagram Is FSADgmWnd2) Then
    '        ' NB: There can be diagrams active if they were opened by the GPF recovery code
    '        EnableAllDrawingTools False ' Ensure no drawing tools are enabled
    '    End If
    'End If

    Screen.MousePointer = ioldMousePointer

    SAInitialized = True    ' Assume success, and allow things to happen.
    'UpdateAllToolPermissions    ' Ensure all menu items are setup with their permissions correctly
    'SAAppObj.AppEvent_Startup     ' We call Startup event here
    LogStatusTimer "Startup Complete " 'DEV_STRING

    If Not CmdLineMacroGen And _
        Not CmdLineDDLGen And _
        Not blnCmdLinePermMapGen And _
        Not blnCmdLineQuiet And _
        Not CmdLineUpgradeMode And _
        Len(sCmdLineExecuteMacroOnStart) = 0 Then
        'QuickTipAtStartUp    ' Display opening tip, if enabled
    End If

    'If CmdBatchFile And Len(BatchFile) > 0 Then
    '    bRequestDelayedShutDown = True
    '    ExecuteBatchFile BatchFile
    'End If

    bSA2001Busy = False  ' Unleash the UI

    'If bRequestDelayedShutDown Then
    '    LogMessage "Shutdown requested during startup." 'DEV_STRING
    '    Main_Inner = MAINERR
    '    ' try and do this cleanly !!!
    '    CloseDownApp    ' will work as SAInitialized is True
    '    Exit Function
    'End If


    fMainForm.ATB.Localise

    ' The following calls are no longer needed because is is all handled by the SAUI code
    'If Not SAAppObj.Encyclopedia Is Nothing Then
        ' There is an ency open

        ' These ency open events are not fired on startup as VBA is not loaded at that time
     '   SAAppObj.AppEvent_EncyOpen   ' Fire - Ency open event now.
     '   SAAppObj.AppEvent_ToolsMenuUpdate   ' Fire - Tools Menu event now.
    'End If
    EnableStartUpToolBars fMainForm.ATB

    DoEvents    ' Ensure all VBA macros have processed their events
    g_blnSAAppFullyStarted = True   ' Make a note that SA has completed startup
    LogMessage "SA Fully started" 'DEV_STRING
    
    Exit Function

ErrorHandler:
    If Err.Number = vbObjectError + XMLPARSEERROR Then
        If Not blnCmdLineQuiet Then
            SAMessageBox SAXRes.GetLocalString(IDSProductName) & SAXRes.GetLocalString(IDS_sa2001msamainbas_____xmlparserfailed) + vbCrLf + SAXRes.GetLocalString(IDS_RunT_Sa2001Msamain____pleasecheckinstallation), vbCritical Or vbOKOnly
        End If
        bRequestDelayedShutDown = True
    End If
    errorflag = True
    Resume Next

FailPermMapGen:

    If Not blnCmdLineQuiet Then
            SAMessageBox SAXRes.GetLocalString(IDS_sa2001msamainbas_____failedtocreatedefaultpermissionmapfile), vbOKOnly + vbCritical, _
        "-permmapgen"
    End If

    bRequestDelayedShutDown = True
    errorflag = True
    Resume Next
End Function

Public Function AuditRun(Optional bForceDialog As Boolean = True, _
                            Optional strNewAuditID As Variant, _
                            Optional strNewPassword As Variant) As Long
    AuditRun = 0
End Function

Public Function bOpenEncyOnStartup(ByVal Path As String) As Boolean
End Function

Public Sub ExecuteMenuOpenEncy()
    Dim strPath As String


    If CmdLinebADORepo Then
        ' Currently the UI driven code is only enabled with the -adorepo switch
        strPath = GetExePath()
        Call bBrowseOpenEncy(strPath)
        EnableMenuItemsIfEncyisOpen
    Else
        ' ?? TODO: Remove the call to sadesign here, use the adorepo code above
        MyExecuteMenuCommand 164
        EnableMenuItemsIfEncyisOpen
    End If
End Sub

' bForceAutoCreate added by MarkG to support GeneratePermissionMapFile which is run if CmdLinePermMapGen is set
' At this time bCreatable was used in existing calls but was not acted upon.
Public Function bBrowseOpenEncy(ByVal Path As String, Optional ByVal bCreatable As Boolean = True, Optional ByVal bAutoOpen = False, Optional bForceAutoCreate As Boolean, Optional lngForceEncyTypeTo As Long = -1, Optional ByVal lngOverrideFlags As Long = 0) As Boolean
End Function


Public Sub CorrectRecentList()
End Sub


Public Sub ApplyBrowserTabOverride(ByVal Path As String)
End Sub


Function bProcessXMLErrorProperty(ByVal XMLString As String, Optional ByRef retErrVal As Long, Optional ByVal bShowUser As Boolean = True, Optional ByRef retErrMsg As String) As Boolean
End Function


Sub EndMain()

    LogMessage "Entering EndMain" 'DEV_STRING

' do this much later, the call to saobjend may use these
'    Set SAAppObj = Nothing  ' destroy reference
'    Set SAImfObj = Nothing


    If SAInitialized Then    ' only clean up if we initialized
        Close_StatusLine_Procs              ' ensure that no status line callbacks occur
        ' ensure that all child forms are closed

    End If

    If bResetMainWindowProc Then               ' only call this if we have set it
'        SetWindowLong fMainForm.hWnd, GWL_WNDPROC, procOld ' set back the window proc
'        If hDialogMessageHook <> 0 Then
'          MyUnHookWindowsHookEx hDialogMessageHook
'        End If
'        If hPostMessageHook <> 0 Then
'          MyUnHookWindowsHookEx hPostMessageHook
'        End If
'        If hSendMessageHook <> 0 Then
'          MyUnHookWindowsHookEx hSendMessageHook
'        End If
'        If hKeyboardMessageHook <> 0 Then
'          MyUnHookWindowsHookEx hKeyboardMessageHook
'        End If
'        If hCBTMessageHook <> 0 Then
'          MyUnHookWindowsHookEx hCBTMessageHook
'        End If
'        If hMouseMessageHook <> 0 Then
'          MyUnHookWindowsHookEx hMouseMessageHook
'        End If
'        bResetMainWindowProc = False
    End If

    ' Save the INI settings
    If SAInitialized Then    ' only clean up if we initialized
        SaveIniSettings
    End If

    Set SAAppObj = Nothing  ' destroy reference


    LogMessage "Closedown complete" 'DEV_STRING

    End
End Sub

Public Function DialogMessageHook(ByVal nCode As Long, ByVal wParam As Long, theMsg As msg) As Long
' This is hooked into the application to trap F1 keypresses in dialogs and sub menus
  Dim n As Long
  Dim lRet As Long
  Dim hParent As Long
  Dim lID As Long
  Dim szDlgId As String

  lRet = 0  ' We never handle it - we just use the information given

  If nCode < 0 Then
    ' See Win API help
    lRet = MyCallNextHookExMsg(hDialogMessageHook, nCode, wParam, theMsg)
  Else
    If theMsg.message <> 0 Then
      Select Case nCode
        Case MSGF_DIALOGBOX:
          If theMsg.message = WM_KEYDOWN And theMsg.wParam = vbKeyF1 Then
            hParent = GetTrueParentWindowHandle(theMsg.hWnd)

            'lID = GetDialogHelpID(hParent)  ' Find the dialog's help ID if it has one

            If lID <> 0 Then
              ' If there is an ID for this dialog
              ActiveHelpID = lID  ' Set the active help id
              F1HelpWaiting = 1

            End If

          End If
        Case MSGF_MENU:
          If theMsg.message = WM_KEYDOWN And theMsg.wParam = vbKeyF1 Then
              'lID = GetActiveSubMenuHelpID()
              If lID <> 0 Then
                ' If there is an ID for this menu
                ActiveHelpID = lID  ' Set the active help id
                F1HelpWaiting = 1
            End If
          End If
      End Select
    End If

    ' Call the next hook in the chain
    MyCallNextHookExMsg hDialogMessageHook, nCode, wParam, theMsg
  End If

  DialogMessageHook = lRet
End Function

Public Function CBTMessageHook(ByVal nCode As Long, ByVal wParam As Long, theMsg As msg) As Long
' This is hooked into the application to trap activation of windows
  Dim frm As Form
  Dim lRet As Long

  lRet = 0  ' We never handle it - we just use the information given
  If nCode < 0 Then
  ElseIf nCode = HCBT_ACTIVATE Then ' including Or nCode = HCBT_SETFOCUS causes diagram window to be opened on ency change
    ' It is important not to update ActiveWindow here.. leave that to the MDIChild_ActivateDeactivateTests routine in FSAMain1
    
    For Each frm In Forms
        If frm.hWnd = wParam Then
            Exit For
        End If
    Next
  End If
  ' Call the next hook in the chain
  lRet = MyCallNextHookExMsg(hCBTMessageHook, nCode, wParam, theMsg)

  CBTMessageHook = lRet
End Function

Public Function MouseMessageHook(ByVal nCode As Long, ByVal wParam As Long, theMsg As mousemsg) As Long
' This is hooked into the application to trap mouse press because although CBTMessageHook traps
'the Activate event it occurs AFTER a WM_LBUTTONDOWN event which sadesign core traps and starts
'a drawing action if allowed to, which caused an internal diagram window to be repainted
'in quick-draw mode instead of the diagram window the user initiated the drawing action in.
  Dim n As Long
  Dim lRet As Long
  Dim hParent As Long
  Dim lID As Long
  Dim szDlgId As String
  Dim frm As Form
  Dim bDontCall As Boolean

  lRet = 0  ' We never handle it - we just use the information given

  If nCode < 0 Then
    ' See Win API help
    lRet = MyCallNextHookExMsg2(hMouseMessageHook, nCode, wParam, theMsg)
  ElseIf nCode = HC_ACTION And Not fMainForm.ActiveDiagram Is Nothing Then
    bDontCall = False
    If wParam = WM_LBUTTONDOWN Or wParam = WM_RBUTTONDOWN Then
    ' Although we can trap WM_MOUSEMOVE which is normally supposed to include mouse button data,
    'that doesn't get received even in theMsg.dwMouseData
    End If

    ' Call the next hook in the chain
    If Not bDontCall Then
        lRet = MyCallNextHookExMsg2(hMouseMessageHook, nCode, wParam, theMsg)
    End If
  Else
    lRet = MyCallNextHookExMsg2(hMouseMessageHook, nCode, wParam, theMsg)
  End If

  MouseMessageHook = lRet
End Function

Public Function PostMessageHook(ByVal nCode As Long, ByVal wParam As Long, theMsg As msg) As Long
' This is hooked into the application to trap posted messages, can change them
  Dim lRet As Long
  Dim frm As Form

  lRet = 0  ' We always return 0 or do as Win API demands

  If nCode < 0 Then
    ' See Win API help
    lRet = MyCallNextHookExMsg(hPostMessageHook, nCode, wParam, theMsg)
  Else
    If (theMsg.hWnd = fMainForm.hWnd) And (wParam = PM_REMOVE) Then
      ' The message is for the main frame and has been removed from the queue
      ' we check for the PM_REMOVE as we are called for every peek at the message and
      ' only want to be called once
      SysMenuProc theMsg.hWnd, theMsg.message, theMsg.wParam, theMsg.lParam
    Else
    End If
    ' Call the next hook in the chain
    lRet = MyCallNextHookExMsg(hPostMessageHook, nCode, wParam, theMsg)
  End If

  PostMessageHook = lRet
End Function

Public Function SendMessageHook(ByVal nCode As Long, ByVal wParam As Long, theMsg As CWPSTRUCT) As Long
' This is hooked into the application to trap sent messages.. can only examine, can't change
  Dim lRet As Long
  Dim frm As Form

  lRet = 0  ' We always return 0 or do as Win API demands

  If nCode < 0 Then
    ' See Win API help
    lRet = MyCallNextHookExCWPSTRUCT(hSendMessageHook, nCode, wParam, theMsg)
  Else
    If theMsg.hWnd = fMainForm.hWnd Then
'''' TODO TOOLBAR - check this - it causes a second open ency dialog
''''        If theMsg.wParam = 164 Then
''''            ExecuteMenuOpenEncy
''''        Else
''''          ' The message is for the main frame
''''          SysMenuProc theMsg.hWnd, theMsg.message, theMsg.wParam, theMsg.lParam
''''        End If
      SysMenuProc theMsg.hWnd, theMsg.message, theMsg.wParam, theMsg.lParam
    Else
    End If

    ' Call the next hook in the chain
    lRet = MyCallNextHookExCWPSTRUCT(hSendMessageHook, nCode, wParam, theMsg)
  End If

  SendMessageHook = lRet
End Function

Public Function KeyboardMessageHook(ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
' This is hooked into the application to trap posted messages
  Dim lRet As Long
  Dim Shift As Integer
  Dim lngSelectedControlType As SATOOLBAR_TOOLTYPE
  Dim objSATool As SAToolbarTool
  Dim bOK As Boolean
  Dim hWnd As Long
  Dim frm As Form

  lRet = 0  ' Not yet handled

  ' F1 key press processing

  If nCode < 0 Then
    ' See Win API help
    lRet = MyCallNextHookExLong(hKeyboardMessageHook, nCode, wParam, lParam)
  ElseIf nCode <> HC_NOREMOVE Then
    ' Decode the keypress if it has been removed from the queue
    If wParam = VK_F1 Then
        If ((&H80000000 And lParam) = &H80000000) Then
          ' Key being released
            If fMainForm.ATB.IsEatingKeypresses Then
                ' Help accelerator DOES NOT FUNCTION when the menus are open so handle separately
                Dim objActiveTool As SAToolbarTool
                Set objActiveTool = fMainForm.ATB.ActiveTool
                If Not objActiveTool Is Nothing Then
                    If Left(objActiveTool.Name, Len(MACROPREFIX)) = MACROPREFIX Then
                        ActiveHelpID = objActiveTool.HelpContextID
                    Else
                        ActiveHelpID = objActiveTool.toolID
                    End If
                    ActiveToolName = objActiveTool.Name
                    'ActiveToolUSCaption = GetToolCaptionString(objActiveTool.name, True)
                End If

                bShowIDOnly = False
                bShowToolNameOnly = False
                bShowUSCaptionOnly = False
                If (&H8000 And GetKeyState(VK_CONTROL)) <> 0 Then
                  If (&H8000 And GetKeyState(VK_SHIFT)) <> 0 Then
                      ' If CTRL-SHIFT was pressed
                      bShowToolNameOnly = True
                  Else
                      ' If CTRL was pressed
                      bShowIDOnly = True
                  End If
                ElseIf (&H8000 And GetKeyState(VK_SHIFT)) <> 0 Then
                    ' If SHIFT was pressed
                    bShowUSCaptionOnly = True
                End If
                F1HelpWaiting = 1
                lRet = 1  ' We handled the keypress do not pass on
            End If
        End If
    ElseIf (wParam = VK_F4) And (&H8000 And GetKeyState(VK_MENU)) Then
        ' ALT-F4 - should always shutdown the application
        If ((&H80000000 And lParam) = &H80000000) Then
            ' Key being released
            
            g_lngLastWM_COMMAND = IDMEXIT   ' Force an exit
            lRet = 1    ' We handled the keypress
            
            ' Leaving this in for reference..this allows external diagram windows to be closed individually.
'            bOk = False ' don't do it
'
'            hwnd = GetActiveWindow
'            ' ^ This returns fmainForm.hwnd when there is an edit session window active!
'            'and when there is a pane window active
'            If hwnd = fMainForm.hwnd Then
'                g_lngLastWM_COMMAND = IDMEXIT   ' Force an exit
'                lRet = 1    ' We handled the keypress
'            Else
'                For Each frm In Forms
'                    If frm.hwnd = hwnd Then
'                        If TypeOf frm Is FSADgmWnd2 Then
'                            SendMessage hwnd, WM_CLOSE, 0, 0
'                            lRet = 1    ' We handled the keypress
'                        End If
'                        Exit For
'                    End If
'                Next
'            End If
        End If
    ElseIf wParam <> 0 Then
        If ((&H80000000 And lParam) = &H80000000) Then
            ' Key being released
            If m_blnLastKeyWasEaten Then
                lRet = 1    ' Eat this code also
                m_blnLastKeyWasEaten = False
            End If
        Else
            If fMainForm.ATB.IsEatingKeypresses Then
                lRet = 1    ' Somehow keypresses leak into the browser and other controls which like arrow keys
                            ' - when the menu system should be in charge.  (ALT to get menus to drop, then arrows)
                            ' If we grab them here we seem to be ok.
                m_blnLastKeyWasEaten = True
            Else
                lngSelectedControlType = fMainForm.ATB.GetCurrentSelectedToolType()
                If lngSelectedControlType > -1 Then
                    If (lngSelectedControlType = SATB_TT_COMBOBOX) Or (lngSelectedControlType = SATB_TT_EDIT) Or (lngSelectedControlType = SATB_TT_CUSTOM) Then
                        If (&H8000 And GetKeyState(VK_SHIFT)) <> 0 Then
                            If (&H8000 And GetKeyState(VK_INSERT)) <> 0 Then
                                lRet = 1
                                m_blnLastKeyWasEaten = True
                            ElseIf (&H8000 And GetKeyState(VK_BACK)) <> 0 Then
                                lRet = 1
                                m_blnLastKeyWasEaten = True
                            ElseIf (&H8000 And GetKeyState(VK_LEFT)) <> 0 Then
                                lRet = 1
                                m_blnLastKeyWasEaten = True
                            ElseIf (&H8000 And GetKeyState(VK_RIGHT)) <> 0 Then
                                lRet = 1
                                m_blnLastKeyWasEaten = True
                            Else
                                m_blnLastKeyWasEaten = False
                            End If
                        Else
                            Select Case wParam
                                Case VK_BACK, VK_LEFT, VK_RIGHT
                                    lRet = 1
                                    m_blnLastKeyWasEaten = True
                                Case Else
                                    m_blnLastKeyWasEaten = False
                            End Select
                        End If
                    Else
                        m_blnLastKeyWasEaten = False
                    End If
                    Set objSATool = fMainForm.ATB.GetCurrentSelectedTool()
                    If Not objSATool Is Nothing Then
                        If objSATool.Name = TOOL_SEARCHTEXT Then
                            If SearchComboKeydownHandler(wParam, objSATool) Then
                                lRet = 1 ' This never happens
                                m_blnLastKeyWasEaten = True
                            End If
                        ElseIf objSATool.Name = TOOL_LISTOSLCCR2 Then ' stops item from being opened when user presses ENTER
                            If wParam = VK_RETURN Then
                                lRet = 1
                                m_blnLastKeyWasEaten = True
                            End If
                        End If
                    End If
                Else
                    m_blnLastKeyWasEaten = False
                End If
            End If
        End If
    End If

    If lRet = 0 Then
        ' Call the next hook in the chain
        lRet = MyCallNextHookExLong(hKeyboardMessageHook, nCode, wParam, lParam)
    Else
        ' Call the next hook in the chain but don't return the value
        MyCallNextHookExLong hKeyboardMessageHook, nCode, wParam, lParam
    End If
  End If

  KeyboardMessageHook = lRet
End Function

Public Function SysMenuProc(ByVal hWnd As Long, ByVal iMsg As Long, _
                            ByVal wParam As Long, ByVal lParam As Long) As Long
Dim X As Long
Dim Shift As Integer
Dim KeyPress As Integer
Dim TemphWnd As Long
Dim hWndChild  As Long

    If iMsg = WM_SYSCOMMAND Then
'        LogMessage "WM_SYSCOMMAND " & Format(wParam) & ", " & Format(lParam) 'DEV_STRING
    ElseIf iMsg = WM_SIZE Then
        ' we do not seem to get the minimised resize event when
        ' SACPP1 sets us to minimized via ShowWindow
'        LogMessage "WM_SIZE" 'DEV_STRING
        If wParam = SIZE_MINIMIZED Then
            FSAMain_State = vbMinimized ' ensure that this resize event gets through
        End If
    ElseIf iMsg = WM_SETREDRAW Then
'        LogMessage "WM_SETREDRAW " & Format(wParam) 'DEV_STRING
        X = 1
    ElseIf iMsg = WM_COMMAND Then

        LogMessage "WM_COMMAND " & Format(wParam) & ", " & Format(lParam) 'DEV_STRING

        If InterceptCommandMessages Then
            Dim lCmd As Long
            lCmd = (wParam And &HFFFF&)

            If lCmd <= MAXCOMMANDMESSAGE Then
                If Not fMainForm.ATB.IsTool(lCmd) Then
                    MyExecuteMenuCommand (lCmd) ' only used for popups from SADESIGN...
                    X = 1 ' say we handled it
                Else
                    g_lngLastWM_COMMAND = lCmd  ' We set this because diagram popups have some ATB menu items in them
                                                ' they are not processed by ATB since they were not fired from the ATB menu system
                                                ' WHEN we make the popup menu an ATB menu this code can go - but until then we
                                                ' have to cheat a little
                    LogMessage "WM_COMMAND - Is toolbar tool so should be handled by ATB - unless it is from a diagram popup" 'DEV_STRING
                End If
            Else
                LogMessage "WM_COMMAND - Not handled" 'DEV_STRING
            End If
        End If
    ElseIf iMsg >= WM_USER Then
        ' hook to pass to SADesign
'        LogMessage "WM_USER" & Format(iMsg - WM_USER) & ", " & Format(wParam) 'DEV_STRING
        If Not CmdLineNoUserMsg Then
            'X = sadesign.SAObjFrameMessage(hWnd, iMsg, wParam, lParam)
        End If
    ElseIf iMsg = WM_MENUSELECT Then
        ' Pass this to SADesign, for it to handle popup menus (Help Ids are calculated via this)
'        LogMessage "WM_MENUSELECT" & Format(iMsg) & ", " & Format(wParam) 'DEV_STRING
        'X = sadesign.SAObjFrameMessage(hWnd, iMsg, wParam, lParam)

    ElseIf iMsg = WM_SYSKEYDOWN Then
        If hWnd = fMainForm.hWnd Then
            ' this is not a desirable state so we need to repost this message to the correct window
            hWndChild = GetWindow(fMainForm.hWnd, GW_CHILD)
            ' and try to prevent a re-occurrence
            MyPostMessage hWnd, WM_SETFOCUS, hWnd, 0
            MyPostMessage hWndChild, iMsg, wParam, lParam
        End If
    ElseIf iMsg = WM_SYSKEYUP Then
        If hWnd = fMainForm.hWnd Then
            ' this is not a desirable state so we need to repost this message to the correct window
            hWndChild = GetWindow(fMainForm.hWnd, GW_CHILD)
            MyPostMessage hWndChild, iMsg, wParam, lParam
        End If
    End If
'''    ' Let old window procedure handle other messages
'''    If x <> 1 Then
'''        SysMenuProc = MyCallWindowProc(procOld, hWnd, iMsg, wParam, lParam)
'''    Else
'''        SysMenuProc = x
'''    End If

       SysMenuProc = X
End Function

Public Sub MyExecuteMenuCommand(command As Long)

    LogMessage "Calling ExecuteMenuCommand " + Format(command) 'DEV_STRING

    If Not SAInitialized Then
        If command = IDMEXIT Then
            bRequestDelayedShutDown = True
        Else
            Exit Sub
        End If
    End If
    If command = IDMEXIT Then       ' EXIT command - we intercept this !!!!
        CloseDownApp
        Exit Sub
'''        If Not CloseDownApp Then        ' shut down gracefully
'''            End                 ' terminate
'''        Else
'''            Exit Sub
'''        End If
    ElseIf command = 173 Then
        '   ActiveHelpId should be zero in order to bring up the help home page
        '   If it is 173 it's the page that explains Help|Help

        LogMessage "Send Help - Context " + Format(ActiveHelpID) 'DEV_STRING

        If ActiveHelpID = 0 Then
            ' No Help ID has been set by the keyboard or dialog hooks
            ' Check to see if any toolbar items are hovered over right now - and get their help id
            Dim objActiveTool As SAToolbarTool
            Set objActiveTool = fMainForm.ATB.ActiveTool
            If Not objActiveTool Is Nothing Then
                If Left(objActiveTool.Name, Len(MACROPREFIX)) = MACROPREFIX Then
                    ActiveHelpID = objActiveTool.HelpContextID
                Else
                    ActiveHelpID = objActiveTool.toolID
                End If
                ActiveToolName = objActiveTool.Name
                'ActiveToolUSCaption = GetToolCaptionString(objActiveTool.name, True)
            End If

            bShowIDOnly = False
            bShowToolNameOnly = False
            bShowUSCaptionOnly = False
            If (&H8000 And GetKeyState(VK_CONTROL)) <> 0 Then
              If (&H8000 And GetKeyState(VK_SHIFT)) <> 0 Then
                  ' If CTRL-SHIFT was pressed
                  bShowToolNameOnly = True
              Else
                  ' If CTRL was pressed
                  bShowIDOnly = True
              End If
            ElseIf (&H8000 And GetKeyState(VK_SHIFT)) <> 0 Then
                ' If SHIFT was pressed
                bShowUSCaptionOnly = True
            End If
        End If

        ' We now know what sort of help is required
        If bShowIDOnly Then
            bShowIDOnly = False
            If ActiveHelpID <> 0 Then
                SAMessageBox SAXRes.GetLocalString(IDS_RunT_Sa2001Msamain____helptopicnumber) + Format(ActiveHelpID), vbInformation
            Else
                MessageBeep 0
            End If
        ElseIf bShowToolNameOnly Then
            bShowToolNameOnly = False
            If ActiveToolName <> SA_VB_EmptyString Then
                SAMessageBox SAXRes.GetLocalString(IDS_sa2001msamainbas_____menutoolnameisn) & ActiveToolName, vbInformation
            Else
                MessageBeep 0
            End If
        ElseIf bShowUSCaptionOnly Then
            bShowUSCaptionOnly = False
            If ActiveToolUSCaption <> SA_VB_EmptyString Then
                SAMessageBox SAXRes.GetLocalString(IDS_sa2001msamainbas_____menutoolcaptionisn) & ActiveToolUSCaption, vbInformation
            Else
                MessageBeep 0
            End If
        Else
            ' Actually display the help
            If ActiveHelpID = 0 Then
              ' Help not pressed on a menu
                'SAWinHelp fMainForm.hWnd, SA_VB_EmptyString, HH_DISPLAY_TOPIC, 0
            Else
                'SAWinHelp fMainForm.hWnd, SA_VB_EmptyString, HH_HELP_CONTEXT, ActiveHelpID
            End If
        End If

        ActiveHelpID = 0
        ActiveToolName = SA_VB_EmptyString
        ActiveToolUSCaption = SA_VB_EmptyString
        bShowIDOnly = False
        bShowToolNameOnly = False
      Exit Sub
' allow for use of the high word - the only call where this could be a problem already has this test.
'''    ElseIf command > MAXCOMMANDMESSAGE Then
'''        LogMessage "MyExecuteCommand did not pass on " & Format(command) 'DEV_STRING
'''        Exit Sub
    End If

    Dim lSaveWindowStyle As Long    ' fix for bug 1963 GPF when minimizing during ency open
                                    ' we now prevent minimize during any SADesign command.
    lSaveWindowStyle = GetWindowLong(fMainForm.hWnd, GWL_STYLE)
    Call SetWindowLong(fMainForm.hWnd, GWL_STYLE, lSaveWindowStyle And (Not WS_MINIMIZEBOX))
    'sadesign.SAObjCommand command   ' execute the command
    Call SetWindowLong(fMainForm.hWnd, GWL_STYLE, lSaveWindowStyle)
End Sub


Public Sub EnableMenuItemsIfEncyisOpen()
    Dim strEncy As String
    Dim lngRetCode As Long
    Dim sConnectString As String
    Dim sServerType As String

    'Compare diagrams should be opened even if an ency is not opened
    EnableMenuTool fMainForm.ATB.Tools("SAIDM_60301"), True
    EnableMenuTool fMainForm.ATB.Tools("SAIDM_818"), True
    If lngRetCode = 0 And strEncy <> SA_VB_EmptyString Then
        'MsgBox "ENCY Open -" & strEncy & "-" 'DEV_STRING
        ShowMenuTool fMainForm.ATB, fMainForm.ATB.Tools("SAIDM_821"), True 'DEV_STRING
        EnableMenuTool fMainForm.ATB.Tools("SAIDM_821"), False 'Cognos Report
        EnableMenuTool fMainForm.ATB.Tools("SAIDM_798"), True   'DEV_STRING Enable the SA Visualization menu item
        If (colFViewBrowseByhWnd.Count = MAX_VIEW_BROWSER) Then
            EnableMenuTool fMainForm.ATB.Tools("SAIDM_30005"), False
        Else
            EnableMenuTool fMainForm.ATB.Tools("SAIDM_30005"), True 'DEV_STRING flag for timer to enable  ' Browser
        End If
        EnableMenuTool fMainForm.ATB.Tools("SAIDM_731"), True   'DEV_STRING Enable the properties menu item
        EnableMenuTool fMainForm.ATB.Tools("SAIDM_10043"), True   'DEV_STRING Enable the object history menu item
        If (bEnableShowClassicBrowser) Then
            ShowMenuTool fMainForm.ATB, fMainForm.ATB.Tools("SAIDM_60299"), True 'DEV_STRING
            EnableMenuTool fMainForm.ATB.Tools("SAIDM_60299"), True 'DEV_STRING
        Else
            ShowMenuTool fMainForm.ATB, fMainForm.ATB.Tools("SAIDM_60299"), False 'DEV_STRING
            EnableMenuTool fMainForm.ATB.Tools("SAIDM_60299"), False 'DEV_STRING
        End If
        EnableMenuTool fMainForm.ATB.Tools("SAIDM_9"), True ' Pic Browser
    Else
        'MsgBox "Ency not open" 'DEV_STRING
        EnableMenuTool fMainForm.ATB.Tools("SAIDM_30005"), False 'DEV_STRING flag for timer to disable  ' Browser
        EnableMenuTool fMainForm.ATB.Tools("SAIDM_60299"), False 'DEV_STRING 'Classic Explorer
        EnableMenuTool fMainForm.ATB.Tools("SAIDM_10007"), False 'DEV_STRING Browser refresh - flag for timer to enable
        EnableMenuTool fMainForm.ATB.Tools("SAIDM_145"), False 'DEV_STRING New Diagram - flag for timer to disable  ' Browser
        EnableMenuTool fMainForm.ATB.Tools("SAIDM_140"), False 'DEV_STRING New Definition - flag for timer to disable  ' Browser
        EnableMenuTool fMainForm.ATB.Tools("SAIDM_731"), False 'DEV_STRING Disable the properties menu item
        EnableMenuTool fMainForm.ATB.Tools("SAIDM_10043"), False   'DEV_STRING Disable the object history menu item
        EnableMenuTool fMainForm.ATB.Tools("SAIDM_10048"), False 'DEV_STRING
        EnableMenuTool fMainForm.ATB.Tools("SAIDM_826"), False 'DEV_STRING
        EnableMenuTool fMainForm.ATB.Tools("SAIDM_827"), False 'DEV_STRING
        EnableMenuTool fMainForm.ATB.Tools("SAIDM_828"), False 'DEV_STRING
        EnableMenuTool fMainForm.ATB.Tools("SAIDM_829"), False 'DEV_STRING
        EnableMenuTool fMainForm.ATB.Tools("SAIDM_9"), False ' Pic Browser
    End If

    bMenusChanged = True    ' flag for timer to activate
End Sub

Public Sub EnableAndShowWSMergeMenu(ByVal v_blnEnable As Boolean, ByVal v_blnShow As Boolean)
    ' Workspace tool enabling - Note workspace menu's are usually hidden if workspaces are not enabled.
    ShowMenuTool fMainForm.ATB, fMainForm.ATB.Tools("SAIDM_421"), v_blnShow
    EnableMenuTool fMainForm.ATB.Tools("SAIDM_421"), v_blnEnable
End Sub
Public Function SetStateOfHeatMapManagerMenuItem()
    EnableMenuTool fMainForm.ATB.Tools("SAIDM_10048"), True   'DEV_STRING Enable Heat map manager menu
End Function

Private Function GetCommandLineOperand(CommandToFind As String, bRemove As Boolean) As String
    ' uses public variable commandline
    Dim cl As String
    Dim i As Long, String0, String1, String2
    cl = CommandLine
    i = InStr(LCase(cl) & Space(1), LCase(CommandToFind) & Space(1))
    If i = 0 Then
        GetCommandLineOperand = SA_VB_EmptyString
        Exit Function
    End If
    String0 = i
    i = i + Len(CommandToFind)
    While Mid(cl, i, 1) = Space(1): i = i + 1: Wend
    String1 = i
    If Mid(cl, i, 1) = Chr(34) Then
        i = i + 1
        String1 = i
        While i <= Len(cl) And Mid(cl, i, 1) <> Chr(34): i = i + 1: Wend
        If i > Len(cl) Then i = i + 1
        String2 = i
    Else
        While i <= Len(cl) And Mid(cl, i, 1) <> Space(1): i = i + 1: Wend
        If i > Len(cl) Then i = i + 1
        String2 = i
    End If
    GetCommandLineOperand = Mid(cl, String1, String2 - String1)
    If bRemove Then
        If Mid(cl, String2, 1) = Chr(34) Then String2 = String2 + 1
        CommandLine = Left(CommandLine, String0 - 1) & Mid(CommandLine, String2)
    End If
End Function

Public Function InCommandLine(CommandToFind As String, bRemove As Boolean) As Boolean
    ' uses public variable commandline
    Dim i As Long
    i = InStr(LCase(CommandLine) & Space(1), LCase(CommandToFind) & Space(1))
    If i = 0 Then
        InCommandLine = False
        Exit Function
    End If
    InCommandLine = True
    If bRemove Then
        ' note we add an extra 1 to the mid start point for the assumed space.
        CommandLine = Left(CommandLine, i - 1) & Mid(CommandLine, i + Len(CommandToFind) + 1)
    End If
End Function

'Public Sub SetDisplayOnTop(Activate As Boolean)
    'Dim frm As Form
    'For Each frm In Forms
    '    If TypeOf frm Is frmDisplay Then
    '        If Not Activate Then
    '            SetWindowPos frm.hWnd, HWND_NOTOPMOST, 0, 0, 0, _
    '                    0, SWP_NOACTIVATE Or SWP_SHOWWINDOW Or SWP_NOSIZE Or SWP_NOMOVE
    '        Else
    '            If frm.mnuPAlwaysOnTop.Checked Then
    ''                SetWindowPos frm.hWnd, HWND_TOPMOST, 0, 0, 0, 0, _
    '                        SWP_NOACTIVATE Or SWP_SHOWWINDOW Or SWP_NOSIZE Or SWP_NOMOVE
    '            End If
    '        End If
    '    End If
    'Next frm
'End Sub

Public Function SAGetGuiResources(Resource As Long) As Long
    ' this call was indroduced in windows 2000 and will fail in earlier versions
    On Error Resume Next
    SAGetGuiResources = GetGuiResources(GetCurrentProcess(), Resource)
    If Err Then SAGetGuiResources = 0
    On Error GoTo 0
End Function

Public Function SAGetSystemResources(Resource As Long) As Long
    ' this will fail in windows 2000
    On Error Resume Next
    SAGetSystemResources = MyGetFreeSystemResources(Resource)
    If Err Then SAGetSystemResources = 0
    On Error GoTo 0
End Function

Public Function CheckSystemResources() As Boolean
'''' JGC 16 June 1999 - we decided not to implement this for cut 6_2x5.
'''' It may be implemented later - I left in the code in MSAMain that reads
'''' the ini file entries adn defines the global variables CriticalSystemResources
'''' and LowSystemResources

    ' debug statements that only work in Windows 2000
    'LogMessage "GDI Resources used are " & Format(SAGetGuiResources(GR_GDIOBJECTS)) 'DEV_STRING
    'LogMessage "User Resources used are " & Format(SAGetGuiResources(GR_USEROBJECTS)) 'DEV_STRING

    CheckSystemResources = True ' assume success

    Dim errorflag As Boolean, SYSResources As Integer
    On Error GoTo ErrorHandler
    errorflag = False
    ' will fail in windows 2000
    SYSResources = MyGetFreeSystemResources(GFSR_SYSTEMRESOURCES)
    On Error GoTo 0
    If Not errorflag Then
        If SYSResources <= ExitSystemResources Then
            SAMessageBox SAXRes.GetLocalString(IDS_RunT_Sa2001Msamain____iamsorrybuticannotperformthisactionnow) _
                & vbCrLf & SAXRes.FormatLocalString(SAXRes.GetLocalString(IDS_RunT_Sa2001Msamain____resourcesquitanyprogramsthatyouarenotusing), CStr(100 - SYSResources)) _
                & vbCrLf & SAXRes.FormatLocalString(SAXRes.GetLocalString(IDS_sa2001msamainbas_____0willexittoallowyoursystemtorecover), SAXRes.GetLocalString(IDSProductName)) _
                , vbCritical Or vbApplicationModal
            Unload fMainForm
            CheckSystemResources = False ' failure
        ElseIf SYSResources <= CriticalSystemResources Then
            SAMessageBox SAXRes.GetLocalString(IDS_RunT_Sa2001Msamain____iamsorrybuticannotperformthisactionnow) _
                & vbCrLf & SAXRes.FormatLocalString(SAXRes.GetLocalString(IDS_RunT_Sa2001Msamain____resourcesquitanyprogramsthatyouarenotusing), CStr(100 - SYSResources)) _
                & vbCrLf & SAXRes.GetLocalString(IDS_RunT_Sa2001Msamain____resourcesquitanyprogramsthatyouarenotusing) _
                , vbCritical Or vbApplicationModal
            CheckSystemResources = False ' failure
        ElseIf SYSResources <= LowSystemResources Then
            SAMessageBox SAXRes.GetLocalString(IDS_RunT_Sa2001Msamain____warninglowresources) _
                & vbCrLf & SAXRes.FormatLocalString(SAXRes.GetLocalString(IDS_RunT_Sa2001Msamain____resourcesquitanyprogramsthatyouarenotusing), CStr(100 - SYSResources)) _
                & vbCrLf & SAXRes.GetLocalString(IDS_RunT_Sa2001Msamain____resourcesquitanyprogramsthatyouarenotusing) _
                , vbExclamation Or vbApplicationModal
        End If
    End If
    Exit Function

ErrorHandler:
    errorflag = True
    Resume Next
End Function

Public Function CloseChildForms(Optional bSaveForms As Boolean = False, Optional bSaveActivePane As Boolean = True) As Boolean
    bCancelShutDown = False                 ' global boolean
    Dim i As Long
    Dim iKept As Long
    Dim frm As Form
    Dim intCancel As Integer
    Dim intUnloadMode As Integer
    Dim objPane As Pane

    For i = 0 To Forms.Count - 1
        Set frm = Forms(i)
        On Error Resume Next
        ' the following function may not exist
        intUnloadMode = vbFormOwner
        intCancel = 0
        frm.QueryUnload intCancel, intUnloadMode
        If intCancel <> 0 Then
            CloseChildForms = True
            Exit Function
        End If
        On Error GoTo 0
    Next

    If (bSaveForms) Then
        fMainForm.Dock.SaveSpecialPanesState bSaveActivePane
    End If

    ' Close all remaining forms
    i = 0
    Do While i + iKept < Forms.Count
        For i = 0 To Forms.Count - 1
            Set frm = Forms(i)
'            MsgBox "Form is " & frm.Caption 'DEV_STRING
            Unload frm
        Next i
    Loop
End Function

Public Function CloseMDIChildForms() As Boolean
   'function was created for closing all open windows from menu Windows | All
    bCancelShutDown = False                 ' global boolean
    Dim i As Long
    Dim frm As Form
    Dim intCancel As Integer
    Dim intUnloadMode As Integer

    i = 0
    Do While i < Forms.Count
        For i = 0 To Forms.Count - 1
            Set frm = Forms(i)
            On Error Resume Next
            ' the following function may not exist
            intUnloadMode = vbFormOwner
            intCancel = 0
            frm.QueryUnload intCancel, intUnloadMode
            If intCancel <> 0 Then
                CloseMDIChildForms = True
                Exit Function
            End If
            On Error GoTo 0
        Next
    Loop

End Function

Public Function CloseDownApp() As Boolean
    ' we close child forms and hide the browser up front to avoid a
    ' GPF when exiting the app with the browser docked top
    ' this GPF is probably an interaction with ATBARS and FORMX
'''    CloseDownApp = CloseChildForms
'''    If Not CloseDownApp Then
'''        HideBrowse
        Unload fMainForm    ' shutdown
'''    End If
'''    'End
End Function

Public Function GetIniSetting(sSection As String, sEntry As String, Optional sDefault As String) As String
    Dim sValue As String, sDef As String
    Dim lRet As Long
    sDef = SA_VB_EmptyString
    If Not IsMissing(sDefault) Then sDef = sDefault
    sValue = String$(255, Space(1))
    lRet = SADUtilsVB_ReadSettingNTS(sSection, sEntry, sDef, sValue, Len(sValue), SA_VB_EmptyString)
    If lRet = 0 Then
        If sDef <> SA_VB_EmptyString Then
            GetIniSetting = sDef
        Else
            GetIniSetting = SA_VB_EmptyString
        End If
    Else
        GetIniSetting = szTruncate(sValue) ' Use szTruncate instead of Left and the length returned because of DBCS
    End If
    'GetIniSetting = Left(sValue, lRet)
End Function

Public Function bGetIniSetting(sSection As String, sEntry As String, sDefault As String) As Boolean
    Dim sValue As String

    sValue = UCase(GetIniSetting(sSection, sEntry, sDefault))
    If Len(sValue) > 0 Then
        sValue = Left(sValue, 1)
    End If
    If sValue = "Y" Or sValue = "T" Then 'DEV_STRING
        bGetIniSetting = True
    Else
        bGetIniSetting = False
    End If
End Function

Public Sub SetIniSetting(sSection As String, sEntry As String, sValue As String)
End Sub

Public Sub bSetIniSetting(sSection As String, sEntry As String, bValue As Boolean)
End Sub

Public Sub bSetIniSettingYN(sSection As String, sEntry As String, bValue As Boolean)
End Sub

Public Sub LoadIniSettings()

    strIconBaseName = GetIniSetting(SAXRes.GetLocalString(IDSProductIniSectionName), "IconBase", "BLU") 'DEV_STRING
    sLastVersionString = GetIniSetting(SAXRes.GetLocalString(IDSProductIniSectionName), SAXRes.GetLocalString(IDSProductAppName) & " version") 'DEV_STRING
    bShowBrowserUserFilters = bGetIniSetting(SAXRes.GetLocalString(IDSProductIniSectionName), "BrowserUserFilters", "N") 'DEV_STRING
    bEnableShowClassicBrowser = bGetIniSetting(SAXRes.GetLocalString(IDSProductIniSectionName), "EnableClassicExplorer", "Y") 'DEV_STRING
    bDetailPicture = bGetIniSetting(SAXRes.GetLocalString(IDSProductIniSectionName), "ShowPicturesInOpenDialog", "Y") 'DEV_STRING

    ' allow the user to stop checking ency lock counts
    bCheckEncyLocks = bGetIniSetting(SAXRes.GetLocalString(IDSProductIniSectionName), "CheckEncyLocks", "N") 'DEV_STRING

    ExitSystemResources = val(GetIniSetting(SAXRes.GetLocalString(IDSProductIniSectionName), "SystemResourcesExit", "1")) 'DEV_STRING
    CriticalSystemResources = val(GetIniSetting(SAXRes.GetLocalString(IDSProductIniSectionName), "SystemResourcesCritical", "5")) 'DEV_STRING
    LowSystemResources = val(GetIniSetting(SAXRes.GetLocalString(IDSProductIniSectionName), "SystemResourcesLow", "10")) 'DEV_STRING

    FSAMainLeft = val(GetIniSetting("Initial", "Left")) 'DEV_STRING
    FSAMainTop = val(GetIniSetting("Initial", "Top")) 'DEV_STRING
    FSAMainWidth = val(GetIniSetting("Initial", "Width")) 'DEV_STRING
    FSAMainHeight = val(GetIniSetting("Initial", "Height")) 'DEV_STRING
    FSAMain_State = val(GetIniSetting("Initial", "WindowState", CStr(vbMaximized))) 'DEV_STRING

    MacroLastPath = GetIniSetting("Macros", "LastMacroPath") 'DEV_STRING
    MacroOpenReadOnly = bGetIniSetting("Macros", "OpenReadOnly", "T") 'DEV_STRING

    Call SetMaxSymbolSelectStyle(val(GetIniSetting("Toolbox", "MaxSymbolSelectStyle", CStr(DEFAULT_MAX_SYMBOL_SELECTS_STYLE)))) 'DEV_STRING

    g_bIncludeJpegs = bGetIniSetting(SAXRes.GetLocalString(IDSProductIniSectionName), "IncludeJPEGinRAM", "Y") 'DEV_STRING
    'get the temp folder from ini
    Dim sTempDir As String
    sTempDir = ""
    g_BPMNTempPath = GetIniSetting("SA BPMN", "BPMNTempFolder", "")   'DEV_STRING
    If Len(g_BPMNTempPath) = 0 Then
        g_BPMNTempPath = SAVBUtils.SA_File_GetFolderLocation(0, SASF_TemporaryFolder)
    End If
    g_bDisplayOSLCHover = bGetIniSetting(SAXRes.GetLocalString(IDSProductIniSectionName), SAXRes.GetLocalString(IDSWININIDisplayOSLCHoverDialogs), "Y") 'DEV_STRING
End Sub

Public Sub SaveIniSettings()
    SetIniSetting SAXRes.GetLocalString(IDSProductIniSectionName), SAXRes.GetLocalString(IDSProductAppName) & " version", VersionString 'DEV_STRING

    SetIniSetting "Initial", "Left", Format(FSAMainLeft) 'DEV_STRING
    SetIniSetting "Initial", "Top", Format(FSAMainTop) 'DEV_STRING
    SetIniSetting "Initial", "Width", Format(FSAMainWidth) 'DEV_STRING
    SetIniSetting "Initial", "Height", Format(FSAMainHeight) 'DEV_STRING
    SetIniSetting "Initial", "WindowState", Format(FSAMain_State) 'DEV_STRING

    bSetIniSetting "Macros", "OpenReadOnly", MacroOpenReadOnly 'DEV_STRING
    SetIniSetting "Macros", "LastMacroPath", MacroLastPath 'DEV_STRING

    SetIniSetting SAXRes.GetLocalString(IDSProductIniSectionName), "XML_Encoding", "Unicode"    'DEV_STRING NB: the other option is "ASCII"

    ' QuickTips
    bSetIniSetting SAXRes.GetLocalString(IDSProductIniSectionName), "QTEnabled", TipsEnabled 'DEV_STRING
    SetIniSetting SAXRes.GetLocalString(IDSProductIniSectionName), "QTNextLine", Format(TipsNextLine) 'DEV_STRING
End Sub

Public Function lGetEncyLockCount() As Long
End Function

Public Function lCheckEncyLockCount(sCaption As String, lStartCount As Long) As Long
    On Error GoTo ErrorExit
    lCheckEncyLockCount = 0
    If bCheckEncyLocks Then
        lCheckEncyLockCount = lGetEncyLockCount()
        If lStartCount <> lCheckEncyLockCount Then
            SAMessageBox SAXRes.GetLocalString(IDS_RunT_Sa2001____encyleftopen), vbExclamation, SAXRes.GetLocalString(IDS_sa2001fbrowsertabconfigfrm_____configureexplorertabs)
            WriteSALog (SAXRes.GetLocalString(IDS_sa2001fbrowsertabconfigfrm_____configureexplorertabs) & " - " & SAXRes.GetLocalString(IDS_RunT_Sa2001____encyleftopen)) 'DEV_STRING
        End If
    End If
    Exit Function
ErrorExit:
        LogMessage "Error getting encyclopedia lock count: " & Err.Number & " - " & Err.Description 'DEV_STRING
End Function

Public Function SAMessageBox_Inner(bWantResult As Boolean, Prompt As String, Optional Buttons As VbMsgBoxStyle = vbOKOnly, _
                            Optional Title As String = "", Optional HelpFile As String = "", _
                            Optional CONTEXT) As VbMsgBoxResult 'DEV_STRING
    ' Simply used to allow the messagebox to only have a prompt, but default the title

    If Title = SA_VB_EmptyString Then
        Title = SAXRes.GetLocalString(IDSProductCaption)
    Else
        Title = SAXRes.GetLocalString(IDSProductCaption) + " - " + Title 'DEV_STRING
    End If


    LogMessage Title & " - " & Prompt 'DEV_STRING

    If blnCmdLineQuiet And Not CmdLineLog Then
        ' force log since this indicates a bug
        Call WriteSALog(SAXRes.GetLocalString(IDS_sa2001msamainbas_____messageboxrequested) & Title & " - " & Prompt) 'DEV_STRING
    End If

    If blnCmdLineQuiet And Not bWantResult Then
        SAMessageBox_Inner = 0 ' this is an invalid vbmsgboxresult
        Exit Function
    End If

    If HelpFile <> SA_VB_EmptyString Then
        SAMessageBox_Inner = MsgBox(Prompt, Buttons, Title, HelpFile, CONTEXT)
    Else
        SAMessageBox_Inner = MsgBox(Prompt, Buttons, Title)
    End If
End Function

Public Sub SAMessageBox(Prompt As String, Optional Buttons As VbMsgBoxStyle = vbOKOnly, _
                        Optional Title As String = "", Optional HelpFile As String = "", _
                        Optional CONTEXT) 'DEV_STRING
    Call SAMessageBox_Inner(False, Prompt, Buttons, Title, HelpFile, CONTEXT)
End Sub

Public Function SAMessageBoxWithResult(Prompt As String, Optional Buttons As VbMsgBoxStyle = vbOKOnly, _
                        Optional Title As String = "", Optional HelpFile As String = "", _
                        Optional CONTEXT) 'DEV_STRING
    SAMessageBoxWithResult = SAMessageBox_Inner(True, Prompt, Buttons, Title, HelpFile, CONTEXT)
End Function

Public Function GenericFormAlreadyDisplayed(LookForThisCaption As String) As Boolean
End Function


' Only to be invoked from EncyOpen, EncyClose, WorkspaceOpen events
Public Sub UpdateCaption()
    Dim strWorkspaceName    As String
    Dim strGCContextName    As String
    Dim strEncyName         As String
    Dim strTemp             As String
    Dim lngResult           As Long
    Const ABOUTITEM_ENCY = 4


    If Not fMainForm Is Nothing Then
        fMainForm.Caption = SAXRes.FormatLocalString(SAXRes.GetLocalString(IDS_sa2001msamain____caption), SAXRes.GetLocalString(IDSProductCaption), strEncyName, strGCContextName)
    End If
End Sub



' ClearINISetting - Delete an SA2001.ini setting,  if it already exists
'
' Params:
'   nSettingId - String ID of setting to delete (usually from Uloc_xxx.str)
Private Sub ClearINISetting(nSettingId As Long)
    If (GetIniSetting(SAXRes.GetLocalString(IDSProductIniSectionName), SAXRes.GetLocalString(nSettingId), "") <> vbNullString) Then
        SetIniSetting SAXRes.GetLocalString(IDSProductIniSectionName), SAXRes.GetLocalString(nSettingId), vbNullString
    End If
End Sub




Public Sub SetDockingPaneFont(objDockingPaneManager As DockingPane)
On Error GoTo ErrHandlerSetDockingPaneFont
    Dim CaptionFont As StdFont
   
    'Create a new font
    Set CaptionFont = SAUtilsFont
    If Not (CaptionFont Is Nothing) Then
        'Sets the font for the pane caption
        Set objDockingPaneManager.PaintManager.CaptionFont = CaptionFont
    
        'Sets the font for the tab buttons when not hidden.
        Set objDockingPaneManager.TabPaintManager.Font = CaptionFont
    
        'Sets the for for the tab buttons when hidden.
        Set objDockingPaneManager.PanelPaintManager.Font = CaptionFont
    End If
    Exit Sub
ErrHandlerSetDockingPaneFont:
    Err.Clear
End Sub

Public Function SAUtilsFont() As StdFont
On Error GoTo ErrHandlerSAUtilsFont
    Set SAUtilsFont = Nothing
    Dim SAFontName As String
    Dim SAFontSize As Long
    Dim SACharSet As Integer
    Dim SAFont As StdFont
    If GetSAFont(SAFontName, SAFontSize, SACharSet) = True Then
        'Create a new font
        Set SAFont = New StdFont
        SAFont.Name = SAFontName
        SAFont.Size = SAFontSize
        SAFont.Charset = SACharSet
        Set SAUtilsFont = SAFont
    End If
    Exit Function
ErrHandlerSAUtilsFont:
    Err.Clear
End Function

Public Function SAUtilsMenuFont() As StdFont
On Error GoTo ErrHandlerSAUtilsFont
    Set SAUtilsMenuFont = Nothing
    Dim SAFontName As String
    Dim SAFontSize As Long
    Dim SACharSet As Integer
    Dim SAFont As StdFont
    If GetSAMenuFont(SAFontName, SAFontSize, SACharSet) = True Then
        'Create a new font
        Set SAFont = New StdFont
        SAFont.Name = SAFontName
        SAFont.Size = SAFontSize
        SAFont.Charset = SACharSet
        Set SAUtilsMenuFont = SAFont
    End If
    Exit Function
ErrHandlerSAUtilsFont:
    Err.Clear
End Function

Public Function ClosePopups()
    On Error Resume Next
    fMainForm.ctlCommandBar.ClosePopups
End Function

