Имя: Пароль:
IT
 
Не получается поймать WM_QUIT в маленькой самописке без формы
,
0 vcv
 
14.03.14
07:26
Есть маленькая самописочка, программа на VBasic, скомпилированная vbc, входящем в состав .NET Framework4. Программка win32 без формы, висит в процессах и показывает в system tray состояние обмена 1С7.7. Все работает, пока пользователь не начинает завершать сеанс. В этом случае винда сообщает, что есть зависшая программа и предлагает жать кнопку что бы убить.
Ни как не могу найти, как в программе на VB без формы ловить сообщения из очереди и корректно завершать свою программку при завершении сеанса.
1 oleg_km
 
14.03.14
10:32
так а в проекте указано, что консольное приложение или GUI?
2 DJ Anthon
 
14.03.14
10:37
там не только квит, там еще события езь
3 DJ Anthon
 
14.03.14
10:37
когда винда опрашивает, можно ли завершиться. не помню, давно уже было
4 mistеr
 
14.03.14
10:47
(0) Так у программы есть какое-нибудь окно или нет? Если нет, то можешь ждать WM_QUITдо ишачей пасхи.
5 vcv
 
14.03.14
11:12
(1) Проекта нет. Как и студии (зачем плодить сущности для мелкой автоматизации). Компилирую исходник штатным компилятором из состава Framework 4.
(4) Окна нет. И не хотелось бы делать.
6 mistеr
 
14.03.14
11:14
(5) А придется. Сделай скрытое, в чем проблема?
7 vcv
 
14.03.14
11:22
(6) Проблема в том, что я не знаю, как окна делать в текстовом редакторе. Студию-то не ставил :)
Да и сущность лишняя в задаче.
8 mistеr
 
14.03.14
11:27
(7) Как обычно, CreateWindow(). MSDN в помошь.
Сущность не лишняя, а необходимая, чтобы обрабатывать оконные сообщения.
9 vcv
 
14.03.14
11:35
Точно необходимая? PeekMessage что-то делает и без окна. Правда что-то невнятненькое :)
10 H A D G E H O G s
 
14.03.14
11:44
(9) Точно.
11 oleg_km
 
14.03.14
11:57
(9) Есть два способа запустить приложение в Windows - это консольное приложение или оконное приложение. Оба имеют обработчики событий. Поскольку .NET среда объекто-ориентированная, то чтобы обрабатывать эти события нужно переопределить соттветствующие обработчики. Странно, что среда по-умолчанию сама не обрабатывает сообщение от Windows. Можешь скинуть текст проекта и командную строку компиляции?
12 mistеr
 
14.03.14
12:01
(7) Я бы сказал, что VB.NET - лишняя сущность в задаче. Сделай на AutoIt, он сам будет обрабатывать WM_QUIT.
13 mistеr
 
14.03.14
12:02
(11) Тут не среда не обрабатывает. Тут Windows не посылает сообщения.
14 vcv
 
14.03.14
12:03
(11)
Первый вариант без экспериментов по перехвату сообщений

C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\vbc.exe "1cv7a_icon.vb" /NoLogo /target:winexe

Option Explicit

Imports System
Imports System.Object
Imports System.IO
Imports System.Drawing
Imports System.Windows.Forms
Imports System.Text

Module AutoExchangeTrayIndicator

Sub Main()

  Dim ApplicationPath as String = Application.StartupPath()
  Dim ConfigFileName as String = ApplicationPath + "\" + Path.GetFileNameWithoutExtension(Application.ExecutablePath()) + ".ini"
  Dim NotifyIcons As New Microsoft.VisualBasic.Collection()

  If File.Exists(ConfigFileName) Then

    Dim ConfigFile As StreamReader = New StreamReader(ConfigFileName)
    Dim ConfigFileLine As String = Trim(ConfigFile.ReadLine)
    Do While Not ConfigFileLine Is Nothing
      if Left(ConfigFileLine,1)<>";" Then
        If IO.File.Exists(ConfigFileLine+"\1cv7.md") Then
          Dim NotifyIconDescription = ""
          If IO.File.Exists(ConfigFileLine+"\1cv7desc.txt") Then
            NotifyIconDescription = Trim(File.ReadAllText(ConfigFileLine+"\1cv7desc.txt",Encoding.GetEncoding(866)))
          End if
          If NotifyIconDescription = "" Then
            NotifyIconDescription = ConfigFileLine
          End if
          Dim NotifyIcon = New System.Windows.Forms.NotifyIcon()
          NotifyIcon.Text = "Индикатор автообмена"+ControlChars.Lf+NotifyIconDescription
          NotifyIcons.Add({NotifyIcon,ConfigFileLine,1,0})
        End if
      End if
      ConfigFileLine = ConfigFile.ReadLine
    Loop

    If NotifyIcons.Count > 0 Then

      Dim Icons As New Microsoft.VisualBasic.Collection()
      Icons.Add(New Icon(ApplicationPath+"\1cv7a_icon0.ico"))
      Icons.Add(New Icon(ApplicationPath+"\1cv7a_icon1.ico"))
      Icons.Add(New Icon(ApplicationPath+"\1cv7a_icon2.ico"))
      Icons.Add(New Icon(ApplicationPath+"\1cv7a_icon3.ico"))
      Icons.Add(New Icon(ApplicationPath+"\1cv7a_icon4.ico"))
      Icons.Add(New Icon(ApplicationPath+"\1cv7a_icon5.ico"))
      Icons.Add(New Icon(ApplicationPath+"\1cv7a_icon6.ico"))
      Icons.Add(New Icon(ApplicationPath+"\1cv7a_icon7.ico"))
      Icons.Add(New Icon(ApplicationPath+"\1cv7a_icon8.ico"))

      While True

        For each NotifyIconInfo in NotifyIcons
          Dim NotifyIcon = NotifyIconInfo.GetValue(0)
          Dim DBPath as String = NotifyIconInfo.GetValue(1)
          Dim NotifyIconPosition as Integer = NotifyIconInfo.GetValue(2)
          Dim DownCounter as Integer = NotifyIconInfo.GetValue(3)
          Dim AutoexchangeON as boolean = False

          Dim InputDataFile = DBPath+"\UZ000000\1Cv77Chs.dat"
          Dim OutputDataFile = DBPath+"\1Cv77Chs.dat"

          If File.Exists(OutputDataFile) Then
            AutoexchangeON = True
          Elseif File.Exists(InputDataFile) Then
            AutoexchangeON = True
          Else
            AutoexchangeON = False
          End if

          If AutoexchangeON Then
            DownCounter = 5
          Else
            DownCounter = DownCounter - 1
            if DownCounter > 0 Then
              AutoexchangeON = True
            End if
          End if

          If AutoexchangeON Then
            If NotifyIconPosition <= 1 Then
              NotifyIconPosition = 2
            ElseIf NotifyIconPosition >= Icons.Count Then
              NotifyIconPosition = 2
            Else
              NotifyIconPosition = NotifyIconPosition + 1
            End if
          Else
            NotifyIconPosition = 1
          End if

          NotifyIcon.Visible = True
          NotifyIcon.Icon = Icons.Item(NotifyIconPosition)

          NotifyIconInfo.SetValue(NotifyIconPosition,2)
          NotifyIconInfo.SetValue(DownCounter,3)

        Next NotifyIconInfo

        Threading.Thread.Sleep(200)

      End while

    End if

  End if

End Sub

End Module
15 vcv
 
14.03.14
12:05
(13) Читал где-то в инете о том, что можно как-то прицепиться к окну рабочего стола. И его сообщения обрабатывать.
16 oleg_km
 
14.03.14
12:07
(14) А, бесконечный цикл, ну да, программа в стиле MS DOS. Нужно или делать консольно приложение и писать обработчики консольных событий или добавить скрытое окно. Других вариантов в Windows нет
17 mistеr
 
14.03.14
12:17
(15) Можно, но это грязный хак, может глючить. И самое главное - без курения MSDN опять же не обойтись. :)
18 vcv
 
14.03.14
12:19
(17) Курить не проблема. Проблема в том, что заставить программку работать без создания фиктивного окна за последние пару дней стало навязчивой идей.
19 mistеr
 
14.03.14
12:25
(18) Согласен, навязчивая идея это проблема.

Варианты: хуки, сабклассинг десктопного окна, и (16).
20 oleg_km
 
14.03.14
12:26
(18) ну это как почесать большим пальцем ноги в носу. Ты компилируешь с ключем /target:winexe, т.е. предполагается что это будет обычное виндовое приложение. Значит, чтобы оно вело себя нормально, оно должно с ОС взаимодействовать нормально, а значит иметь очередь сообщений.