SendMessage – вызов пунктов системного меню стандарт. окна

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
awl100Alex
Постоялец
Постоялец
 
Сообщения: 355
Зарегистрирован: 29.01.2008 (Вт) 15:19
Откуда: Украина

SendMessage – вызов пунктов системного меню стандарт. окна

Сообщение awl100Alex » 26.02.2008 (Вт) 14:05

Если нажать Alt+пробел в фокусе любого стандартного окна, то слева вверху, появится системное меню с пунктами «Свернуть», «Развернуть», и т.д.

У меня такая проблема:
Имеется некая программа, которая при запуске отображается на экране и в трее, и которая при вызове «Свернуть» своего системного меню, сворачивается в трей и исчезает с панели задач. Тоже самое происходит, если нажать обычную «_» кнопку на окне...

Мне нужно из своей программы послать этому окну сообщение, которое будет имитировать(!) событие сворачивания ее в трей, то есть фактически – вызов пункта системного меню «Свернуть»...

Делаю так:
Код: Выделить всё
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Integer, ByVal lParam As Any) As Long
Const WM_SYSCOMMAND = &H112
Const SC_MINIMIZE = &HF020

'Посылаем окну сообщение свернуться...
SendMessage «хэндл_окна», WM_SYSCOMMAND, ByVal SC_MINIMIZE, ByVal 0& 


Происходит то, что окно сворачивается... но НЕ исчезает с панели задач!

Как мне через SendMessage правильно обратится к «Свернуть» системного меню этого окна??? Может быть через WM_MENUCOMMAND??? Но как конкретней?

P.S.
При условии некоторых ограничений:
1) Делать окну SW_HIDE нельзя!
2) Прицеливаться по координатам... и посылать кнопке «_» окна CLICK нельзя – пользователь может менять размеры окна!
3) Использовать события клавиатуры тоже нельзя – форма окна может находится НЕ в фокусе, или может быть случайно сброшена с фокуса в момент выполнения команды каким-то сторонним событием!

awl100Alex
Постоялец
Постоялец
 
Сообщения: 355
Зарегистрирован: 29.01.2008 (Вт) 15:19
Откуда: Украина

Сообщение awl100Alex » 27.02.2008 (Ср) 1:00

Вот... кое-что удалось нарыть в Инете:

Код: Выделить всё
Private Declare Function GetSystemMenu Lib "user32" (ByVal hWnd As Long, ByVal bRevert As Long) As Long
Private Declare Function GetMenuItemCount Lib "user32" (ByVal hMenu As Long) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd _
As Long, ByVal wMsg As Long, ByVal wParam As Integer, ByVal lParam As Any) As Long
Const WM_COMMAND = &H111
Const WM_MENUCOMMAND = &H126
Const WM_SYSCOMMAND = &H112

Private Sub Command1_Click()
'Получаем дескриптор к системному меню окна...
hSysMenu = GetSystemMenu(Me.hWnd, 0)
'Получаем индекс системного меню...
nCnt = GetMenuItemCount(hSysMenu)
  'индекс начинается с 0 (0, 1, 2, 3...)
  If nCnt Then
   
   'Отправляем сообщене...
   SendMessage hSysMenu, WM_COMMAND, 3, 0& '3 - это "Свернуть" форму
   'SendMessage hSysMenu, WM_MENUCOMMAND, 3, 0&
   'SendMessage hSysMenu, WM_SYSCOMMAND, 3, 0&
     
  End If
End Sub


Но все равно форма никак НЕ реагирует на посылаемое сообщение! :(

Подскажите, пожалуйста, где ошибка в этой команде сообщения?..

P.S.
Кстати, в ходе жесточайших(!) экспериментов, случайно открылась интересная особенность... был получен ответ на один из вопросов на этом форуме. Уже не помню, где и искать, поэтому, если не найду тот топик... то открою новый в котором все расскажу. :)

BV
Thinker
Thinker
Аватара пользователя
 
Сообщения: 3987
Зарегистрирован: 12.09.2004 (Вс) 0:55
Откуда: Молдавия, г. Кишинёв

Сообщение BV » 27.02.2008 (Ср) 10:27

Нда... Оцени ShowWindow SW_MINIMIZE/SetWindowPlacement
const char *out = "|*0>78-,+<|"; size_t cc = char_traits<char>::length(out);
for (size_t i=0;i<cc;i++){cout<<static_cast<char>((out[i]^89));}cout<<endl;

Денис
Доктор VB наук
Доктор VB наук
Аватара пользователя
 
Сообщения: 2734
Зарегистрирован: 07.11.2006 (Вт) 13:55
Откуда: Ейск, Краснодарский край

Сообщение Денис » 27.02.2008 (Ср) 10:33

awl100Alex
дело в том, что кодеры совершенно по разному делают сворачивание в трей. и если ты наткнулся на прогу, в которой это реализовано криво, то, ИМХО, почти ничего поделать нельзя. Может скажешь, что за "некая программа"?
Программирование — богоизбранная дисциплина! Если бог и есть, то вселенную он скомпилировал, не иначе.

awl100Alex
Постоялец
Постоялец
 
Сообщения: 355
Зарегистрирован: 29.01.2008 (Вт) 15:19
Откуда: Украина

Сообщение awl100Alex » 27.02.2008 (Ср) 12:31

BV
ShowWindow SW_MINIMIZE – пройденный путь. Безрезультатно!.. :(

SetWindowPlacement – попробую, но я уверен, что все-таки можно как-то через SendMessage... Знать бы только, как?..

Денис
Ну о чем ты говоришь??!..
Как это может быть стандартное(!) меню любого(!) окна Windows реализовано криво??!! В каком бы редакторе не писали прогу – меню стандартное!

«Может скажешь, что за "некая программа"?» - любая!.. и Делфи, и VB реагируют одинаково, то есть - никак... :(

Денис
Доктор VB наук
Доктор VB наук
Аватара пользователя
 
Сообщения: 2734
Зарегистрирован: 07.11.2006 (Вт) 13:55
Откуда: Ейск, Краснодарский край

Сообщение Денис » 27.02.2008 (Ср) 15:48

awl100Alex
А я говорю, о том, что к процедуре Form_Minimize в "этой программе" прикручена процедура скрытия. И из системного меню вызывается системный обработчик, сворачивающий окно, а при нажатии кнопки "_" на форме вызывается процедура Form_Minimize

... аааа. точно ты же сам сендмессейджем вызываешь системный обработчик сворачивания окна, в обход его процедуры сворачивания при котором оно исчезает.

короче, я в этом ничо не понимаю, пусть тебе лучше продвинутые гуру советуют
Программирование — богоизбранная дисциплина! Если бог и есть, то вселенную он скомпилировал, не иначе.

awl100Alex
Постоялец
Постоялец
 
Сообщения: 355
Зарегистрирован: 29.01.2008 (Вт) 15:19
Откуда: Украина

Сообщение awl100Alex » 27.02.2008 (Ср) 16:21

Продвинутые гуру где Вы!!??.. Help! ;)

awl100Alex
Постоялец
Постоялец
 
Сообщения: 355
Зарегистрирован: 29.01.2008 (Вт) 15:19
Откуда: Украина

Сообщение awl100Alex » 28.02.2008 (Чт) 18:27

BV
SetWindowPlacement работает так же как и ShowWindow SW_MINIMIZE - проверил... Не подходит! :(

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Сообщение Twister » 29.02.2008 (Пт) 8:42

точно ты же сам сендмессейджем вызываешь системный обработчик сворачивания окна, в обход его процедуры сворачивания при котором оно исчезает.
Неверно. При SendMessage вызывается текущая процедура обработки сообщений, она же вызывается принажатии на пункт меню или на кнопку в заголовке. Ты б лучше подопытную прогу выложил.
А я все практикую лечение травами...

BV
Thinker
Thinker
Аватара пользователя
 
Сообщения: 3987
Зарегистрирован: 12.09.2004 (Вс) 0:55
Откуда: Молдавия, г. Кишинёв

Сообщение BV » 29.02.2008 (Пт) 10:11

SetWindowPlacement работает так же как и ShowWindow SW_MINIMIZE - проверил... Не подходит!


Тогда программу и код, которым проверял -- в студию.
const char *out = "|*0>78-,+<|"; size_t cc = char_traits<char>::length(out);
for (size_t i=0;i<cc;i++){cout<<static_cast<char>((out[i]^89));}cout<<endl;

awl100Alex
Постоялец
Постоялец
 
Сообщения: 355
Зарегистрирован: 29.01.2008 (Вт) 15:19
Откуда: Украина

Сообщение awl100Alex » 29.02.2008 (Пт) 13:32

BV писал(а): Тогда программу и код, которым проверял -- в студию.


Ты немного уводишь в сторону от той проблемы, которую нужно решить: я же все(!) написал в самом начале! Мне нужно не просто свернуть указанную программу... а через SendMessage сымитировать(!) команду клика по «Свернуть» в системном меню! Прога, которую нужно свернуть написана на Делфи 6.
Вот картинка, чтобы было понятно...
Вложения
SysMenuForm.jpg
Системное меню любого стандартного окна...
SysMenuForm.jpg (11.3 Кб) Просмотров: 655

awl100Alex
Постоялец
Постоялец
 
Сообщения: 355
Зарегистрирован: 29.01.2008 (Вт) 15:19
Откуда: Украина

Сообщение awl100Alex » 29.02.2008 (Пт) 13:52

BV
Вот то, что ты просил, но это все НЕ то!!..
Вложения
Proba.rar
SetWindowPlacement и ShowWindow...
(4.97 Кб) Скачиваний: 87

Atoman
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 109
Зарегистрирован: 01.02.2008 (Пт) 6:36

Сообщение Atoman » 29.02.2008 (Пт) 15:35

Немного переделал пример "awl100Alex"
Сворачивает окно через WM_SYSCOMMAND
Вложения
Proba.zip
(4.84 Кб) Скачиваний: 56

awl100Alex
Постоялец
Постоялец
 
Сообщения: 355
Зарегистрирован: 29.01.2008 (Вт) 15:19
Откуда: Украина

Сообщение awl100Alex » 29.02.2008 (Пт) 19:02

Atoman

SendMessage(hHandle, WM_SYSCOMMAND, SC_MINIMIZE, ByVal 0&) ... - :shock:

WM_SYSCOMMAND - Получается!... :shock: Подожди ка... но ведь я же в самом начале это пробовал, и программа не исчезала из панели задач! А сейчас получилось... Как это понимать???

Код один и тот же... Только на разных машинах запускал под одной операционкой. Или это были просто глюки в системе, или я чего то не совсем понимаю... :(

...???!!!...

Ладно... извините за неумышленное заблуждение...

Atoman
Спасибо, что заставил еще раз пройти этот путь.

Atoman
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 109
Зарегистрирован: 01.02.2008 (Пт) 6:36

Сообщение Atoman » 29.02.2008 (Пт) 19:13

У меня сначала тоже не получалось.
Вот у этих констант значения разные.

Код: Выделить всё
Const SC_MINIMIZE = &HF020
Const SC_MINIMIZE = 61472

awl100Alex
Постоялец
Постоялец
 
Сообщения: 355
Зарегистрирован: 29.01.2008 (Вт) 15:19
Откуда: Украина

Сообщение awl100Alex » 29.02.2008 (Пт) 20:09

Да, нет... Значения одинаковые!.. :? Только система исчислений разная.
Вложения
Const.jpg
Калькулятор Windows...
Const.jpg (36.54 Кб) Просмотров: 655

awl100Alex
Постоялец
Постоялец
 
Сообщения: 355
Зарегистрирован: 29.01.2008 (Вт) 15:19
Откуда: Украина

Сообщение awl100Alex » 29.02.2008 (Пт) 21:06

Ну, блин!.. Windows OC чтоб тебя! :x Я все понял!!! :cheers:
Это таки был ГЛЮК в "матрице"! :( Сейчас все объясню на примерах...

Atoman
Если бы не ты, то, наверное, долго еще бы искал "иголку" в стоге сена. Еще раз спасибо!.. :)

Atoman
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 109
Зарегистрирован: 01.02.2008 (Пт) 6:36

Сообщение Atoman » 29.02.2008 (Пт) 21:25

Зачем иголку, да ещё и в стоге сена?
Яндекс > Const SC_MINIMIZE 'Мне помог
Гугл > ...
Поиск

awl100Alex
Постоялец
Постоялец
 
Сообщения: 355
Зарегистрирован: 29.01.2008 (Вт) 15:19
Откуда: Украина

Сообщение awl100Alex » 29.02.2008 (Пт) 22:40

Вообщем, все оказалось банально просто... :)
Вот два варианта, которые приводят к одному и тому же результату, потому что они полностью(!) одинаковы. Разные только пути решения...

Код: Выделить всё
Private Declare Function GetSystemMenu Lib "user32" (ByVal hWnd As Long, ByVal bRevert As Long) As Long
Private Declare Function GetMenuItemCount Lib "user32" (ByVal hMenu As Long) As Long
Private Declare Function GetMenuItemID Lib "user32" (ByVal hMenu As Long, ByVal nPos As Long) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd _
As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Any) As Long
Const WM_SYSCOMMAND = &H112
Const SC_MINIMIZE = 61472 ' => Const SC_MINIMIZE = &HF020

Private Sub Command1_Click()
'Вариант 1
'Получаем дескриптор к системному меню окна...
hSysMenu = GetSystemMenu(Me.hWnd, 0)
'Получаем колличество индексов системного меню...
nCnt = GetMenuItemCount(hSysMenu)
  'индекс начинается с 0 (0, 1, 2, 3...)
  If nCnt Then 'Если меню существует, выполняем обработку...
   'Указываем, что работать хотим с третьим пунктом меню,
   'получаем указатель на команду меню под индексом 3 - то есть "Свернуть"...
   hMenuItem = GetMenuItemID(hSysMenu, 3)
   'Отправляем сообщение...
   'то есть - имитируем клик по "Свернуть" в системном меню формы!..
   SendMessage Me.hWnd, WM_SYSCOMMAND, hMenuItem, ByVal 0&
  End If
End Sub

Private Sub Command2_Click()
'Вариант 2
'Посылаем окну сообщение свернуться...
SendMessage Me.hWnd, WM_SYSCOMMAND, SC_MINIMIZE, ByVal 0&
End Sub
Вложения
Viktorya.rar
Два варианта одного решения...
(4.68 Кб) Скачиваний: 62

awl100Alex
Постоялец
Постоялец
 
Сообщения: 355
Зарегистрирован: 29.01.2008 (Вт) 15:19
Откуда: Украина

Сообщение awl100Alex » 29.02.2008 (Пт) 22:41

А теперь посмотрите сюда... и вы поймете, за что я благодарил Atoman...
Вложения
Идентичность.jpg
Идентичность.jpg (184.37 Кб) Просмотров: 659

awl100Alex
Постоялец
Постоялец
 
Сообщения: 355
Зарегистрирован: 29.01.2008 (Вт) 15:19
Откуда: Украина

Сообщение awl100Alex » 29.02.2008 (Пт) 22:42

Atoman
Ты случайно указал мне на SC_MINIMIZE в интерпретации десятичного(!) значения, и когда я трассировал код, то заметил, что функция GetMenuItemID(hSysMenu, 3) возвращает десятичное(!) значение SC_MINIMIZE!
Вот тогда я и понял, в каком порядке нужно было расставить все «фишки»! :)

awl100Alex
Постоялец
Постоялец
 
Сообщения: 355
Зарегистрирован: 29.01.2008 (Вт) 15:19
Откуда: Украина

Сообщение awl100Alex » 29.02.2008 (Пт) 22:46

Всем, спасибо! :D
Тему можно считать закрытой! :D


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 87

    TopList