<?xml version="1.0" encoding="utf-8"?>
<CrossEngineApp Version="1">
  <Options>object ProjOption: TProjectOptions
  Title = 'WM Query GUI'
  AppName = 'wmquerygui'
  Language = 'PASCAL'
  AppIcon.Data = {
[encoded data, 24771 characters]
    4336000000007FFF3132000000007FFF0A20
  }
  AppAutor = 'Copyright(c) 2020-2025 Alexey Kuryakin daqgroup@mail.ru'
  MinVMajor = 2
  MinVMinor = 1
  MinVRevision = 2
  ExternalPath = '$DIESELPASCAL_EXTERNAL;$DIESEL_LOCALSET_DIR/external;$DIESEL_EXE_DIR/external;'
  AutoCreateExternal.Strings = (
    'dpAntiZombie'
    'dpGuiResMain'
  )
end
</Options>
  <Metadata>
    <wmquerygui ImageIndex="2">
      <Object ClassName=""/>
      <Code>program wmquerygui;

uses dpCmdArgs,dpSystem,dpSysUtils,dpWindows,dpVbs,dpCrwDaqSys,dpDaqConfig,
     dpGuiResMain,Main;

begin
  InitGuiResMain; // Init GUI Resources - Main
  SetCrwDaqChildTitle('Window Manager Query GUI');
  if InstanceRunning(ValidateInstanceName(GetCrwDaqChildTitle),true) then begin
   AppActivateByClassTitle('Window',GetCrwDaqChildTitle);
   Application.Terminate;
   Exit;
  end;
  MainForm := TMainForm.Create(Application);
end.
</Code>
      <Child>
        <Main ImageIndex="1">
          <Object ClassName="TMainForm">object MainForm: TForm
  Left = 318
  Height = 600
  Top = 182
  Width = 800
  BorderWidth = 4
  Caption = 'MainForm'
  ClientHeight = 600
  ClientWidth = 800
  Constraints.MinHeight = 600
  Constraints.MinWidth = 800
  OnCreate = FormCreate
  ParentFont = True
  ShowHint = True
  LCLVersion = '3.6.0.0'
  object PanelMain: TPanel
    Left = 4
    Height = 592
    Top = 4
    Width = 792
    Align = alClient
    BorderWidth = 4
    ClientHeight = 592
    ClientWidth = 792
    TabOrder = 0
    object PageControlMain: TPageControl
      Left = 5
      Height = 582
      Top = 5
      Width = 782
      ActivePage = TabSheetWmquery
      Align = alClient
      Images = DataModuleGuiResMain.ImageListMain32x32
      TabIndex = 0
      TabOrder = 0
      object TabSheetWmquery: TTabSheet
        Caption = 'WM Query  '
        ClientHeight = 538
        ClientWidth = 772
        ImageIndex = 344
        OnEnter = TabSheetWmqueryEnter
        object PanelWinList: TPanel
          Left = 0
          Height = 440
          Top = 0
          Width = 772
          Align = alClient
          BorderWidth = 4
          ClientHeight = 440
          ClientWidth = 772
          TabOrder = 0
          object GroupBoxWinList: TGroupBox
            Left = 5
            Height = 217
            Top = 5
            Width = 762
            Align = alTop
            Caption = 'List of Desktop Windows'
            ClientHeight = 200
            ClientWidth = 760
            Constraints.MinHeight = 150
            TabOrder = 0
            object ListBoxWindows: TListBox
              Left = 0
              Height = 184
              Top = 16
              Width = 760
              Align = alClient
              ItemHeight = 0
              TabOrder = 0
              TopIndex = -1
              OnClick = ListBoxWindowsClick
            end
            object LabelWinHeader: TLabel
              Left = 0
              Height = 16
              Top = 0
              Width = 760
              Align = alTop
              Caption = 'Handle  Desktop  ProcessID  WindowClass  HostName  WindowTitle'
            end
          end
          object SplitterWinList: TSplitter
            Cursor = crVSplit
            Left = 5
            Height = 10
            Top = 222
            Width = 762
            Align = alTop
            Color = clSkyBlue
            MinSize = 150
            ParentColor = False
            ResizeAnchor = akTop
          end
          object GroupBoxWinProperties: TGroupBox
            Left = 5
            Height = 203
            Top = 232
            Width = 762
            Align = alClient
            Caption = 'Selected Window Properties'
            ClientHeight = 186
            ClientWidth = 760
            TabOrder = 2
            object MemoWinProperties: TMemo
              Left = 0
              Height = 186
              Top = 0
              Width = 760
              Align = alClient
              Color = clInfoBk
              HideSelection = False
              ReadOnly = True
              ScrollBars = ssAutoBoth
              TabOrder = 0
              WordWrap = False
            end
          end
        end
        object PanelWinButtons: TPanel
          Left = 0
          Height = 98
          Top = 440
          Width = 772
          Align = alBottom
          BorderWidth = 4
          ClientHeight = 98
          ClientWidth = 772
          TabOrder = 1
          object PanelWinUpdate: TPanel
            Left = 5
            Height = 88
            Top = 5
            Width = 134
            Align = alLeft
            ClientHeight = 88
            ClientWidth = 134
            TabOrder = 0
            object BitBtnWmQueryUpdate: TBitBtn
              Left = 4
              Height = 78
              Top = 4
              Width = 123
              Action = ActionWmQueryUpdate
              Layout = blGlyphBottom
              Images = DataModuleGuiResMain.ImageListMain32x32
              ImageIndex = 298
              TabOrder = 0
            end
          end
          object PanelWinActions: TPanel
            Left = 139
            Height = 88
            Top = 5
            Width = 628
            Align = alClient
            ClientHeight = 88
            ClientWidth = 628
            TabOrder = 1
            object PageControlWinActions: TPageControl
              Left = 1
              Height = 86
              Top = 1
              Width = 626
              ActivePage = TabSheetWmQueryMoveResizeWindow
              Align = alClient
              TabIndex = 1
              TabOrder = 0
              OnChange = PageControlWinActionsChange
              object TabSheetWmQueryShowWindow: TTabSheet
                Caption = 'Show/Hide  '
                ClientHeight = 58
                ClientWidth = 616
                object PanelWmQueryShowWindow: TPanel
                  Left = 0
                  Height = 58
                  Top = 0
                  Width = 616
                  Align = alClient
                  ClientHeight = 58
                  ClientWidth = 616
                  TabOrder = 0
                  object BitBtnWmQueryActivateWindow: TBitBtn
                    Left = 4
                    Height = 46
                    Top = 4
                    Width = 115
                    Action = ActionWmQueryActivateWindow
                    Images = DataModuleGuiResMain.ImageListMain32x32
                    ImageIndex = 164
                    TabOrder = 0
                  end
                  object BitBtnWmQueryShowWindow: TBitBtn
                    Left = 128
                    Height = 46
                    Top = 4
                    Width = 135
                    Action = ActionWmQueryShowWindow
                    Images = DataModuleGuiResMain.ImageListMain32x32
                    ImageIndex = 163
                    TabOrder = 1
                  end
                  object LabelWmQueryShowWindow: TLabel
                    Left = 272
                    Height = 16
                    Top = 4
                    Width = 128
                    Caption = 'ShowWindow Mode:'
                  end
                  object ComboBoxSwMode: TComboBox
                    Left = 268
                    Height = 28
                    Top = 20
                    Width = 152
                    ItemHeight = 0
                    ItemIndex = 1
                    Items.Strings = (
                      'HIDE'
                      'SHOWNORMAL'
                      'SHOWMINIMIZED'
                      'SHOWMAXIMIZED'
                      'SHOWNOACTIVATE'
                      'SHOW'
                      'MINIMIZE'
                      'SHOWMINNOACTIVE'
                      'SHOWNA'
                      'RESTORE'
                      'SHOWDEFAULT'
                    )
                    Style = csDropDownList
                    TabOrder = 2
                    Text = 'SHOWNORMAL'
                  end
                end
              end
              object TabSheetWmQueryMoveResizeWindow: TTabSheet
                Caption = 'Move/Size  '
                ClientHeight = 58
                ClientWidth = 616
                object PanelWmQueryMoveResizeWindow: TPanel
                  Left = 0
                  Height = 58
                  Top = 0
                  Width = 616
                  Align = alClient
                  ClientHeight = 58
                  ClientWidth = 616
                  TabOrder = 0
                  object BitBtnWmQueryMoveTo: TBitBtn
                    Left = 4
                    Height = 46
                    Top = 4
                    Width = 95
                    Action = ActionWmQueryMoveTo
                    Layout = blGlyphRight
                    Images = DataModuleGuiResMain.ImageListMain32x32
                    ImageIndex = 14
                    TabOrder = 0
                  end
                  object EditWmQueryLeft: TEdit
                    Left = 100
                    Height = 28
                    Top = 0
                    Width = 80
                    TabOrder = 1
                    Text = '0'
                  end
                  object EditWmQueryTop: TEdit
                    Left = 100
                    Height = 28
                    Top = 26
                    Width = 80
                    TabOrder = 2
                    Text = '0'
                  end
                  object LabelWmQueryLeft: TLabel
                    Left = 184
                    Height = 16
                    Top = 8
                    Width = 48
                    Caption = '&lt;-Left'
                  end
                  object LabelWmQueryTop: TLabel
                    Left = 184
                    Height = 16
                    Top = 32
                    Width = 40
                    Caption = '&lt;-Top'
                  end
                  object LabelWmQueryWidth: TLabel
                    Left = 248
                    Height = 16
                    Top = 8
                    Width = 64
                    Caption = ' Width-&gt;'
                  end
                  object LabelWmqueryHeight: TLabel
                    Left = 248
                    Height = 16
                    Top = 32
                    Width = 64
                    Caption = 'Height-&gt;'
                  end
                  object EditWmqueryWidth: TEdit
                    Left = 320
                    Height = 28
                    Top = 0
                    Width = 80
                    TabOrder = 3
                    Text = '0'
                  end
                  object EditWmqueryHeight: TEdit
                    Left = 320
                    Height = 28
                    Top = 26
                    Width = 80
                    TabOrder = 4
                    Text = '0'
                  end
                  object BitBtnWmQueryReSize: TBitBtn
                    Left = 400
                    Height = 46
                    Top = 4
                    Width = 95
                    Action = ActionWmQueryReSize
                    Images = DataModuleGuiResMain.ImageListMain32x32
                    ImageIndex = 15
                    TabOrder = 5
                  end
                  object ComboBoxWmQueryGravity: TComboBox
                    Left = 500
                    Height = 28
                    Top = 20
                    Width = 200
                    ItemHeight = 0
                    ItemIndex = 10
                    Items.Strings = (
                      '0  GDK_GRAVITY_DEFAULT'
                      '1  GDK_GRAVITY_NORTH_WEST'
                      '2  GDK_GRAVITY_NORTH'
                      '3  GDK_GRAVITY_NORTH_EAST'
                      '4  GDK_GRAVITY_WEST'
                      '5  GDK_GRAVITY_CENTER'
                      '6  GDK_GRAVITY_EAST'
                      '7  GDK_GRAVITY_SOUTH_WEST'
                      '8  GDK_GRAVITY_SOUTH'
                      '9  GDK_GRAVITY_SOUTH_EAST'
                      '10 GDK_GRAVITY_STATIC'
                    )
                    Style = csDropDownList
                    TabOrder = 6
                    Text = '10 GDK_GRAVITY_STATIC'
                  end
                  object LabelWmQueryGravity: TLabel
                    Left = 504
                    Height = 16
                    Top = 4
                    Width = 56
                    Caption = 'Gravity'
                  end
                end
              end
              object TabSheetWmQueryKillWindow: TTabSheet
                Caption = 'Kill  '
                ClientHeight = 58
                ClientWidth = 616
                object PanelWmQueryKillWindow: TPanel
                  Left = 0
                  Height = 58
                  Top = 0
                  Width = 616
                  Align = alClient
                  ClientHeight = 58
                  ClientWidth = 616
                  TabOrder = 0
                  object BitBtnWmQueryKillWindow: TBitBtn
                    Left = 4
                    Height = 46
                    Top = 4
                    Width = 99
                    Action = ActionWmQueryKillWindow
                    Images = DataModuleGuiResMain.ImageListMain32x32
                    ImageIndex = 23
                    TabOrder = 0
                  end
                  object LabelSigName: TLabel
                    Left = 108
                    Height = 16
                    Top = 4
                    Width = 88
                    Caption = 'Send SIGNAL'
                  end
                  object ComboBoxSigName: TComboBox
                    Left = 108
                    Height = 28
                    Top = 20
                    Width = 140
                    ItemHeight = 0
                    ItemIndex = 15
                    Items.Strings = (
                      ''
                      ' 1) SIGHUP'
                      ' 2) SIGINT'
                      ' 3) SIGQUIT'
                      ' 4) SIGILL'
                      ' 5) SIGTRAP'
                      ' 6) SIGABRT'
                      ' 7) SIGBUS'
                      ' 8) SIGFPE'
                      ' 9) SIGKILL'
                      '10) SIGUSR1'
                      '11) SIGSEGV'
                      '12) SIGUSR2'
                      '13) SIGPIPE'
                      '14) SIGALRM'
                      '15) SIGTERM'
                      '16) SIGSTKFLT'
                      '17) SIGCHLD'
                      '18) SIGCONT'
                      '19) SIGSTOP'
                      '20) SIGTSTP'
                      '21) SIGTTIN'
                      '22) SIGTTOU'
                      '23) SIGURG'
                      '24) SIGXCPU'
                      '25) SIGXFSZ'
                      '26) SIGVTALRM'
                      '27) SIGPROF'
                      '28) SIGWINCH'
                      '29) SIGIO'
                      '30) SIGPWR'
                      '31) SIGSYS'
                    )
                    Style = csDropDownList
                    TabOrder = 1
                    Text = '15) SIGTERM'
                  end
                end
              end
              object TabSheetWmQueryFind: TTabSheet
                Caption = 'Find  '
                ClientHeight = 58
                ClientWidth = 616
                object PanelWmQueryFind: TPanel
                  Left = 0
                  Height = 58
                  Top = 0
                  Width = 616
                  Align = alClient
                  ClientHeight = 58
                  ClientWidth = 616
                  TabOrder = 0
                  object BitBtnWmQueryFindProblems: TBitBtn
                    Left = 260
                    Height = 46
                    Top = 4
                    Width = 163
                    Action = ActionWmQueryFindProblems
                    Anchors = [akTop, akRight]
                    Images = DataModuleGuiResMain.ImageListMain32x32
                    ImageIndex = 252
                    TabOrder = 2
                  end
                  object BitBtnWmQueryGoToFound: TBitBtn
                    Left = 428
                    Height = 46
                    Top = 4
                    Width = 179
                    Action = ActionWmQueryGoToFound
                    Anchors = [akTop, akRight]
                    Images = DataModuleGuiResMain.ImageListMain32x32
                    ImageIndex = 60
                    TabOrder = 3
                  end
                  object BitBtnWmQueryFindWindows: TBitBtn
                    Left = 4
                    Height = 46
                    Top = 4
                    Width = 147
                    Action = ActionWmQueryFindWindows
                    Images = DataModuleGuiResMain.ImageListMain32x32
                    ImageIndex = 303
                    TabOrder = 0
                  end
                  object EditWmQueryFindWindows: TEdit
                    Left = 156
                    Height = 28
                    Top = 20
                    Width = 100
                    Anchors = [akTop, akLeft, akRight]
                    TabOrder = 1
                    Text = 'conky'
                  end
                  object LabelWmQueryFindWindows: TLabel
                    Left = 160
                    Height = 16
                    Top = 4
                    Width = 80
                    Caption = 'Key word …'
                  end
                end
              end
              object TabSheetWmQueryHelp: TTabSheet
                Caption = 'Help/Info  '
                ClientHeight = 58
                ClientWidth = 616
                object PanelWmQueryHelp: TPanel
                  Left = 0
                  Height = 58
                  Top = 0
                  Width = 616
                  Align = alClient
                  ClientHeight = 58
                  ClientWidth = 616
                  TabOrder = 0
                  object BitBtnWmQueryShowInfo: TBitBtn
                    Left = 140
                    Height = 46
                    Top = 4
                    Width = 131
                    Action = ActionWmQueryShowInfo
                    Images = DataModuleGuiResMain.ImageListMain32x32
                    ImageIndex = 124
                    TabOrder = 1
                  end
                  object BitBtnWmQueryHelp: TBitBtn
                    Left = 4
                    Height = 46
                    Top = 4
                    Width = 131
                    Action = ActionWmQueryHelp
                    Images = DataModuleGuiResMain.ImageListMain32x32
                    ImageIndex = 124
                    TabOrder = 0
                  end
                  object BitBtnWmQueryBrowseXdg: TBitBtn
                    Left = 276
                    Height = 46
                    Top = 4
                    Width = 131
                    Action = ActionWmQueryBrowseXdg
                    Images = DataModuleGuiResMain.ImageListMain32x32
                    ImageIndex = 124
                    TabOrder = 2
                  end
                end
              end
            end
          end
        end
      end
      object TabSheetTest: TTabSheet
        Caption = 'Test  '
        ClientHeight = 538
        ClientWidth = 772
        ImageIndex = 114
        object PanelMainContent: TPanel
          Left = 0
          Height = 472
          Top = 0
          Width = 772
          Align = alClient
          BorderWidth = 8
          ClientHeight = 472
          ClientWidth = 772
          TabOrder = 0
          object LabelMainExecUserCmnd: TLabel
            Left = 9
            Height = 16
            Top = 9
            Width = 754
            Align = alTop
            Caption = 'Result:'
            ParentColor = False
          end
          object MemoMainExecUserCmnd: TMemo
            Left = 9
            Height = 438
            Top = 25
            Width = 754
            Align = alClient
            Color = clInfoBk
            ReadOnly = True
            ScrollBars = ssAutoBoth
            TabOrder = 0
            WordWrap = False
          end
        end
        object PanelMainButtons: TPanel
          Left = 0
          Height = 66
          Top = 472
          Width = 772
          Align = alBottom
          BorderWidth = 8
          ClientHeight = 66
          ClientWidth = 772
          TabOrder = 1
          object LabeMainSendUserCmnd: TLabel
            Left = 8
            Height = 16
            Top = 10
            Width = 160
            Anchors = [akLeft, akBottom]
            Caption = 'User command to send'
            ParentColor = False
          end
          object EditMainSendUserCmnd: TEdit
            Left = 8
            Height = 28
            Hint = 'Input command to send to CRW-DAQ console.'
            Top = 22
            Width = 366
            Anchors = [akLeft, akRight, akBottom]
            TabOrder = 0
            Text = '@echo Hello, CRW-DAQ'
          end
          object BitBtnMainSendUserCmnd: TBitBtn
            Left = 382
            Height = 46
            Top = 12
            Width = 91
            Action = ActionMainSendUserCmnd
            Anchors = [akRight, akBottom]
            Images = DataModuleGuiResMain.ImageListMain32x32
            ImageIndex = 59
            TabOrder = 1
          end
          object BitBtnMainRunCrw32Ini: TBitBtn
            Left = 476
            Height = 46
            Top = 12
            Width = 91
            Action = ActionMainExecUserCmnd
            Anchors = [akRight, akBottom]
            Images = DataModuleGuiResMain.ImageListMain32x32
            ImageIndex = 114
            TabOrder = 2
          end
          object BitBtnMainProgramExit: TBitBtn
            Left = 572
            Height = 46
            Top = 12
            Width = 91
            Action = ActionMainProgramExit
            Anchors = [akRight, akBottom]
            ModalResult = 11
            Images = DataModuleGuiResMain.ImageListMain32x32
            ImageIndex = 113
            TabOrder = 3
          end
          object BitBtnMainParentShow: TBitBtn
            Left = 668
            Height = 46
            Top = 12
            Width = 91
            Action = ActionMainParentShow
            Anchors = [akRight, akBottom]
            ModalResult = 11
            Images = DataModuleGuiResMain.ImageListMain32x32
            ImageIndex = 234
            TabOrder = 4
          end
        end
      end
      object TabSheetLogEvents: TTabSheet
        BorderWidth = 8
        Caption = 'Log  '
        ClientHeight = 538
        ClientWidth = 772
        ImageIndex = 168
        object PanelLogEventsContent: TPanel
          Left = 0
          Height = 476
          Top = 0
          Width = 772
          Align = alClient
          BorderWidth = 8
          ClientHeight = 476
          ClientWidth = 772
          TabOrder = 0
          object LabelLogEvents: TLabel
            Left = 9
            Height = 16
            Top = 9
            Width = 754
            Align = alTop
            Caption = 'Event log (list of events occurred):'
            ParentColor = False
          end
          object MemoLogEvents: TMemo
            Left = 9
            Height = 424
            Top = 25
            Width = 754
            Align = alClient
            Color = clInfoBk
            ReadOnly = True
            ScrollBars = ssAutoBoth
            TabOrder = 0
            WordWrap = False
          end
          object StatusBarLogEvents: TStatusBar
            Left = 9
            Height = 18
            Top = 449
            Width = 754
            Panels = &lt;&gt;
          end
        end
        object PanelLogEventsButtons: TPanel
          Left = 0
          Height = 62
          Top = 476
          Width = 772
          Align = alBottom
          BorderWidth = 8
          ClientHeight = 62
          ClientWidth = 772
          TabOrder = 1
          object BitBtnLogEventsTest: TBitBtn
            Left = 481
            Height = 46
            Hint = 'Raise exception for test.'
            Top = 8
            Width = 91
            Anchors = [akTop, akRight]
            Caption = ' Test'
            Images = DataModuleGuiResMain.ImageListMain32x32
            ImageIndex = 115
            OnClick = BitBtnLogEventsTestClick
            TabOrder = 0
          end
          object BitBtnLogEventsClear: TBitBtn
            Left = 577
            Height = 46
            Top = 8
            Width = 91
            Action = ActionMainLogEventsClear
            Anchors = [akTop, akRight]
            Images = DataModuleGuiResMain.ImageListMain32x32
            ImageIndex = 119
            TabOrder = 1
          end
          object BitBtnLogEventsGoBack: TBitBtn
            Left = 673
            Height = 46
            Top = 8
            Width = 91
            Action = ActionMainLogEventsGoBack
            Anchors = [akTop, akRight]
            Images = DataModuleGuiResMain.ImageListMain32x32
            ImageIndex = 59
            TabOrder = 2
          end
          object LabelMainListSysInfo: TLabel
            Left = 8
            Height = 16
            Top = 8
            Width = 88
            Caption = 'Info topic:'
            ParentColor = False
          end
          object ComboBoxMainListSysInfo: TComboBox
            Left = 8
            Height = 28
            Top = 28
            Width = 182
            DropDownCount = 24
            ItemHeight = 0
            ItemIndex = 0
            Items.Strings = (
              'list environ'
              'list session'
              'list modules 0'
              'list process 0 0 *'
              'list windows 0 * *'
            )
            TabOrder = 3
            Text = 'list environ'
          end
          object LabelMainListSysInfoTimeOut: TLabel
            Left = 190
            Height = 16
            Top = 8
            Width = 56
            Caption = 'TimeOut'
            ParentColor = False
          end
          object SpinEditMainListSysInfoTimeOut: TSpinEdit
            Left = 190
            Height = 26
            Hint = 'Timeout for execution, sec.'
            Top = 26
            Width = 54
            MaxValue = 60
            MinValue = 1
            TabOrder = 4
            Value = 5
          end
          object BitBtnMainListSysInfo: TBitBtn
            Left = 246
            Height = 46
            Top = 8
            Width = 91
            Action = ActionMainListSysInfo
            Images = DataModuleGuiResMain.ImageListMain32x32
            ImageIndex = 124
            TabOrder = 5
          end
        end
      end
    end
  end
  object TimerLogEventsUpdater: TTimer
    OnTimer = TimerLogEventsUpdaterTimer
    Left = 356
  end
  object ActionListMain: TActionList
    Images = DataModuleGuiResMain.ImageListMain32x32
    Left = 320
    object ActionMainProgramExit: TAction
      Caption = 'Exit'
      Hint = 'Exit program.'
      ImageIndex = 113
      OnExecute = ActionMainExitExecute
    end
    object ActionMainParentShow: TAction
      Caption = 'Show'
      Hint = 'Open (activate) patent Crw32 program window.'
      ImageIndex = 234
      OnExecute = ActionMainParentShowExecute
    end
    object ActionMainFormShow: TAction
      Caption = 'Show MainForm'
      ImageIndex = 164
      OnExecute = ActionMainFormShowExecute
    end
    object ActionMainSendUserCmnd: TAction
      Caption = 'Send'
      Hint = 'Send command to CRW-DAQ  console.'
      ImageIndex = 59
      OnExecute = ActionMainSendUserCmndExecute
    end
    object ActionMainExecUserCmnd: TAction
      Caption = 'Exec'
      Hint = 'Run command from Crw32.ini list.'
      ImageIndex = 114
      OnExecute = ActionMainExecUserCmndExecute
    end
    object ActionMainLogEventsClear: TAction
      Caption = 'Clear'
      Hint = 'Clear event log.'
      ImageIndex = 119
      OnExecute = ActionMainLogEventsClearExecute
    end
    object ActionMainLogEventsGoBack: TAction
      Caption = 'Back'
      Hint = 'Go back to main page.'
      ImageIndex = 59
      OnExecute = ActionMainLogEventsGoBackExecute
    end
    object ActionMainListSysInfo: TAction
      Caption = 'Info'
      Hint = 'Print system information by specified topic.'
      ImageIndex = 124
      OnExecute = ActionMainListSysInfoExecute
    end
    object ActionWmQueryUpdate: TAction
      Caption = 'Update'
      ImageIndex = 298
      OnExecute = ActionWmqueryUpdateExecute
    end
    object ActionWmQueryMoveTo: TAction
      Caption = 'MoveTo'
      ImageIndex = 14
      OnExecute = ActionWmQueryMoveToExecute
    end
    object ActionWmQueryReSize: TAction
      Caption = 'ReSize'
      ImageIndex = 15
      OnExecute = ActionWmQueryReSizeExecute
    end
    object ActionWmQueryActivateWindow: TAction
      Caption = 'Activate'
      ImageIndex = 164
      OnExecute = ActionWmQueryActivateExecute
    end
    object ActionWmQueryShowWindow: TAction
      Caption = 'ShowWindow'
      ImageIndex = 163
      OnExecute = ActionWmQueryShowWindowExecute
    end
    object ActionWmQueryKillWindow: TAction
      Caption = 'Kill'
      ImageIndex = 23
      OnExecute = ActionWmQueryWinKillExecute
    end
    object ActionWmQueryShowInfo: TAction
      Caption = 'Show Info'
      ImageIndex = 124
      OnExecute = ActionWmQueryShowInfoExecute
    end
    object ActionWmQueryHelp: TAction
      Caption = 'Show Help'
      ImageIndex = 124
      OnExecute = ActionWmQueryHelpExecute
    end
    object ActionWmQueryBrowseXdg: TAction
      Caption = 'Browse XDG'
      ImageIndex = 124
      OnExecute = ActionWmQueryBrowseXdgExecute
    end
    object ActionWmQueryFindProblems: TAction
      Caption = 'Find Problems'
      ImageIndex = 252
      OnExecute = ActionWmQueryFindProblemsExecute
    end
    object ActionWmQueryGoToFound: TAction
      Caption = 'GoTo Found …'
      ImageIndex = 60
      OnExecute = ActionWmQueryGoToSelExecute
    end
    object ActionWmQueryFindWindows: TAction
      Caption = 'Find Windows'
      ImageIndex = 303
      OnExecute = ActionWmQueryFindWindowsExecute
    end
  end
  object TrayIconMain: TTrayIcon
    PopUpMenu = PopupMenuTray
    Icon.Data = {
[encoded data, 9514 characters]
      0000
    }
    OnClick = TrayIconMainClick
    OnDblClick = TrayIconMainDblClick
    Left = 392
  end
  object PopupMenuTray: TPopupMenu
    Images = DataModuleGuiResMain.ImageListMain32x32
    Left = 432
    object MenuItemTrayFormShow: TMenuItem
      Action = ActionMainFormShow
    end
    object MenuItemTrayParentShow: TMenuItem
      Action = ActionMainParentShow
    end
    object N1: TMenuItem
      Caption = '-'
    end
    object MenuItemTrayProgramExit: TMenuItem
      Action = ActionMainProgramExit
    end
  end
end
</Object>
          <Code>unit Main;

uses  dpCmdArgs,dpSystem,dpSysUtils,dpVbs,dpWindows,dpGuiUtils,
      dpCrwDaqSys,dpDaqConfig,dpAntiZombie,dpGuiResMain,WmqueryUtils;

type
  TMainForm = class(TForm)
    TimerLogEventsUpdater: TTimer;
    ActionListMain: TActionList;
    ActionMainProgramExit: TAction;
    ActionMainParentShow: TAction;
    ActionMainFormShow: TAction;
    ActionMainSendUserCmnd: TAction;
    ActionMainExecUserCmnd: TAction;
    ActionMainLogEventsClear: TAction;
    ActionMainLogEventsGoBack: TAction;
    // TrayIcon
    TrayIconMain: TTrayIcon;
    PopupMenuTray: TPopupMenu;
    MenuItemTrayFormShow: TMenuItem;
    MenuItemTrayParentShow: TMenuItem;
    MenuItemTrayProgramExit: TMenuItem;
    MenuItemTrayProgramExitSeparator: TMenuItem;
    // Main Panel
    PanelMain: TPanel;
    // Main TabSheep
    TabSheetTest: TTabSheet;
    PageControlMain: TPageControl;
    PanelMainContent: TPanel;
    LabelMainExecUserCmnd: TLabel;
    PanelMainButtons: TPanel;
    LabeMainSendUserCmnd: TLabel;
    EditMainSendUserCmnd: TEdit;
    BitBtnMainSendUserCmnd: TBitBtn;
    BitBtnMainRunCrw32Ini: TBitBtn;
    BitBtnMainProgramExit: TBitBtn;
    BitBtnMainParentShow: TBitBtn;
    // LogEvents TabSheet
    TabSheetLogEvents: TTabSheet;
    PanelLogEventsContent: TPanel;
    LabelLogEvents: TLabel;
    MemoLogEvents: TMemo;
    StatusBarLogEvents: TStatusBar;
    PanelLogEventsButtons: TPanel;
    BitBtnLogEventsTest: TBitBtn;
    BitBtnLogEventsClear: TBitBtn;
    BitBtnLogEventsGoBack: TBitBtn;
    MemoMainExecUserCmnd: TMemo;
    ActionMainListSysInfo: TAction;
    LabelMainListSysInfo: TLabel;
    ComboBoxMainListSysInfo: TComboBox;
    LabelMainListSysInfoTimeOut: TLabel;
    SpinEditMainListSysInfoTimeOut: TSpinEdit;
    BitBtnMainListSysInfo: TBitBtn;
    TabSheetWmquery: TTabSheet;
    PanelWinList: TPanel;
    PanelWinButtons: TPanel;
    GroupBoxWinList: TGroupBox;
    ListBoxWindows: TListBox;
    LabelWinHeader: TLabel;
    ActionWmQueryUpdate: TAction;
    SplitterWinList: TSplitter;
    GroupBoxWinProperties: TGroupBox;
    MemoWinProperties: TMemo;
    ActionWmQueryMoveTo: TAction;
    ActionWmQueryReSize: TAction;
    ActionWmQueryActivateWindow: TAction;
    PanelWinUpdate: TPanel;
    BitBtnWmQueryUpdate: TBitBtn;
    PanelWinActions: TPanel;
    PageControlWinActions: TPageControl;
    TabSheetWmQueryShowWindow: TTabSheet;
    PanelWmQueryShowWindow: TPanel;
    BitBtnWmQueryActivateWindow: TBitBtn;
    TabSheetWmQueryMoveResizeWindow: TTabSheet;
    PanelWmQueryMoveResizeWindow: TPanel;
    BitBtnWmQueryMoveTo: TBitBtn;
    EditWmQueryLeft: TEdit;
    EditWmQueryTop: TEdit;
    LabelWmQueryLeft: TLabel;
    LabelWmQueryTop: TLabel;
    LabelWmQueryWidth: TLabel;
    LabelWmqueryHeight: TLabel;
    EditWmqueryWidth: TEdit;
    EditWmqueryHeight: TEdit;
    BitBtnWmQueryReSize: TBitBtn;
    ActionWmQueryShowWindow: TAction;
    BitBtnWmQueryShowWindow: TBitBtn;
    LabelWmQueryShowWindow: TLabel;
    ComboBoxSwMode: TComboBox;
    TabSheetWmQueryHelp: TTabSheet;
    ActionWmQueryShowInfo: TAction;
    TabSheetWmQueryKillWindow: TTabSheet;
    PanelWmQueryHelp: TPanel;
    BitBtnWmQueryShowInfo: TBitBtn;
    PanelWmQueryKillWindow: TPanel;
    ActionWmQueryKillWindow: TAction;
    BitBtnWmQueryKillWindow: TBitBtn;
    LabelSigName: TLabel;
    ComboBoxSigName: TComboBox;
    ActionWmQueryHelp: TAction;
    BitBtnWmQueryHelp: TBitBtn;
    TabSheetWmQueryFind: TTabSheet;
    PanelWmQueryFind: TPanel;
    ActionWmQueryFindProblems: TAction;
    BitBtnWmQueryFindProblems: TBitBtn;
    ActionWmQueryGoToFound: TAction;
    BitBtnWmQueryGoToFound: TBitBtn;
    ActionWmQueryFindWindows: TAction;
    BitBtnWmQueryFindWindows: TBitBtn;
    EditWmQueryFindWindows: TEdit;
    LabelWmQueryFindWindows: TLabel;
    ActionWmQueryBrowseXdg: TAction;
    BitBtnWmQueryBrowseXdg: TBitBtn;
    ComboBoxWmQueryGravity: TComboBox;
    LabelWmQueryGravity: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure TrayIconMainClick(Sender: TObject);
    procedure TimerLogEventsUpdaterTimer(Sender: TObject);
    procedure ActionMainExitExecute(Sender: TObject);
    procedure ActionMainParentShowExecute(Sender: TObject);
    procedure ActionMainFormShowExecute(Sender: TObject);
    procedure ActionMainSendUserCmndExecute(Sender: TObject);
    procedure ActionMainExecUserCmndExecute(Sender: TObject);
    procedure ActionMainLogEventsClearExecute(Sender: TObject);
    procedure ActionMainLogEventsGoBackExecute(Sender: TObject);
    procedure ActionMainListSysInfoExecute(Sender: TObject);
    procedure BitBtnLogEventsTestClick(Sender: TObject);
    procedure TrayIconMainDblClick(Sender: TObject);
    procedure ListBoxWindowsClick(Sender: TObject);
    procedure TabSheetWmqueryEnter(Sender: TObject);
    procedure ActionWmqueryUpdateExecute(Sender: TObject);
    procedure ActionWmQueryMoveToExecute(Sender: TObject);
    procedure ActionWmQueryReSizeExecute(Sender: TObject);
    procedure ActionWmQueryActivateExecute(Sender: TObject);
    procedure ActionWmQueryShowWindowExecute(Sender: TObject);
    procedure ActionWmQueryShowInfoExecute(Sender: TObject);
    procedure ActionWmQueryWinKillExecute(Sender: TObject);
    procedure ActionWmQueryHelpExecute(Sender: TObject);
    procedure ActionWmQueryFindProblemsExecute(Sender: TObject);
    procedure ActionWmQueryGoToSelExecute(Sender: TObject);
    procedure PageControlWinActionsChange(Sender: TObject);
    procedure ActionWmQueryFindWindowsExecute(Sender: TObject);
    procedure ActionWmQueryBrowseXdgExecute(Sender: TObject);
  private
    myUpdateTrigger:Boolean;
  protected
  public
    procedure ShowTrayIcon;
    procedure AdjustComponents;
    procedure BugReport(E:Exception; Sender:TObject; Where:String);
    procedure SendCommandToCrwDaq(S:String; Activate:Boolean=true);
    procedure PostCommandToCrwDaq(S:String);
    procedure UpdateDesktopWindowsList;
    procedure UpdateWinProperties(Sel:Integer=0);
    procedure UpdateWinPropertiesByLine(Line:String);
    function  ListBoxWindowsSelectedLine:String;
    function  HasSelectedWindow:Boolean;
    procedure UpdateWinActions;
  end;

var MainForm: TMainForm;

implementation

procedure TMainForm.FormCreate(Sender: TObject);
begin
 try
  defIpcInit;
  defParamsInit;
  SetDefaultFontName(Font);
  InitAntiZombie(1000,true);
  Caption:=GetCrwDaqChildTitle;
  FormCenterToScreen(Self,0,0);
  SetButtonCursorToHandPoint(Self);
  StatusBarLogEvents.Font.Size:=10;
  PageControlMain.ActivePage:=TabSheetWmquery;
  PageControlWinActions.ActivePage:=TabSheetWmQueryShowWindow;
  LogEvents(Now,GetBriefEngineScriptInfo);
  LogEvents(Now,'Start.');
  AdjustComponents;
  ShowTrayIcon;
  if (CRW_DAQ_SYS_EXE_PID=0) then begin
   ActionMainParentShow.Enabled:=false;
   ActionMainSendUserCmnd.Enabled:=false;
   //RaiseException('Parent Crw32.exe process is not specified.');
  end;
  myUpdateTrigger:=true;
 except
  on E:Exception do Self.BugReport(E,Self,'FormCreate');
 end;
end;

procedure TMainForm.ShowTrayIcon;
begin
 Application.Title:=GetScriptName;
 TrayIconMain.Visible:=true;
 TrayIconMain.Hint:=GetScriptName+LineEnding+Caption;
 MenuItemTrayFormShow.Caption:=FormatVar('Show Window [%s]',Caption);
 MenuItemTrayProgramExit.Caption:=FormatVar('Exit from [%s]',Caption);
 MenuItemTrayParentShow.Caption:=FormatVar('Show Parent Window [%s]',ParentCrwDaqTitle);
 HideApplicationIconFromTaskBar(true);
end;

procedure RusCaption(C:TObject; ru:String);
begin
 if (ru='') or not Assigned(C) then Exit;
 if (C is TLabel) then with TLabel(C) do Caption:=RusEng(ru,Caption);
 if (C is TButton) then with TButton(C) do Caption:=RusEng(ru,Caption);
 if (C is TBitBtn) then with TBitBtn(C) do Caption:=RusEng(ru,Caption);
 if (C is TGroupBox) then with TGroupBox(C) do Caption:=RusEng(ru,Caption);
 if (C is TTabSheet) then with TTabSheet(C) do Caption:=RusEng(ru,Caption);
end;

procedure TMainForm.AdjustComponents;
const SIGINT=2;
begin
 MemoLogEvents.Font.Size:=10;
 if IsWindows then ComboBoxSigName.ItemIndex:=SIGINT;
 SetDefaultSansFontName(LabelMainListSysInfoTimeOut.Font);
 if (Screen.Width&gt;=1400) then FormCenterToScreen(Self,60,0);
 MemoWinProperties.Font.Color:=clNavy;
 RusCaption(TabSheetTest,'Тест  ');
 RusCaption(TabSheetLogEvents,'Журнал  ');
 RusCaption(GroupBoxWinList,'Список Окон на Рабочем Столе:');
 RusCaption(GroupBoxWinProperties,'Свойства Выбранного Окна:');
 RusCaption(TabSheetWmQueryShowWindow,'Отображение  ');
 RusCaption(TabSheetWmQueryMoveResizeWindow,'Сдвиг/Размер  ');
 RusCaption(TabSheetWmQueryKillWindow,'Завершение  ');
 RusCaption(TabSheetWmQueryHelp,'Справка  ');
 RusCaption(BitBtnWmQueryUpdate,'Обновить');
 RusCaption(BitBtnWmQueryActivateWindow,'Показать');
 RusCaption(BitBtnWmQueryShowWindow,'Отобразить');
 RusCaption(LabelWmQueryShowWindow,'Режим отображения:');
 RusCaption(BitBtnWmQueryShowInfo,'Информация');
 RusCaption(BitBtnWmQueryBrowseXdg,'Обзор XDG');
 RusCaption(BitBtnWmQueryHelp,'Справка');
 RusCaption(BitBtnWmQueryMoveTo,'Сдвиг');
 RusCaption(BitBtnWmQueryReSize,'Размер');
 RusCaption(BitBtnWmQueryKillWindow,'Убить');
 RusCaption(LabelSigName,'Послать СИГНАЛ:');
 RusCaption(LabelWmQueryLeft,'&lt;-Левый');
 RusCaption(LabelWmQueryTop,'&lt;-Верх');
 RusCaption(LabelWmQueryWidth,'Ширина-&gt;');
 RusCaption(LabelWmQueryHeight,'Высота-&gt;');
 RusCaption(TabSheetWmQueryFind,'Поиск  ');
 RusCaption(BitBtnWmQueryFindWindows,'Поиск Окон');
 RusCaption(BitBtnWmQueryFindProblems,'Поиск Проблем');
 RusCaption(BitBtnWmQueryGoToFound,'К Найденному …');
 RusCaption(LabelWmQueryFindWindows,'Искать по …');
 RusCaption(LabelWmQueryGravity,'Гравитация:');
 if IsUnix then EditWmQueryFindWindows.Text:='conky';
 if IsWindows then EditWmQueryFindWindows.Text:='cmd';
end;

procedure TMainForm.BugReport(E:Exception; Sender:TObject; Where:String);
begin
 SystemBugReport(E,Sender,Where);
 PageControlMain.ActivePage:=TabSheetLogEvents;
end;

procedure TMainForm.SendCommandToCrwDaq(S:String; Activate:Boolean=true);
begin
 try
  if (CRW_DAQ_SYS_EXE_PID=0)
  then RaiseException('Parent Crw32.exe process is not specified.');
  S:=Trim(S); if (S='') then Exit;
  if (CRW_DAQ_SYS_EXE_PID=0) then Exit;
  if Activate then AppActivateByTitle(ParentCrwDaqTitle);
  if (Send2CrwDaq(CRW_DAQ_SYS_EXE_PID,S,Handle)=0)
  then LogEvents(Now,'Sent command: '+S)
  else LogEvents(Now,'Fail command: '+S);
 except
  on E:Exception do Self.BugReport(E,Self,'SendCommandToCrwDaq');
 end;
end;

procedure TMainForm.PostCommandToCrwDaq(S:String);
begin
 SendCommandToCrwDaq(S,false);
end;

procedure TMainForm.TrayIconMainClick(Sender: TObject);
begin
 ActionMainFormShow.Execute;
end;

procedure TMainForm.TrayIconMainDblClick(Sender: TObject);
begin
 ActionMainFormShow.Execute;
end;

procedure TMainForm.UpdateDesktopWindowsList;
var cmd,arg,ans:String; Lines:TStringList; ii:Integer;
begin
 try
  arg:='ListWindows';
  cmd:=wmquery.Command(arg);
  ans:=wmquery.Execute(arg);
  if (ans&lt;&gt;'') then begin
   ans:=wmquery.FormatListWindows(ans,true);
   if (ans&lt;&gt;'') then begin
    Lines:=TStringList.Create;
    try
     Lines.Text:=ans;
     LabelWinHeader.Caption:=Lines.Strings[0];
     Lines.Delete(0); // Drop header from list
     ii:=ListBoxWindows.ItemIndex;
     ListBoxWindows.Items.Text:=Lines.Text;
     if (ii&lt;0) and (ListBoxWindows.Items.Count&gt;0) then ii:=0;
     if (ii&gt;=0) and (ii&lt;=ListBoxWindows.Count-1) then ListBoxWindows.ItemIndex:=ii;
    finally
     Lines.Free;
    end;
    UpdateWinProperties;
   end;
  end else begin
   ListBoxWindows.Items.Text:='';
   LabelWinHeader.Caption:=wmquery.HeaderLine;
   MemoWinProperties.Lines.Text:='Could not read List  of Windows.';
  end;
  UpdateWinActions;
 except
  on E:Exception do Self.BugReport(E,Self,'UpdateDesktopWindowsList');
 end;
end;

function TMainForm.ListBoxWindowsSelectedLine:String;
var ii:Integer;
begin
 Result:='';
 ii:=ListBoxWindows.ItemIndex;
 if (ii&gt;=0) and (ii&lt;=ListBoxWindows.Count-1)
 then Result:=ListBoxWindows.Items.Strings[ii];
end;

procedure TMainForm.UpdateWinProperties(Sel:Integer=0);
begin
 UpdateWinPropertiesByLine(ListBoxWindowsSelectedLine);
 if (Sel&gt;=0) then MemoWinProperties.SelStart:=Sel;
end;

procedure TMainForm.UpdateWinPropertiesByLine(Line:String);
var sWnd,sDesk,sPid,sClass,sHost,sTitle,sBounds:String;
var sLeft,sTop,sRight,sBottom,sWidth,sHeight:String;
var sPPid,sPrio,sTask,sProc:String; Pid:Integer;
var sWinType,sWinState:String;
var winOperable:Boolean;
begin
 try
  MemoWinProperties.Lines.Clear;
  if (Line&lt;&gt;'') then begin
   sWnd:=wmquery.ExtractWinListWnd(Line);
   sDesk:=wmquery.ExtractWinListDesk(Line);
   sPid:=wmquery.ExtractWinListPid(Line);
   sClass:=wmquery.ExtractWinListClass(Line);
   sHost:=wmquery.ExtractWinListHost(Line);
   sTitle:=wmquery.ExtractWinListTitle(Line);
   sBounds:=wmquery.Execute('WindowBounds -wnd '+sWnd);
   sLeft  :=Trim(ExtractWord(1,sBounds,' '));
   sTop   :=Trim(ExtractWord(2,sBounds,' '));
   sRight :=Trim(ExtractWord(3,sBounds,' '));
   sBottom:=Trim(ExtractWord(4,sBounds,' '));
   sWidth :=Trim(ExtractWord(5,sBounds,' '));
   sHeight:=Trim(ExtractWord(6,sBounds,' '));
   Pid:=StrToIntDef(sPid,0);
   if (Pid&gt;0) then sProc:=GetListOfProcesses(Pid,0,'') else sProc:='';
   sPPid  :=Trim(ExtractWord(2,sProc,' ,'));
   sPrio  :=Trim(ExtractWord(3,sProc,' ,'));
   sTask  :=Trim(ExtractWord(4,sProc,' ,'));
   sWinType:=wmquery.Execute('WindowTypeList -wnd '+sWnd);
   sWinState:=wmquery.Execute('WindowStateList -wnd '+sWnd);
   sWinType:=StringReplace(Trim(sWinType),EOL,', ',rfReplaceAll);
   sWinState:=StringReplace(Trim(sWinState),EOL,',',rfReplaceAll);
   MemoWinProperties.Lines.Add('Handle        = '+sWnd);
   MemoWinProperties.Lines.Add('Desktop       = '+sDesk);
   MemoWinProperties.Lines.Add('ProcessID     = '+sPid);
   MemoWinProperties.Lines.Add('ParentPID     = '+sPPid);
   MemoWinProperties.Lines.Add('Priority      = '+sPrio);
   MemoWinProperties.Lines.Add('TaskName      = '+sTask);
   MemoWinProperties.Lines.Add('WindowClass   = '+sClass);
   MemoWinProperties.Lines.Add('HostName      = '+sHost);
   MemoWinProperties.Lines.Add('WindowTitle   = '+sTitle);
   MemoWinProperties.Lines.Add('LeftTop       = '+sLeft+', '+sTop);
   MemoWinProperties.Lines.Add('RightBottom   = '+sRight+', '+sBottom);
   MemoWinProperties.Lines.Add('WidthHeight   = '+sWidth+', '+sHeight);
   MemoWinProperties.Lines.Add('WindowType    = '+sWinType);
   MemoWinProperties.Lines.Add('WindowState   = '+sWinState);
   EditWmqueryLeft.Text:=sLeft;
   EditWmQueryTop.Text:=sTop;
   EditWmqueryWidth.Text:=sWidth;
   EditWmQueryHeight.Text:=sHeight;
   winOperable:=wmquery.IsValidWnd(sWnd) and (sTitle&lt;&gt;'');
   PanelWmQueryShowWindow.Enabled:=winOperable;
   PanelWmQueryMoveResizeWindow.Enabled:=winOperable;
   PanelWmQueryKillWindow.Enabled:=winOperable and (Pid&gt;0);
   BitBtnWmQueryGoToFound.Enabled:=false;
  end;
 except
  on E:Exception do Self.BugReport(E,Self,'UpdateWinPropertiesByLine');
 end;
end;

procedure TMainForm.ListBoxWindowsClick(Sender: TObject);
begin
 try
  UpdateWinProperties;
  if (PageControlWinActions.ActivePage=TabSheetWmQueryFind)
  then PageControlWinActions.ActivePage:=TabSheetWmQueryShowWindow;
 except
  on E:Exception do Self.BugReport(E,Self,'ListBoxWindowsClick');
 end;
end;

procedure TMainForm.TabSheetWmqueryEnter(Sender: TObject);
begin
 //UpdateDesktopWindowsList;
end;

procedure TMainForm.ActionWmqueryUpdateExecute(Sender: TObject);
begin
 UpdateDesktopWindowsList;
end;

 // unix wmquery MoveResizeWindow -wnd WND -geom g,x,y,w,h
procedure TMainForm.ActionWmQueryMoveToExecute(Sender: TObject);
var sWnd,sGravity,sLeft,sTop,sPos,sTit,sMsg,arg,ans:String;
var iLeft,iTop,iGravity:Integer;
begin
 try
  sWnd:=wmquery.ExtractWinListWnd(ListBoxWindowsSelectedLine);
  if wmquery.IsValidWnd(sWnd) then begin
   iGravity:=ComboBoxWmQueryGravity.ItemIndex;
   if (iGravity&lt;0) then iGravity:=GDK_GRAVITY_STATIC;
   sGravity:=IntToStr(iGravity);
   sLeft:=Trim(EditWmqueryLeft.Text);
   sTop:=Trim(EditWmQueryTop.Text);
   if TryStrToInt(sLeft,iLeft) then
   if TryStrToInt(sTop,iTop) then begin
    sTit:=RusEng('Вопрос','Question');
    sPos:=IntToStr(iLeft)+','+IntToStr(iTop);
    sMsg:=RusEng('Хотите Изменить для Выбранного Окна ('+sWnd+') Положение (',
                 'Please Confirm Selected Window ('+sWnd+') MoveTo (')+sPos+')?';
    if (MessageBox(sMsg,sTit,MB_YESNOCANCEL+MB_ICONQUESTION)=mrYes) then begin
     arg:='MoveResizeWindow -wnd '+sWnd+' -geom '+sGravity+','+sPos;
     ans:=wmquery.Execute(arg);
     LogEvents(Now,wmquery.Command(arg)+EOL+ans);
     UpdateWinProperties;
    end;
   end;
  end;
 except
  on E:Exception do Self.BugReport(E,Self,'ActionWmQueryMoveToExecute');
 end;
end;

procedure TMainForm.ActionWmQueryReSizeExecute(Sender: TObject);
var sWnd,sGravity,sWidth,sHeight,sSize,sTit,sMsg,arg,ans:String;
var iWidth,iHeight,iGravity:Integer;
begin
 try
  sWnd:=wmquery.ExtractWinListWnd(ListBoxWindowsSelectedLine);
  if wmquery.IsValidWnd(sWnd) then begin
   iGravity:=ComboBoxWmQueryGravity.ItemIndex;
   if (iGravity&lt;0) then iGravity:=GDK_GRAVITY_STATIC;
   sGravity:=IntToStr(iGravity);
   sWidth:=Trim(EditWmqueryWidth.Text);
   sHeight:=Trim(EditWmQueryHeight.Text);
   if TryStrToInt(sWidth,iWidth) then
   if TryStrToInt(sHeight,iHeight) then begin
    sTit:=RusEng('Вопрос','Question');
    sSize:=IntToStr(iWidth)+','+IntToStr(iHeight);
    sMsg:=RusEng('Хотите Изменить для Выбранного Окна ('+sWnd+') Размер (',
                 'Please Confirm Selected Window ('+sWnd+') ReSize (')+sSize+')?';
    if (MessageBox(sMsg,sTit,MB_YESNOCANCEL+MB_ICONQUESTION)=mrYes) then begin
     arg:='MoveResizeWindow -wnd '+sWnd+' -geom '+sGravity+',*,*,'+sSize;
     ans:=wmquery.Execute(arg);
     LogEvents(Now,wmquery.Command(arg)+EOL+ans);
     UpdateWinProperties;
    end;
   end;
  end;
 except
  on E:Exception do Self.BugReport(E,Self,'ActionWmQueryMoveToExecute');
 end;
end;

procedure TMainForm.ActionWmQueryActivateExecute(Sender: TObject);
var sWnd,arg,ans:String;
begin
 try
  sWnd:=wmquery.ExtractWinListWnd(ListBoxWindowsSelectedLine);
  if wmquery.IsValidWnd(sWnd) then begin
   if IsWindows then begin
    arg:='ShowWindow -wnd '+sWnd+' -sw ShowNormal';
    ans:=wmquery.Execute(arg);
    LogEvents(Now,wmquery.Command(arg)+EOL+ans);
   end;
   arg:='ActivateWindow -wnd '+sWnd;
   ans:=wmquery.Execute(arg);
   LogEvents(Now,wmquery.Command(arg)+EOL+ans);
   UpdateWinProperties;
  end;
 except
  on E:Exception do Self.BugReport(E,Self,'ActionWmQueryActivateExecute');
 end;
end;

procedure TMainForm.ActionWmQueryShowWindowExecute(Sender: TObject);
var sWnd,arg,ans,swm:String;
begin
 try
  sWnd:=wmquery.ExtractWinListWnd(ListBoxWindowsSelectedLine);
  if wmquery.IsValidWnd(sWnd) then begin
   swm:=Trim(ComboBoxSwMode.Text);
   arg:='ShowWindow -wnd '+sWnd+' -sw '+swm;
   ans:=wmquery.Execute(arg);
   LogEvents(Now,wmquery.Command(arg)+EOL+ans);
   UpdateWinProperties;
  end;
 except
  on E:Exception do Self.BugReport(E,Self,'ActionWmQueryShowWindowExecute');
 end;
end;

procedure TMainForm.ActionWmQueryShowInfoExecute(Sender: TObject);
var arg,cmd,ans:String; List:TStrings;
 procedure AddInfo(what:String);
 begin
  arg:=what;
  ans:=wmquery.Execute(arg);
  cmd:=wmquery.Command(arg);
  LogEvents(Now,wmquery.Command(arg)+EOL+ans);
  List.Add(cmd+EOL+StringOfChar('#',Length(cmd))+EOL+TrimRight(ans)+EOL);
 end;
begin
 try
  List:=MemoWinProperties.Lines;
  if Assigned(List) then begin
   List.Clear;
   AddInfo('DisplayInfo');
   if IsUnix then begin
    AddInfo('XLibInfo');
    AddInfo('ListDesktopManagers');
    AddInfo('WindowManagerName');
    AddInfo('SupportedList');
    AddInfo('ListTerminals');
   end;
  end;
 except
  on E:Exception do Self.BugReport(E,Self,'ActionWmQueryShowInfoExecute');
 end;
end;

procedure TMainForm.ActionWmQueryWinKillExecute(Sender: TObject);
var sWnd,sPid,sTit,sMsg,sCap,arg,cmd,ans,sig:String; iPid,Timeout:Integer;
begin
 try
  sWnd:=wmquery.ExtractWinListWnd(ListBoxWindowsSelectedLine);
  sPid:=wmquery.ExtractWinListPid(ListBoxWindowsSelectedLine);
  sTit:=wmquery.ExtractWinListTitle(ListBoxWindowsSelectedLine);
  iPid:=StrToIntDef(sPid,0); Timeout:=1000;
  if wmquery.IsValidWnd(sWnd) and (iPid&gt;0) and (sTit&lt;&gt;'') then begin
   sCap:=RusEng('Вопрос','Question');
   sMsg:=RusEng('Хотите УБИТЬ Окно ('+sWnd+') с Заголовком (',
                'You sure to KILL Window ('+sWnd+') with Title (')+sTit+')?';
   if (MessageBox(sMsg,sCap,MB_YESNOCANCEL+MB_ICONQUESTION)=mrYes) then begin
    sig:=Trim(ExtractWord(2,ComboBoxSigName.Text,' '));
    if (sig&lt;&gt;'') then sig:=' -sig '+sig+' ';
    arg:='KillWindow -wnd '+sWnd+sig+' -timeout '+IntToStr(timeout);
    ans:=wmquery.Execute(arg);
    cmd:=wmquery.Command(arg);
    LogEvents(Now,cmd+EOL+ans);
    myUpdateTrigger:=true;
   end;
  end;
 except
  on E:Exception do Self.BugReport(E,Self,'ActionWmQueryWinKillExecute');
 end;
end;

procedure TMainForm.ActionWmQueryHelpExecute(Sender: TObject);
var arg,cmd,ans,msg:String;
begin
 try
  arg:='--help';
  ans:=wmquery.Execute(arg);
  cmd:=wmquery.Command(arg);
  LogEvents(Now,cmd+EOL+ans);
  msg:=cmd+EOL+StringOfChar('#',Length(cmd))+EOL+ans;
  MemoWinProperties.Lines.Text:=msg;
 except
  on E:Exception do Self.BugReport(E,Self,'ActionWmQueryHelpExecute');
 end;
end;

procedure TMainForm.ActionWmQueryFindProblemsExecute(Sender: TObject);
var i,problems:Integer;
 procedure HasProblem(Line:String):Boolean;
 var Pid,wLeft,wTop,wRight,wBottom,dLeft,dTop,dRight,dBottom:Integer;
 var sWnd,sDesk,sPid,sClass,sHost,sTitle,sBounds,Bugs:String;
 var sLeft,sTop,sRight,sBottom,sWidth,sHeight:String;
  procedure Problem(msg:String);
  begin
   MemoWinProperties.Lines.Add(' '+sWnd+FormatVar(': %-40s -&gt; ',msg)+sTitle);
  end;
  function InRect(x,y:Integer; L,T,R,B:Integer):Boolean;
  begin
   Result:=false;
   if (x&lt;L) or (x&gt;R) then Exit;
   if (y&lt;T) or (y&gt;B) then Exit;
   Result:=True;
  end;
  function InScreen(L,T,R,B:Integer):Boolean;
  begin
   Result:=InRect(L,T,dLeft,dTop,dRight,dBottom)
       and InRect(L,B,dLeft,dTop,dRight,dBottom)
       and InRect(R,T,dLeft,dTop,dRight,dBottom)
       and InRect(R,B,dLeft,dTop,dRight,dBottom);
  end;
 begin
  Result:=false;
  Line:=Trim(Line); Bugs:='';
  if (Line&lt;&gt;'') then begin
   sWnd:=wmquery.ExtractWinListWnd(Line);
   sDesk:=wmquery.ExtractWinListDesk(Line);
   sPid:=wmquery.ExtractWinListPid(Line);
   sClass:=wmquery.ExtractWinListClass(Line);
   sHost:=wmquery.ExtractWinListHost(Line);
   sTitle:=wmquery.ExtractWinListTitle(Line);
   sBounds:=wmquery.Execute('WindowBounds -wnd '+sWnd);
   sLeft  :=Trim(ExtractWord(1,sBounds,' '));
   sTop   :=Trim(ExtractWord(2,sBounds,' '));
   sRight :=Trim(ExtractWord(3,sBounds,' '));
   sBottom:=Trim(ExtractWord(4,sBounds,' '));
   sWidth :=Trim(ExtractWord(5,sBounds,' '));
   sHeight:=Trim(ExtractWord(6,sBounds,' '));
   wLeft  :=StrToIntDef(sLeft,0);
   wTop   :=StrToIntDef(sTop,0);
   wRight :=StrToIntDef(sRight,0);
   wBottom:=StrToIntDef(sBottom,0);
   dLeft:=Screen.DesktopLeft;
   dTop:=Screen.DesktopTop;
   dRight:=dLeft+Screen.DesktopWidth;
   dBottom:=dTop+Screen.DesktopHeight;
   Pid:=StrToIntDef(sPid,0);
   if not wmquery.IsValidWnd(sWnd) then begin
    Bugs:=Bugs+' Handle';
    Result:=true;
   end;
   if (StrToIntDef(sDesk,-1)&lt;0) then begin
    Bugs:=Bugs+' Desktop';
    Result:=true;
   end;
   if (pid&lt;=0) then begin
    Bugs:=Bugs+' PID';
    Result:=true;
   end;
   if not InScreen(wLeft,wTop,wRight,wBottom) then begin
    Bugs:=Bugs+'WindowBounds';
    Result:=true;
   end;
   Bugs:=Trim(Bugs);
   Bugs:=StringReplace(Bugs,' ',',',rfReplaceAll);
   if Result then Problem('Invalid '+Bugs+'.');
  end;
 end;
begin
 try
  UpdateDesktopWindowsList;
  MemoWinProperties.Clear; problems:=0;
  MemoWinProperties.Lines.Add('Поиск проблем:');
  MemoWinProperties.Lines.Add('##############');
  for i:=0 to ListboxWindows.Count-1 do begin
   if HasProblem(ListboxWindows.Items.Strings[i])
   then inc(problems);
  end;
  BitBtnWmQueryGoToFound.Enabled:=(problems&gt;0);
  MemoWinProperties.Lines.Add(RusEng('Найдено Проблем: ','Problem(s) found: ')+IntToStr(problems));
 except
  on E:Exception do Self.BugReport(E,Self,'ActionWmQueryFindProblemsExecute');
 end;
end;

procedure TMainForm.ActionWmQueryGoToSelExecute(Sender: TObject);
const HexChars=['0'..'9','A'..'F','a'..'f','x','X'];
const EolChars=[#13,#10,#0]; SpaceChars=[#0..' '];
var sel,sWnd,msg,s:String; i,n:Integer;
begin
 try
  n:=0; // Try to select Wnd
  i:=MemoWinProperties.SelStart;
  s:=MemoWinProperties.Lines.Text;
  while (i&gt;0) and not (StrFetch(s,i+1) in EolChars) do dec(i);
  while (i&lt;Length(s)) and (StrFetch(s,i+1) in SpaceChars) do inc(i);
  while (i+n&lt;Length(s)) and (StrFetch(s,i+1+n) in HexChars) do inc(n);
  MemoWinProperties.SelStart:=i; MemoWinProperties.SelLength:=n;
  // GoTo selected Wnd
  sel:=MemoWinProperties.SelText;
  if wmquery.IsValidWnd(sel) then begin
   for i:=0 to ListBoxWindows.Count-1 do begin
    sWnd:=wmquery.ExtractWinListWnd(ListBoxWindows.Items.Strings[i]);
    if not wmquery.IsValidWnd(sWnd) then continue;
    if IsSameText(sel,sWnd) then begin
     ListBoxWindows.ItemIndex:=i;
     MemoWinProperties.SetFocus;
     //ListBoxWindows.SetFocus;
     Break;
    end;
   end;
  end else begin
   msg:=RusEng('В окне "Свойства выбранного Окна" не указано целевое окно.',
               'Target Window is not selected in "Window Properties" viewer.');
   ShowMessage(msg);
  end;
 except
  on E:Exception do Self.BugReport(E,Self,'ActionWmQueryGoToSelExecute');
 end;
end;

function TMainForm.HasSelectedWindow:Boolean;
var sWnd,xWnd:String;
begin
 Result:=false;
 try
 sWnd:=wmquery.ExtractWinListWnd(ListBoxWindowsSelectedLine);
 xWnd:=wmquery.GetStringsValue(MemoWinProperties.Lines,'Handle');
 if not SameText(sWnd,xWnd) then Exit;
 Result:=wmquery.IsValidWnd(sWnd);
 except
  on E:Exception do BugReport(E,Self,'HasSelectedWindow');
 end;
end;

procedure TMainForm.UpdateWinActions;
var n,Pid:Integer; sTitle:String;
var winOperable:Boolean;
begin
 try
  n:=ListBoxWindows.Count;
  sTitle:=wmquery.GetStringsValue(MemoWinProperties.Lines,'WindowTitle');
  Pid:=StrToIntDef(wmquery.GetStringsValue(MemoWinProperties.Lines,'ProcessID'),0);
  winOperable:=(n&gt;0) and HasSelectedWindow and (sTitle&lt;&gt;'');
  PanelWmQueryShowWindow.Enabled:=(n&gt;0) and winOperable;
  PanelWmQueryMoveResizeWindow.Enabled:=(n&gt;0) and winOperable;
  PanelWmQueryKillWindow.Enabled:=(n&gt;0) and winOperable and (Pid&gt;0);
  BitBtnWmQueryGoToFound.Enabled:=false;
  PanelWmQueryFind.Enabled:=(n&gt;0);
 except
  on E:Exception do BugReport(E,Self,'UpdateWinActions');
 end;
end;

procedure TMainForm.PageControlWinActionsChange(Sender: TObject);
begin
 UpdateWinActions;
end;

procedure TMainForm.ActionWmQueryFindWindowsExecute(Sender: TObject);
var kw:String; i,Matches:Integer;
 function HasMatch(s,key:String):Boolean;
 begin
  Result:=(Pos(UpperCase(key),UpperCase(s))&gt;0);
  if Result then MemoWinProperties.Lines.Add(' '+s);
 end;
begin
 kw:=Trim(EditWmQueryFindWindows.Text);
 if (kw&lt;&gt;'') then
 try
  UpdateDesktopWindowsList;
  MemoWinProperties.Clear; Matches:=0;
  MemoWinProperties.Lines.Add('Поиск Окон:');
  MemoWinProperties.Lines.Add('###########');
  for i:=0 to ListboxWindows.Count-1 do begin
   if HasMatch(ListboxWindows.Items.Strings[i],kw)
   then inc(Matches);
  end;
  BitBtnWmQueryGoToFound.Enabled:=(Matches&gt;0);
  MemoWinProperties.Lines.Add(RusEng('Найдено Окон: ','Window(s) found: ')+IntToStr(Matches));
 except
  on E:Exception do BugReport(E,Self,'ActionWmQueryFindWindowsExecute');
 end;
end;

procedure TMainForm.ActionWmQueryBrowseXdgExecute(Sender: TObject);
const xdghtm='c:\opt\crwdaq\resource\guides\freedesktop.org\xdg.htm';
var xdg,cmd,ans:String;
begin
 try
  xdg:=AdaptFileName(xdghtm);
  if FileExists(xdg) then begin
   if IsUnix then begin
    cmd:='unix getapppath firefox chromium -t text/html -a .html xdg-open --run '+xdg;
    if RunCommand(cmd,ans)
    then LogEvents(Now,'Succeed: '+Trim(cmd+EOL+ans))
    else LogEvents(Now,'Failed: '+Trim(cmd+EOL+ans));
   end;
   if IsWindows then begin
    cmd:='grun -7 unix getapppath firefox.exe chrome.exe -t htmlfile -a .html --run '+xdg;
    if RunCommand(cmd,ans)
    then LogEvents(Now,'Succeed: '+Trim(cmd+EOL+ans))
    else LogEvents(Now,'Failed: '+Trim(cmd+EOL+ans));
   end;
  end;
 except
  on E:Exception do BugReport(E,Self,'ActionWmQueryBrowseXdgExecute');
 end;
end;

procedure TMainForm.TimerLogEventsUpdaterTimer(Sender: TObject);
begin
 try
  MoveBugReportListToLogger(nil);
  MoveLogEventsListToLoggerMemo(MemoLogEvents);
  if (PageControlMain.ActivePage=TabSheetLogEvents) then
  StatusBarLogEvents.SimpleText:=DateTimePrompt(Now)+GetHeapStatusBrief
   +FormatVar('. Events: %d',LogCountTotal)
   +FormatVar(', Bugs: %d',BugCountTotal)+'.';
  HandlePendingHideApplicationIconFromTaskBar;
  if myUpdateTrigger then begin
   UpdateDesktopWindowsList;
   myUpdateTrigger:=false;
  end;
 except
  on E:Exception do Self.BugReport(E,Self,'TimerLogEventsUpdaterTimer');
 end;
end;

procedure TMainForm.ActionMainExitExecute(Sender: TObject);
begin
 Application.Terminate;
end;

procedure TMainForm.ActionMainParentShowExecute(Sender: TObject);
begin
 AppActivateByTitle(ParentCrwDaqTitle);
end;

procedure TMainForm.ActionMainFormShowExecute(Sender: TObject);
begin
 ShowAndActivateFormByReference(Self,SW_SHOW);
end;

procedure TMainForm.ActionMainSendUserCmndExecute(Sender: TObject);
begin
 try
  if (CRW_DAQ_SYS_EXE_PID=0)
  then RaiseException('Parent Crw32.exe process is not specified.');
  EditMainSendUserCmnd.Text:=Trim(EditMainSendUserCmnd.Text);
  if (Pos('@',EditMainSendUserCmnd.Text)&lt;&gt;1)
  then RaiseException('Invalid format of command.');
  SendCommandToCrwDaq(EditMainSendUserCmnd.Text);
 except
  on E:Exception do Self.BugReport(E,Self,'ActionMainSendUserCmndExecute');
 end;
end;

procedure TMainForm.ActionMainExecUserCmndExecute(Sender: TObject);
var cmd,arg,ans:String;
begin
 try
  arg:='ListWindows';
  cmd:=wmquery.Command(arg);
  ans:=wmquery.Execute(arg);
  if (ans&lt;&gt;'') then begin
   ans:=wmquery.FormatListWindows(ans,true);
   StringsAppendFromText(MemoMainExecUserCmnd.Lines,cmd+EOL+ans);
  end else begin
   ans:=RusEng('Вызов прошел неудачно.','Command failed.');
   StringsAppendFromText(MemoMainExecUserCmnd.Lines,cmd+EOL+ans);
  end;
 except
  on E:Exception do Self.BugReport(E,Self,'ActionMainExecUserCmndExecute');
 end;
end;

procedure TMainForm.ActionMainLogEventsClearExecute(Sender: TObject);
begin
 MemoLogEvents.Lines.Clear;
 LogCountTotal:=0; BugCountTotal:=0;
 LogEvents(Now,GetBriefEngineScriptInfo);
 LogEvents(Now,'Start.');
end;

procedure TMainForm.ActionMainLogEventsGoBackExecute(Sender: TObject);
begin
 PageControlMain.ActivePage:=TabSheetTest;
end;

procedure TMainForm.ActionMainListSysInfoExecute(Sender: TObject);
var What,Info:String; Timeout:Integer;
begin
 Timeout:=1000*SpinEditMainListSysInfoTimeOut.Value;
 What:=Trim(ComboBoxMainListSysInfo.Text);
 Info:=ListSysInfoAsText(What,Timeout);
 LogEvents(Now,What);
 LogEvents(0,Info);
end;

var BugTestNum:Integer=0;

procedure TMainForm.BitBtnLogEventsTestClick(Sender: TObject);
begin
 try
  Inc(BugTestNum);
  RaiseException('This is exception test '+IntToStr(BugTestNum));
 except
  on E:Exception do Self.BugReport(E,Self,'BitBtnLogEventsTestClick');
 end;
end;

end.
</Code>
        </Main>
        <WmqueryUtils ImageIndex="2">
          <Object ClassName=""/>
          <Code>unit WmqueryUtils;

interface

uses  dpCmdArgs,dpSystem,dpSysUtils,dpVbs,dpWindows,dpGuiUtils,dpLinux,
      dpCrwDaqSys,dpDaqConfig,dpAntiZombie,dpGuiResMain;

 {
 WM Query - Window Manager query to get information or execute command.
 }
type
 TWmQuery = class(TObject)
  {
  Execute wmquery command and return result.
  }
 public
  function Execute(args:String):String;
  {
  Directory list to search executable file.
  }
 public
  function ExeSearchDirList:String;
  {
  Request command to execute WM Query. By default it's 'unix wmquery args'.
  }
 public
  function Command(args:String):String;
  {
  Header line for wmquery.Execute('ListWindows') output:
  Handle  Desktop  ProcessID  WindowClass  HostName  WindowTitle
  }
 public
  function HeaderLine:String;
  {
  Extract field (n=1..6) from line of window list.
  }
 public
  function ExtractWinListField(n:Integer; Line:String):String;
  function ExtractWinListWnd(Line:String):String;
  function ExtractWinListDesk(Line:String):String;
  function ExtractWinListPid(Line:String):String;
  function ExtractWinListClass(Line:String):String;
  function ExtractWinListHost(Line:String):String;
  function ExtractWinListTitle(Line:String):String;
 public
  {
  Check Line is valid window handle 0xNNNNNNNN.
  }
  function IsValidWnd(Line:String):Boolean;
  {
  Nice format for wmquery.Execute('ListWindows').
  Example:
  Handle      Desktop  ProcessID  WindowClass                  HostName  WindowTitle
  0x04A0006A  2        6236       doublecmd.Doublecmd          y510p     Double Commander - ROOT PRIVILEGES
  0x03C00002  -1       0          Conky.Conky                  y510p     conky (y510p)
  0x0480006B  2        308845     doublecmd.Doublecmd          y510p     Double Commander
  0x0500004A  2        458015     CrossDesigner.CrossDesigner  y510p     Object Inspector
  0x050001B4  2        458015     CrossDesigner.CrossDesigner  y510p     Менеджер проекта
  0x05000391  2        458015     CrossDesigner.CrossDesigner  y510p     CodeEditor
  0x05000396  2        458015     CrossDesigner.CrossDesigner  y510p     MainForm
  0x050001AF  2        458015     CrossDesigner.CrossDesigner  y510p     Дизель-Паскаль
  0x05400061  2        482916     CrossMachine.CrossMachine    y510p     wmquerygui.lm9
  }
 public
  function FormatListWindows(aList:String; aHead:Boolean):String;
 public
  {
  ShowWindow modes.
  }
  function SwModes(Delim:String=EOL):String;
 public
  {
  Get Value from Items list of 'Name = Value' lines.
  }
  function GetStringsValue(Items:TStrings; Ident:String):String;
 end;

const
 GDK_GRAVITY_DEFAULT    = 0;
 GDK_GRAVITY_NORTH_WEST = 1;
 GDK_GRAVITY_NORTH      = 2;
 GDK_GRAVITY_NORTH_EAST = 3;
 GDK_GRAVITY_WEST       = 4;
 GDK_GRAVITY_CENTER     = 5;
 GDK_GRAVITY_EAST       = 6;
 GDK_GRAVITY_SOUTH_WEST = 7;
 GDK_GRAVITY_SOUTH      = 8;
 GDK_GRAVITY_SOUTH_EAST = 9;
 GDK_GRAVITY_STATIC     = 10;
 GDK_GRAVITY_NAMES      = 'GDK_GRAVITY_DEFAULT'+EOL+
                          'GDK_GRAVITY_NORTH_WEST'+EOL+
                          'GDK_GRAVITY_NORTH'+EOL+
                          'GDK_GRAVITY_NORTH_EAST'+EOL+
                          'GDK_GRAVITY_WEST'+EOL+
                          'GDK_GRAVITY_CENTER'+EOL+
                          'GDK_GRAVITY_EAST'+EOL+
                          'GDK_GRAVITY_SOUTH_WEST'+EOL+
                          'GDK_GRAVITY_SOUTH'+EOL+
                          'GDK_GRAVITY_SOUTH_EAST'+EOL+
                          'GDK_GRAVITY_STATIC'+EOL;

  {
  The WM Query object.
  }
function wmquery:TWmQuery;

implementation

function TWmQuery.ExeSearchDirList:String;
var dir:String;
begin
 Result:=GetEnv('PATH')+PathSep+ExtractFileDir(GetScriptFullName);
 if IsWindows then begin
  dir:=ExpEnv('%CRW_DAQ_SYS_HOME_DIR%\resource\shell');
  if DirectoryExists(dir) then Result:=Result+PathSep+dir;
  dir:=ExpEnv('%SystemDrive%\opt\crwdaq\resource\shell');
  if DirectoryExists(dir) then Result:=Result+PathSep+dir;
 end;
end;

function TWmQuery.Command(args:String):String;
var exe:String;
begin
 Result:='';
 if IsUnix then Result:='unix wmquery '+args;
 if IsWindows then begin
  exe:=FileSearch('wmquery.exe',ExeSearchDirList,false);
  if IsEmptyStr(exe) then exe:='wmquery.exe';
  Result:=ExtractFileName(GetComSpec)+' /c chcp 65001 &gt; nul &amp; '+exe+' '+args;
 end;
end;

function TWmQuery.Execute(args:String):String;
var cmd,ans,opt:String; RunSucceed:Boolean; pid,exitcode:Integer;
begin
 ans:='';
 args:=Trim(args);
 if (args&lt;&gt;'') then begin
  RunSucceed:=false;
  pid:=0; exitcode:=0;cmd:=Command(args);
  if IsUnix then RunSucceed:=RunCommand(cmd,ans);
  if IsWindows then begin
   opt:='Display=SW_HIDE|TimeOut=7000|BuffKb=64';
   ans:=execute_command_as_text(cmd,pid,exitcode,opt);
   RunSucceed:=(ans&lt;&gt;'') and (pid&gt;0) and (exitcode=0);
  end;
  if RunSucceed then begin
   LogEvents(Now,'RunCommand('+cmd+'):'+EOL+'Succeed.');
  end else begin
   LogEvents(Now,'RunCommand('+cmd+'):'+EOL+'Failure.');
   ans:='';
  end;
 end;
 Result:=ans;
end;

 ///////////////////////////////////////////////////////////////////////////////
 // Note: Handle,Desktop,ProcessID,HostName are solid (has no space inside).
 //       WindowClass,WindowTitle may have spaces. To find end of WindowClass,
 //       double space search uses (must be two spaces after WindowClass item).
 //       The wmquery output contains data with double space after WindowClass.
 ///////////////////////////////////////////////////////////////////////////////
function TWmQuery.ExtractWinListField(n:Integer; Line:String):String;
var tail:String; p:Integer;
begin
 Result:='';
 case n of
  1,2,3: Result:=ExtractWord(n,Line,' ');
  4,5,6: begin
   tail:=SkipWords(3,Line,' '); p:=Pos('  ',tail); if (p&lt;2) then Exit;
   if (n=4) then Result:=Copy(tail,1,p-1) else tail:=Copy(tail,p,MaxInt);
   if (n=5) then Result:=ExtractWord(1,tail,' ');
   if (n=6) then Result:=SkipWords(1,tail,' ');
  end;
 end;
 if (Result&lt;&gt;'') then Result:=Trim(Result);
end;

function TWmQuery.ExtractWinListWnd(Line:String):String;
begin
 Result:=ExtractWinListField(1,Line);
end;

function TWmQuery.ExtractWinListDesk(Line:String):String;
begin
 Result:=ExtractWinListField(2,Line);
end;

function TWmQuery.ExtractWinListPid(Line:String):String;
begin
 Result:=ExtractWinListField(3,Line);
end;

function TWmQuery.ExtractWinListClass(Line:String):String;
begin
 Result:=ExtractWinListField(4,Line);
end;

function TWmQuery.ExtractWinListHost(Line:String):String;
begin
 Result:=ExtractWinListField(5,Line);
end;

function TWmQuery.ExtractWinListTitle(Line:String):String;
begin
 Result:=ExtractWinListField(6,Line);
end;

function TWmQuery.IsValidWnd(Line:String):Boolean;
var Wnd:LongInt;
begin
 Result:=false;
 if (Pos('0x',Line)&gt;0) then begin
  Line:=StringReplace(Line,'0x','$',rfReplaceAll);
  Wnd:=StrToIntDef(Line,0);
  Result:=(Wnd&lt;&gt;0);
 end;
end;

function TWmQuery.HeaderLine:String;
begin // wmquery always uses 2 spaces after WindowClass to make right parsing.
 Result:='Handle Desktop ProcessID WindowClass  HostName WindowTitle';
end;

function TWmQuery.FormatListWindows(aList:String; aHead:Boolean):String;
var Lines:TStringList; Line,fmt1,fmt2,fmt3,fmt4,fmt5,fmt6:String;
var i,w1,w2,w3,w4,w5,w6:Integer;
begin
 Result:='';
 try
  Lines:=TStringList.Create;
  try
   Lines.Text:=aList;
   w1:=Length(ExtractWord(1,HeaderLine,' '));
   w2:=Length(ExtractWord(2,HeaderLine,' '));
   w3:=Length(ExtractWord(3,HeaderLine,' '));
   w4:=Length(ExtractWord(4,HeaderLine,' '));
   w5:=Length(ExtractWord(5,HeaderLine,' '));
   w6:=Length(ExtractWord(6,HeaderLine,' '));
   for i:=Lines.Count-1 downto 0 do begin
    Line:=Lines.Strings[i];
    if (ExtractWinListField(6,Line)='')
    then begin Lines.Delete(i); Continue; end;
    w1:=iMax(w1,Length(ExtractWinListField(1,Line)));
    w2:=iMax(w2,Length(ExtractWinListField(2,Line)));
    w3:=iMax(w3,Length(ExtractWinListField(3,Line)));
    w4:=iMax(w4,Length(ExtractWinListField(4,Line)));
    w5:=iMax(w5,Length(ExtractWinListField(5,Line)));
    w6:=iMax(w6,Length(ExtractWinListField(6,Line)));
   end;
   fmt1:='%-'+IntToStr(w1)+'s  ';
   fmt2:='%-'+IntToStr(w2)+'s  ';
   fmt3:='%-'+IntToStr(w3)+'s  ';
   fmt4:='%-'+IntToStr(w4)+'s  ';
   fmt5:='%-'+IntToStr(w5)+'s  ';
   fmt6:='%s';
   if (aHead) then Lines.Insert(0,HeaderLine);
   for i:=0 to Lines.Count-1 do begin
    Line:=Lines.Strings[i];
    Line:=FormatVar(fmt1,ExtractWinListField(1,Line))
         +FormatVar(fmt2,ExtractWinListField(2,Line))
         +FormatVar(fmt3,ExtractWinListField(3,Line))
         +FormatVar(fmt4,ExtractWinListField(4,Line))
         +FormatVar(fmt5,ExtractWinListField(5,Line))
         +FormatVar(fmt6,ExtractWinListField(6,Line));
    Lines.Strings[i]:=Line;
   end;
   Result:=Lines.Text;
  finally
   Lines.Free;
  end;
 except
  on E:Exception do BugReport(E,nil,'FormatListWindows');
 end;
end;

function TWmQuery.SwModes(Delim:String=EOL):String;
const swm='HIDE,SHOWNORMAL,SHOWMINIMIZED,SHOWMAXIMIZED,SHOWNOACTIVATE,'
         +'SHOW,MINIMIZE,SHOWMINNOACTIVE,SHOWNA,RESTORE,SHOWDEFAULT';
begin
 if (Delim=',')
 then Result:=swm
 else Result:=StringReplace(swm,',',Delim,rfReplaceAll);
end;

function TWmQuery.GetStringsValue(Items:TStrings; Ident:String):String;
var i:Integer; sn,sv:String;
begin
 Result:='';
 if (Ident&lt;&gt;'') then
 if Assigned(Items) then
 try
  sn:=''; sv:='';
  for i:=0 to Items.Count-1 do begin
   if (ExtractNameValuePair(Items.Strings[i],sn,sv)&gt;0) then
   if SameText(sn,Ident) then begin Result:=sv; Break; end;
  end;
 except
  on E:Exception do BugReport(E,Self,'GetStringsValue');
 end;
end;

var
 TheWmQuery:TWmQuery=nil;

function wmquery:TWmQuery;
begin
 if not Assigned(TheWmQuery) then begin
  TheWmQuery:=TWmQuery.Create;
 end;
 Result:=TheWmQuery;
end;

end.
</Code>
        </WmqueryUtils>
      </Child>
    </wmquerygui>
  </Metadata>
</CrossEngineApp>
