Форум: "Основная";
Текущий архив: 2011.04.03;
Скачать: [xml.tar.bz2];
ВнизПроверка видимости контекстного меню Найти похожие ветки
← →
dmitry_12_08_73 © (2009-08-28 16:09) [0]Как проверить, видимо ли в своем приложении хоть одно контекстное меню?
← →
Rouse_ © (2009-08-29 00:19) [1]Эмм... меню модально, т.е. если из основного потока код проверки выполнился - меню нет.
← →
oldman © (2009-08-29 13:12) [2]
> dmitry_12_08_73 ©
а в чем проблема?
оно невидимо?
код в студию!
← →
Юрий Зотов © (2009-08-29 23:35) [3]> dmitry_12_08_73 © (28.08.09 16:09)
procedure TForm1.OnAppMessage(var Msg: TMsg; var Handled: Boolean);
begin
FFlag := Msg.message = WM_ENTERMENULOOP;
Caption := BoolToStr(FFlag, True)
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Application.OnMessage := OnAppMessage
end;
procedure TForm1.PopupMenu1Popup(Sender: TObject);
begin
FFlag := True;
Caption := BoolToStr(FFlag, True)
end;
Но проверку флага FFlag надо делать из НЕглавного потока, потому что в главном она не имеет смысла (см. [1] - если меню нет, то флаг заведомо будет равен False, а если оно есть, то код проверки в главном потоке просто не сработает).
← →
dmitry_12_08_73 © (2009-08-30 12:39) [4]Вы знаете, проблема в следующем.
Моя программа находится в трее, я нажимаю правой кнопкой мыши на контекстном меню, выбираю нужный пункт, затем делаю копирование образа экрана. При этом (если в винде в настройках установлена анимация меню). то моё контекстное меню не успевает исчезнуть и копируется с экраном, а меня это не устравивает.
Поэтому я как-то хочу проверять видимость контекстного меню (пока оно полностью не исчезнет), а потом уже копировать экран.
← →
dmitry_12_08_73 © (2009-08-30 12:44) [5]Я так понял, что ответ Юрия Зотова мне подходит
← →
Юрий Зотов © (2009-08-30 13:52) [6]> dmitry_12_08_73 © (30.08.09 12:39) [4]
Попробуйте сначала сделать проще. Пункт меню не копирует экран, а через PostMessage посылает Вашей невидимой форме сообщение. Получив это сообщение, форма копирует экран.
← →
dmitry_12_08_73 © (2009-08-30 15:25) [7]Юрий. Честно говоря не понял этого Вашего совета.
Я отображаю контекстное меню, нажимаю его пункт (при этом меню начинает плавно исчезать), затем в событии MenuItem.OnClick запускаю процедуру копирования экрана BitBlt. и получается так, что BitBlt при копировании экрана копирует и исчезающее меню.
← →
Юрий Зотов © (2009-08-30 15:56) [8]> dmitry_12_08_73 © (30.08.09 15:25) [7]
В модуле Вашей невидимой формы:
1. В секции interface перед словом type пишете:
const
WM_UserPlus100 = WM_USER + 100;
2. В секции protected класса формы пишете объявление метода:
procedure WMUserPlus100(var Message: TMessage); message WM_UserPlus100;
Потом ставите курсор на эту строчку, жмете Ctrl+Shift+C и получаете тело метода.
3. В теле метода пишете слово inherited, а после него - код копирования экрана (просто переносите этот код из MenuItem.OnClick).
4. В MenuItem.OnClick пишете строчку:
PostMessage(Handle, WM_UserPlus100, 0, 0);
Больше в MenuItem.OnClick ничего не должно быть.
===================
Суть в том, что при клике по пункту меню форме будет послано сообщение WM_UserPlus100. Но поскольку программа в этот момент крутится в цикле меню, то обработано это сообщение будет не сразу, а встанет в очередь. Когда цикл меню завершится (то есть, когда меню исчезнет), сообщения из очереди начнут обрабатываться и произойдет копирование экрана.
Во всяком случае, такой способ стоит попробовать. Он намного проще, чем городить второй поток и из него отслеживать пропадание меню.
← →
dmitry_12_08_73 © (2009-08-30 18:32) [9]Спасибо большое, буду пробовать
← →
Германн © (2009-08-30 20:29) [10]
> Юрий Зотов © (30.08.09 15:56) [8]
А зачем "В теле метода пишете слово inherited"?
← →
Юрий Зотов © (2009-08-30 21:19) [11]> Германн © (30.08.09 20:29) [10]
Насколько помню, какие-то из сообщений WM_USER + X с некоторых пор используются стандартными системными контролами. Копать документацию, честно говоря, просто лень, проще задать WM_USER+100 и написать inherited. Если обработчик существует, то inherited даст ему нормально сработать, после чего нормально сработает и наш код. А если обработчик не существует, то inherited ничему не помешает. То есть, вреда от inherited в любом случае нет, а польза может быть.
← →
Германн © (2009-08-30 21:25) [12]Понятно.
← →
Германн © (2009-08-31 01:33) [13]
> Юрий Зотов © (30.08.09 21:19) [11]
Не. Всё-таки не понимаю полностью.
Как наследник класса TForm может узнать, что некие "стандартные системные контролы" используют данное сообщение?
Даже если класс TForm им пользуется, то как вызвать inherited, если процедура не перекрывается, а заменяется?
← →
Германн © (2009-08-31 01:45) [14]
> Германн © (31.08.09 01:33) [13]
P.S.
Да. Я понимаю, что inherited (в данном случае) вреда не принесёт. Но не похоже ли это его использование на "дуть на воду"?
← →
Юрий Зотов © (2009-08-31 01:46) [15]> Германн © (31.08.09 01:33) [13]
> Как наследник класса TForm может узнать, что некие "стандартные
> системные контролы" используют данное сообщение?
А ему и знать об этом не надо. Вызвал inherited - и все. VCL сама разрулит. Если обработчик в цепочке есть - он быдет вызван, если нет - ничего не произойдет.
> как вызвать inherited, если процедура не перекрывается, а заменяется?
Перекрывается. Методы обработки сообщений - динамические по умолчанию. Да даже и в статическом "заменяющем" методе никто не запрещает вызвать "замененный" метод предка через inherited.
← →
Германн © (2009-08-31 01:53) [16]
> Перекрывается. Методы обработки сообщений - динамические
> по умолчанию. Да даже и в статическом "заменяющем" методе
> никто не запрещает вызвать "замененный" метод предка через
> inherited.
>
((((
Похоже мне придётся очень много заново учить, если я хочу удержаться на новой работе. :(
← →
Юрий Зотов © (2009-08-31 02:23) [17]> Германн © (31.08.09 01:53) [16]
Вот иллюстрация. TForm2 - наследник TForm1. При двойном щелчке по Form2 она сама себе посылает сообщение. Но мы сначала видим надпись "Это Form1" (срабатывает inherited), а уж потом - "Это Form2" (срабатывает собственный код TForm2).
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
const
WM_UserPlus100 = WM_USER + 100;
type
TForm1 = class(TForm)
procedure FormActivate(Sender: TObject);
protected
procedure WMUserPlus100(var Message: TMessage); message WM_UserPlus100;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TForm1 }
uses
Unit2;
procedure TForm1.WMUserPlus100(var Message: TMessage);
begin
inherited;
ShowMessage("Это Form1")
end;
procedure TForm1.FormActivate(Sender: TObject);
begin
if Form2 = nil then
begin
Form2 := TForm2.Create(Application);
Form2.Show
end
end;
======================
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Unit1;
type
TForm2 = class(TForm1)
procedure FormDblClick(Sender: TObject);
protected
procedure WMUserPlus100(var Message: TMessage); message WM_UserPlus100;
end;
var
Form2: TForm2;
implementation
{$R *.dfm}
{ TForm2 }
procedure TForm2.WMUserPlus100(var Message: TMessage);
begin
inherited;
ShowMessage("Это Form2")
end;
procedure TForm2.FormDblClick(Sender: TObject);
begin
PostMessage(Handle, WM_UserPlus100, 0, 0)
end;
← →
Германн © (2009-08-31 02:44) [18]
> Юрий Зотов © (31.08.09 02:23) [17]
Юр, я уже и сам это проверил прежде чем написать
> Германн © (31.08.09 01:53) [16]
:)
Только в своём примере inherited написал только один раз.
Я "чел" отсталый от времени, почти как мастодонт, но всё же не без рук и мозгов! :)
P.S. А по поводу "своей новой работы" я готов потрепаться на ММП. Если выберусь на неё ещё когда-то. :(
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2011.04.03;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.003 c