Файл: 1_C#_Введение_в_программирование_Уч_пособ_(Марченко-2005).pdf
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 11.12.2025
Просмотров: 1325
Скачиваний: 3
методы для обработки сообщений Windows,
свойства для получения сведений о приложении.
Открытые свойства
AllowQuit |
Получает значение, определяющее, может ли вызывающий |
||||||||||
|
объект выйти из этого приложения. |
|
|
|
|
|
|||||
CommonAppDataPath |
Получает |
путь для данных приложения, являющихся общими |
|||||||||
|
для всех пользователей. |
|
|
|
|
|
|
|
|||
CommonAppDataRegistry |
Получает раздел реестра для данных приложения, являющихся |
||||||||||
|
общими для всех пользователей. |
|
|
|
|
|
|
||||
CompanyName |
Получает название компании, связанное с приложением. |
||||||||||
CurrentCulture |
Получает |
или задает данные о культурной среде для |
|||||||||
|
текущего потока. |
|
|
|
|
|
|
|
|
||
CurrentInputLanguage |
Получает |
или |
задает текущий |
язык |
ввода для |
текущего |
|||||
|
потока. |
|
|
|
|
|
|
|
|
|
|
ExecutablePath |
Получает путь для исполняемого файла, запустившего |
||||||||||
|
приложение, включая исполняемое имя. |
|
|
|
|
||||||
LocalUserAppDataPath |
Получает путь для данных приложения местного, не |
||||||||||
|
перемещающегося, пользователя. |
|
|
|
|
|
|
||||
MessageLoop |
Получает значение, указывающее, существует ли цикл |
||||||||||
|
обработки сообщений в данном потоке. |
|
|
|
|
||||||
ProductName |
Получает |
название |
продукта, |
связанное |
с |
данным |
|||||
|
приложением. |
|
|
|
|
|
|
|
|
|
|
ProductVersion |
Получает версию продукта, связанную с данным приложением. |
||||||||||
SafeTopLevelCaptionFormat |
Получает или задает строку формата для использования в |
||||||||||
|
заголовках окон верхнего уровня, когда они отображаются с |
||||||||||
|
предупреждающим объявлением. |
|
|
|
|
|
|
||||
StartupPath |
Получает путь для исполняемого файла, запустившего |
||||||||||
|
приложение, не включая исполняемое имя. |
|
|
|
|||||||
UserAppDataPath |
Получает путь для данных приложения пользователя. |
||||||||||
UserAppDataRegistry |
Получает |
раздел |
реестра |
для |
|
данных |
приложения |
||||
|
пользователя. |
|
|
|
|
|
|
|
|
|
|
Открытые методы |
|
|
|
|
|
|
|
|
|
|
|
AddMessageFilter |
Добавляет фильтр сообщений для контроля за сообщениями |
||||||||||
|
Windows во время их направления к местам назначения. |
||||||||||
DoEvents |
Обрабатывает все сообщения Windows, в данный момент |
||||||||||
|
находящиеся в очереди сообщений. |
|
|
|
|
|
|||||
EnableVisualStyles |
Включите визуальные стили Windows XP для приложения. |
||||||||||
Exit |
Сообщает всем прокачкам сообщений, что следует завершить |
||||||||||
|
работу, а после обработки сообщений закрывает все окна |
||||||||||
|
приложения. |
|
|
|
|
|
|
|
|
|
|
ExitThread |
Выходит из цикла обработки сообщений в текущем потоке и |
||||||||||
|
закрывает все окна в потоке. |
|
|
|
|
|
|
||||
OleRequired |
Инициализирует OLE в текущем потоке. |
|
|
|
|
||||||
OnThreadException |
Вызывает событие ThreadException. |
|
|
|
|
|
|||||
RemoveMessageFilter |
Удаляет |
фильтр |
сообщений |
из |
|
прокачки |
|
сообщений |
|||
|
приложения. |
|
|
|
|
|
|
|
|
|
|
Run |
Перегружен. |
Запускает |
стандартный |
цикл |
|
обработки |
|||||
|
сообщений приложения в текущем потоке. |
|
|
|
|||||||
Открытые события |
|
|
|
|
|
|
|
|
|
|
|
ApplicationExit |
Происходит при закрытии приложения. |
|
|
|
|
||||||
Idle |
Происходит, когда приложение заканчивает обработку и |
||||||||||
|
собирается перейти в состояние незанятости. |
|
|
||||||||
ThreadException |
Возникает при выдаче не перехваченного исключения потока. |
||||||||||
ThreadExit |
Происходит при закрытии потока. Перед закрытием главного |
||||||||||
|
потока для приложения вызывается данное событие, за |
||||||||||
|
которым следует событие ApplicationExit. |
|
|
|
|||||||
IMessageFilter позволяет остановить вызов события или выполнить специальные операции до вызова обработчика событий.
Класс имеет свойства CurrentCulture и CurrentInputLanguage, чтобы получать или задавать сведения о культурной среде для текущего потока.
События класса Application
ApplicationExit |
Статическое. |
Происходит при закрытии приложения. |
Idle |
Статическое. |
Происходит, когда приложение заканчивает обработку и |
187
ThreadException
ThreadExit
собирается перейти в состояние незанятости.
Статическое. Возникает при выдаче не перехваченного исключения потока.
Статическое. Происходит при закрытии потока. Перед закрытием главного потока для приложения вызывается данное событие, за которым следует событие ApplicationExit.
Итак, класс Application располагает методами для запуска и останова ПОТОКОВ и ПРИЛОЖЕНИЙ, а также для обработки Windows messages.
Вызов методов Run обеспечивает выполнение цикла обработки сообщений (an application message loop) в текущем потоке, а также, возможно, делает видимой соответствующую форму.
Вызов методов Exit и ExitThread приводит к остановке цикла обработки сообщений.
Вызов DoEvents позволяет активизировать обработку сообщений практически из любого места выполняемого программного кода. Например, во время выполнения операторов цикла.
Вызов AddMessageFilter обеспечивает добавление фильтра сообщений to the application message pump для monitor Windows messages.
Интерфейс IMessageFilter позволяет реализовывать специальные алгоритмы непосредственно перед вызовом обработчика сообщения.
Класс статический и объектов-представителей этого класса создать невозможно!
Windows message
Прежде всего, Message – это СТРУКТУРА, представляющая в .NET сообщения Windows. Те самые, которые адресуются приложению и используются системой как средство уведомления выполняющихся в Windows приложений.
Эта структура используется также для формирования собственных сообщений, которые могут формироваться “в обход системы” и передаваться для последующей их обработки оконным процедурам приложений. Это стандартный интерфейс обмена информацией между приложениями. Важно, чтобы приложение “понимало” смысл происходящего.
Объект-представитель Message structure, может быть создан с использованием метода Create (создать – не означает отправить).
Список членов Message structure
Члены |
|
|
|
|
|
Объявление |
|
|
HWnd property. Gets or sets the window handle |
of |
public IntPtr HWnd(get; set;) |
||||||
the message. |
|
|
|
|
|
public int Msg {get; set;} |
||
Msg property. Gets or sets the ID number for |
the |
|||||||
message. |
|
|
|
|
|
public IntPtr WParam {get; set;} |
||
WParam property. Gets or sets the WParam field |
of |
|||||||
the message. Значение этого поля зависит от |
|
|
|
|||||
конкретного сообщения. Use the WParam field to get |
|
|
|
|||||
information that is important to handling the |
|
|
|
|||||
message. Это поле обычно используется для |
|
|
|
|||||
фиксирования |
small |
pieces |
of |
information, |
|
|
|
|
например, значений флагов. |
|
|
|
public IntPtr Lparam {get; set;} |
||||
LParam property. Gets or sets the LParam field |
of |
|||||||
the message. The value of this field depends |
on |
|
|
|
||||
the message. Use the LParam field to get |
|
|
|
|||||
information that is important to handling the |
|
|
|
|||||
message. This field is typically used to store an |
|
|
|
|||||
object if it is needed by the message. |
|
|
public IntPtr Result {get; set;} |
|||||
Result property. Specifies the value that |
is |
|||||||
returned to Windows in response to handling the |
|
|
|
|||||
message. |
|
|
|
|
|
public static Message Create ( |
||
Create method. Создает новую структуру Message. |
|
|||||||
|
|
|
|
|
|
IntPtr hWnd, |
|
|
|
|
|
|
|
|
int msg, |
|
|
|
|
|
|
|
|
IntPtr wparam, |
|
|
|
|
|
|
|
|
IntPtr lparam); |
|
|
Equality operator. Сравнивает два сообщения |
на |
public static Boolean |
operator |
|||||
предмет определения их идентичности. |
|
|
==( |
|
|
|||
|
|
|
|
|
|
Message left, |
|
|
|
|
|
|
|
|
Message right); |
|
|
Inequality operator. |
Сравнивает |
два |
сообщения |
на |
public |
static |
Boolean |
|
188
предмет определения их различия. |
operator !=( |
|
|
|
Message left, |
|
|
|
Message right); |
|
|
Equals метод. Compares two message structures to |
public |
override |
bool |
determine if they are equal. |
Equals(object o) |
|
|
GetHashCode method. Gets the hash code of the |
public |
override |
int |
message handle. |
GetHashCode(); |
|
|
При этом IntPtr – это platform-specific тип, который используется для представления указателей или дескрипторов. Предназначен для представления целочисленных величин, размеры которых зависят от характеристик платформы (is platform-specific). То есть ожидается, что объект этого типа будет иметь размер 32 бита на 32-разрядных аппаратных средствах и операционных системах, и 64 битах на аппаратных средствах на 64 бита и операционных системах.
Тип IntPtr может использоваться языками, которые поддерживают механизм указателей, и как общее средство для обращения к данным между языками, которые поддерживают и не поддерживают указатели.
Объект IntPtr может быть также использован для поддержки дескрипторов.
For example, instances of IntPtr are used extensively in the System.IO.FileStream class to hold file handles.
Существует ещё один экзотический тип – UIntPtr, который в отличие от IntPtr не является CLS-compliant типом.
Только IntPtr тип используется в common language runtime.
UIntPtr тип разработан в основном для поддержки архитектурной симметрии (to maintain architectural symmetry) с IntPtr типом.
Примеры перехвата сообщений
В данном приложении очередь сообщений запускается без использования дополнительных классов. Выполняется в режиме отладки. Причина, по которой приложение не реагирует на сообщения системы при запуске в обычном режиме, в настоящее время мне не известна.
using System;
using System.Windows.Forms;
namespace MessageLoop01
{
// A message filter.
public class MyMessageFilter : IMessageFilter
{
long nMess = 0;
public bool PreFilterMessage(ref Message m)
{
nMess++;
Console.WriteLine
(“Processing the messages: {0} - {1}: {2}”,m.Msg, nMess,
Application.MessageLoop); return false;
}
}
///<summary>
///Summary description for Class1.
///</summary>
class Class1
{
///<summary>
///The main entry Point for the application.
///</summary>
static void Main(string[] args)
{
Application.AddMessageFilter(new MyMessageFilter()); Application.Run();
}
}
}
189
В следующем примере объект-представитель класса Form связан с оконной процедурой, в рамках которой и запускается цикл обработки сообщений. Замечательное сочетание консольного приложения с окном формы.
using System;
using System.Windows.Forms;
namespace MessageLoop01
{
// A message filter.
public class MyMessageFilter : IMessageFilter
{
long nMess = 0;
public bool PreFilterMessage(ref Message m)
{
nMess++;
Console.WriteLine
(“Processing the messages: {0} - {1}:{2} > {3}”,m.Msg,m.LParam,m.WParam,nMess); return false;
}
}
class MyForm:Form
{
public MyForm()
{
if (Application.MessageLoop) Console.WriteLine(“Yes!”); else Console.WriteLine(“No!”);
Application.AddMessageFilter(new MyMessageFilter());
}
}
///<summary>
///Summary description for Class1.
///</summary>
class Class1
{
///<summary>
///The main entry Point for the application.
///</summary>
[STAThread]
static void Main(string[] args)
{
if (Application.MessageLoop) Console.WriteLine(“Yes!”); else Console.WriteLine(“No!”);
Application.Run(new MyForm());
}
}
}
Метод WndProc
В классах - наследниках класса Control (в классах Form, Кнопка, Список, …) объявляется виртуальный метод WndProc, который обеспечивает обработку передаваемых приложению сообщений Windows. Переопределение этого метода позволяет задавать специфику поведения создаваемого элемента управления, включая и саму форму.
protected virtual void WndProc(ref Message m); Parameters
m
The Windows Message to process.
190
Все сообщения после PreProcessMessage метода поступают к WndProc методу. В сущности, ничего не изменилось! WndProc method в точности соответствует
WindowProc функции.
Пример переопределения WndProc
Реакция приложения на передаваемые в оконную процедуру WndProc сообщения Windows определяет поведение приложения. Метод WndProc в приложении может быть переопределён. При его переопределении следует иметь в виду, что для адекватного поведения приложения в среде Windows необходимо обеспечить вызов базовой версии метода WndProc. Всё, что не было обработано в рамках переопределённого метода WndProc, должно обрабатываться в методе базового класса.
Ниже демонстрируется пример переопределения метода WndProc. В результате переопределения приложение “научилось” идентифицировать и реагировать на системное сообщение WM_ACTIVATEAPP, которое передаётся каждому приложению при переводе приложения из активного состояния в пассивное и обратно.
using System;
using System.Drawing; using System.Windows.Forms;
namespace csTempWindowsApplication1
{
public class Form1 : System.Windows.Forms.Form
{
//Здесь определяется константа, которая содержится в «windows.h» header file. private const int WM_ACTIVATEAPP = 0x001C;
//Флаг активности приложения.
private bool appActive = true;
[STAThread] static void Main()
{
Application.Run(new Form1());
}
//=================================================================== public Form1()
{
// Задание свойств формы.
this.Size = new System.Drawing.Size(300,300); this.Text = “Form1”;
this.Font = new System.Drawing.Font(“Microsoft Sans Serif”, 18F,
System.Drawing.FontStyle.Bold,
System.Drawing.GraphicsUnit.Point,
((System.Byte)(0))
);
}
//===================================================================
//===================================================================
//Вот переопределённая оконная процедура. protected override void WndProc(ref Message m)
{
//Listen for operating system messages. switch (m.Msg)
{
//Сообщение под кодовым названием WM_ACTIVATEAPP occurs when the application
//becomes the active application or becomes inactive.
case WM_ACTIVATEAPP:
//The WParam value identifies what is occurring. appActive = (((int)m.WParam != 0));
//Invalidate to get new text painted. this.Invalidate();
break;
}
base.WndProc(ref m);
191