Function Windows_Services(@Service, @Params) /*********************************************************************************************************************** This program is proprietary and is not to be used by or disclosed to others, nor is it to be copied without written permission from SRP Computer Solutions, Inc. Name : Windows_Services Description : Handler program for all module related services. Notes : The generic parameters should contain all the necessary information to process the services. Often this will be information like the data Record and Key ID. Parameters : Service [in] -- Name of the service being requested Error [out] -- Any errors that were created Param1-10 [in/out] -- Additional request parameter holders Response [out] -- Response to be sent back to the Controller (MCP) or requesting procedure History : (Date, Initials, Notes) 05/14/13 dmb Original programmer. 05/15/13 dmb Add the IsRunning and Close service. Update the GetHandle service to use the GetTopWindow API function. 05/22/13 dmb Add Hide, Show, Maximize, and Minimize services (all based on the ShowWindow API). 10/02/13 dmb [SRPFW-18] Add IsVisible service. 11/11/13 dmb [SRPFW-75] Add RunEXE and OpenFile services. 11/12/13 dmb [SRPFW-76] Add KillEXE service. 03/28/20 dmb [SRPFW-304] Update services to use Error_Services when applicable. 05/13/20 dmb [SRPFW-312] Add MakeActive service. ***********************************************************************************************************************/ #pragma precomp SRP_PreCompiler $insert LOGICAL $insert SERVICE_SETUP // General Windows API equates Equ WM_USER to 1024 Equ WM_CLOSE to 16 Equ WM_COMMAND to 273 Equ WM_LBUTTONDOWN to 513 ; // 0x0201 Equ WM_LBUTTONUP to 514 ; // 0x0202 Equ WM_LBUTTONDBLCLK to 515 ; // 0x0203 Equ WM_RBUTTONDOWN to 516 ; // 0x0204 Equ WM_RBUTTONUP to 517 ; // 0x0205 Equ WM_PARENTNOTIFY to 528 ; // 0x0210 Equ WM_SYSCOLORCHANGE to 21 ; // 0x0015 Equ WM_SETCURSOR to 32 ; // 0x0020 Equ WM_SIZE to 5 ; // 0x0005 Equ WM_MOVE to 3 ; // 0x0003 Equ WM_GETMINMAXINFO to 36 ; // 0x0024 Equ WM_WINDOWPOSCHANGING to 70 // ShowWindow API equates Equ SW_FORCEMINIMIZE to 11 Equ SW_HIDE to 0 Equ SW_MAXIMIZE to 3 Equ SW_MINIMIZE to 6 Equ SW_RESTORE to 9 Equ SW_SHOW to 5 Equ SW_SHOWDEFAULT to 10 Equ SW_SHOWMAXIMIZED to 3 Equ SW_SHOWMINIMIZED to 2 Equ SW_SHOWMINNOACTIVE to 7 Equ SW_SHOWNA to 8 Equ SW_SHOWNOACTIVATE to 4 Equ SW_SHOWNORMAL to 1 Declare function Windows_Services, WinAPI_MoveWindow, WinAPI_GetWindowTextA, WinAPI_GetWindow, WinAPI_IsWindow Declare function FindWindow, PostMessage, ShowWindow, IsWindowVisible Declare function SRP_GetTopWindow, ShellExecute, Kill_Application, Utility Declare subroutine Windows_Services, SRP_SetForeGroundWindow GoToService else Error_Services('Set', Service : ' is not a valid service request within the ' : ServiceModule : ' services module.') end Return Response else '' //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Service Parameter Options //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Options BOOLEAN = True$, False$ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Services //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //---------------------------------------------------------------------------------------------------------------------- // SetSize // // Param1 - Handle to the window. // Param2 - Class Name to the window. This is ignored if there is a handle. // Param3 - Caption text of the window. This is ignored if there is a handle or class name. // Param4 - X Position. // Param5 - Y Position. // Param6 - Width. // Param7 - Height. // // Sets the size of the window. //---------------------------------------------------------------------------------------------------------------------- Service SetSize(Handle, ClassName, CaptionText, XPos, YPos, Width, Height) If Len(Handle) EQ 0 then Begin Case Case Len(ClassName) Handle = Windows_Services('GetHandle', ClassName) Case Len(CaptionText) Handle = Windows_Services('GetHandle', '', CaptionText) End Case end If Handle GT 0 then rv = WinAPI_MoveWindow(Handle, XPos, YPos, Width, Height, True$) end else Error_Services('Add', 'No valid window was passed in to the ' : Service : ' service.') end end service //---------------------------------------------------------------------------------------------------------------------- // IsRunning // // Param1 - Handle to the window. // Param2 - Class Name to the window. This is ignored if there is a handle. // Param3 - Caption text of the window. This is ignored if there is a handle or class name. // // Returns True if the window is running or False is not. //---------------------------------------------------------------------------------------------------------------------- Service IsRunning(Handle, ClassName, CaptionText) Begin Case Case Len(Handle) If WinAPI_IsWindow(Handle) else Handle = '' Case Len(ClassName) Handle = Windows_Services('GetHandle', ClassName) Case Len(CaptionText) Handle = Windows_Services('GetHandle', '', CaptionText) End Case Response = (Handle GT 0) end service //---------------------------------------------------------------------------------------------------------------------- // IsVisible // // Param1 - Handle to the window. // Param2 - Class Name to the window. This is ignored if there is a handle. // Param3 - Caption text of the window. This is ignored if there is a handle or class name. // // Returns True if the window is visible or False is not. //---------------------------------------------------------------------------------------------------------------------- Service IsVisible(Handle, ClassName, CaptionText) Begin Case Case Len(Handle) If WinAPI_IsWindow(Handle) else Handle = '' Case Len(ClassName) Handle = Windows_Services('GetHandle', ClassName) Case Len(CaptionText) Handle = Windows_Services('GetHandle', '', CaptionText) End Case Response = (IsWindowVisible(Handle) GT 0) end service //---------------------------------------------------------------------------------------------------------------------- // RunEXE // // Param1 - Full path and file name of the executable to run. // // Runs an executable program. This uses the RUNWIN service without any special flags. Therefore all executables will be // launched modelessly and in normal mode. //---------------------------------------------------------------------------------------------------------------------- Service RunEXE(PathToEXE) If Len(PathToEXE) then AppInfo = Utility('RUNWIN', PathToEXE) If Len(AppInfo<2>) else Error_Services('Add', Quote(PathToExe) : ' is an invalid executable file provided to the ' : Service : ' service.') end end else Error_Services('Add', 'No path to an executable file was provided to the ' : Service : ' service.') end end service //---------------------------------------------------------------------------------------------------------------------- // OpenFile // // Param1 - Full path and file name to open. // // Opens an OS file. This uses the ShellExecute Windows API without any special flags. //---------------------------------------------------------------------------------------------------------------------- Service OpenFile(PathToFile) If Len(PathToFile) then rv = ShellExecute('', 'open' : \00\, PathToFile : \00\, '' : \00\, '' : \00\, 0) end else Error_Services('Add', 'No path to a file was provided to the ' : Service : ' service.') end end service //---------------------------------------------------------------------------------------------------------------------- // Close // // Param1 - Handle to the window. // Param2 - Class Name to the window. This is ignored if there is a handle. // Param3 - Caption text of the window. This is ignored if there is a handle or class name. // // Close the window. If the class name or window caption is passed in, only the first instance of any window will be // closed. The developer will need to call the Close service multiple times until there are no more matching windows. //---------------------------------------------------------------------------------------------------------------------- Service Close(Handle, ClassName, CaptionText) If Len(Handle) EQ 0 then Begin Case Case Len(ClassName) Handle = Windows_Services('GetHandle', ClassName) Case Len(CaptionText) Handle = Windows_Services('GetHandle', '', CaptionText) End Case end If Handle GT 0 then rv = PostMessage(Handle, WM_CLOSE, 0, 0) end else Error_Services('Add', 'No valid window was passed in to the ' : Service : ' service.') end end service //---------------------------------------------------------------------------------------------------------------------- // KillEXE // // Param1 - Full path and file name of the executable to run. // Param2 - Caption text of the window. // // Attempts to kill a running executable program. Returns a 1 if successful, or a negative number if unsuccessful. //---------------------------------------------------------------------------------------------------------------------- Service KillEXE(EXEName, CaptionText) Results = '' If Len(EXEName) OR Len(CaptionText) then Results = Kill_Application(EXEName, CaptionText, TimeoutDelay, True$) end else Error_Services('Add', 'No valid executable file or caption was provided to the ' : Service : ' service.') end Response = Results end service //---------------------------------------------------------------------------------------------------------------------- // Hide // // Param1 - Handle to the window. // Param2 - Class Name to the window. This is ignored if there is a handle. // Param3 - Caption text of the window. This is ignored if there is a handle or class name. // // Hide the window. If the class name or window caption is passed in, only the first instance of any window will be // hidden. The developer will need to call the Hide service multiple times until there are no more matching windows. //---------------------------------------------------------------------------------------------------------------------- Service Hide(Handle, ClassName, CaptionText) CmdShow = SW_HIDE GoSub ShowWindowAPI end service //---------------------------------------------------------------------------------------------------------------------- // Show // // Param1 - Handle to the window. // Param2 - Class Name to the window. This is ignored if there is a handle. // Param3 - Caption text of the window. This is ignored if there is a handle or class name. // // Activates the window and displays it in its current size and position. If the class name or window caption is passed // in, only the first instance of any window will be hidden. The developer will need to call the Hide service multiple // times until there are no more matching windows. //---------------------------------------------------------------------------------------------------------------------- Service Show(Handle, ClassName, CaptionText) CmdShow = SW_SHOW GoSub ShowWindowAPI end service //---------------------------------------------------------------------------------------------------------------------- // Maximize // // Param1 - Handle to the window. // Param2 - Class Name to the window. This is ignored if there is a handle. // Param3 - Caption text of the window. This is ignored if there is a handle or class name. // // Maximizes the specified window. If the class name or window caption is passed in, only the first instance of any // window will be hidden. The developer will need to call the Hide service multiple times until there are no more // matching windows. //---------------------------------------------------------------------------------------------------------------------- Service Maximize(Handle, ClassName, CaptionText) CmdShow = SW_MAXIMIZE GoSub ShowWindowAPI end service //---------------------------------------------------------------------------------------------------------------------- // Minimize // // Param1 - Handle to the window. // Param2 - Class Name to the window. This is ignored if there is a handle. // Param3 - Caption text of the window. This is ignored if there is a handle or class name. // // Minimizes the specified window. If the class name or window caption is passed in, only the first instance of any // window will be hidden. The developer will need to call the Hide service multiple times until there are no more // matching windows. //---------------------------------------------------------------------------------------------------------------------- Service Minimize(Handle, ClassName, CaptionText) CmdShow = SW_MINIMIZE GoSub ShowWindowAPI end service //---------------------------------------------------------------------------------------------------------------------- // MakeActive // // Handle - Handle to the window. - [Required] // // Brings the window to the foreground and makes it active. This uses the SetForegroundWindow API: // https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setforegroundwindow //---------------------------------------------------------------------------------------------------------------------- Service MakeActive(Handle) If Handle NE '' then SRP_SetForeGroundWindow(Handle) end end service //---------------------------------------------------------------------------------------------------------------------- // GetHandle // // Param1 - Class Name to the window. // Param2 - Caption text of the window. This is ignored if there is a handle or class name. // Param3 - Flag that determines if all handles should be returned rather than the first match. Only works when finding // handles by CaptionText. // // Gets the handle for the window. //---------------------------------------------------------------------------------------------------------------------- Service GetHandle(ClassName, CaptionText, AllHandles) Handle = '' If AllHandles NE True$ then AllHandles = False$ Begin Case Case Len(ClassName) // The FindWindow API returns the handle of a valid class name that is already running. Handle = FindWindow(ClassName : \00\, '') Case Len(CaptionText) // The GetTopWindow API will return the handle of the first window running in z-order. StartHandle = SRP_GetTopWindow('') NextHandle = StartHandle TextBuffer = Str(\00\, 100) // The GetWindowText API will return the caption text of the window. rv = WinAPI_GetWindowTextA(NextHandle, TextBuffer, Len(TextBuffer)) ThisCaption = TextBuffer[1, \00\] If ThisCaption EQ CaptionText then Handle = NextHandle : @FM // If the top window is not a match, then use the GetWindow API to retrieve the next running window's // handle. Continue to loop through each window until a match is found or there are no more windows // to process. If Len(Handle) EQ 0 OR AllHandles = True$ then Loop Until (NextHandle EQ 0) OR (Len(Handle) AND AllHandles EQ False$) NextHandle = WinAPI_GetWindow(NextHandle, 2) TextBuffer = Str(\00\, 100) rv = WinAPI_GetWindowTextA(NextHandle, TextBuffer, Len(TextBuffer)) ThisCaption = TextBuffer[1, \00\] If ThisCaption EQ CaptionText then Locate NextHandle in Handle using @FM setting fPos else Handle := NextHandle : @FM end end Repeat end Handle[-1, 1] = '' ; // Strip off the final @FM End Case Response = Handle end service //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Internal GoSubs ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////? ShowWindowAPI: If Len(Handle) EQ 0 then Begin Case Case Len(ClassName) Handle = Windows_Services('GetHandle', ClassName) Case Len(CaptionText) Handle = Windows_Services('GetHandle', '', CaptionText) End Case end If Handle GT 0 then rv = ShowWindow(Handle, CmdShow) end else Error_Services('Add', 'No valid window was passed in to the ' : Service : ' service.') end return