Windows api message codes

Window Messages (Get Started with Win32 and C++)

A GUI application must respond to events from the user and from the operating system.

  • Events from the user include all the ways that someone can interact with your program: mouse clicks, key strokes, touch-screen gestures, and so on.
  • Events from the operating system include anything «outside» of the program that can affect how the program behaves. For example, the user might plug in a new hardware device, or Windows might enter a lower-power state (sleep or hibernate).

These events can occur at any time while the program is running, in almost any order. How do you structure a program whose flow of execution cannot be predicted in advance?

To solve this problem, Windows uses a message-passing model. The operating system communicates with your application window by passing messages to it. A message is simply a numeric code that designates a particular event. For example, if the user presses the left mouse button, the window receives a message that has the following message code.

Some messages have data associated with them. For example, the WM_LBUTTONDOWN message includes the x-coordinate and y-coordinate of the mouse cursor.

To pass a message to a window, the operating system calls the window procedure registered for that window. (And now you know what the window procedure is for.)

The Message Loop

An application will receive thousands of messages while it runs. (Consider that every keystroke and mouse-button click generates a message.) Additionally, an application can have several windows, each with its own window procedure. How does the program receive all these messages and deliver them to the correct window procedure? The application needs a loop to retrieve the messages and dispatch them to the correct windows.

For each thread that creates a window, the operating system creates a queue for window messages. This queue holds messages for all the windows that are created on that thread. The queue itself is hidden from your program. You cannot manipulate the queue directly. However, you can pull a message from the queue by calling the GetMessage function.

This function removes the first message from the head of the queue. If the queue is empty, the function blocks until another message is queued. The fact that GetMessage blocks will not make your program unresponsive. If there are no messages, there is nothing for the program to do. If you have to perform background processing, you can create additional threads that continue to run while GetMessage waits for another message. (See Avoiding Bottlenecks in Your Window Procedure.)

The first parameter of GetMessage is the address of a MSG structure. If the function succeeds, it fills in the MSG structure with information about the message. This includes the target window and the message code. The other three parameters let you filter which messages you get from the queue. In almost all cases, you will set these parameters to zero.

Although the MSG structure contains information about the message, you will almost never examine this structure directly. Instead, you will pass it directly to two other functions.

The TranslateMessage function is related to keyboard input. It translates keystrokes (key down, key up) into characters. You do not really have to know how this function works; just remember to call it before DispatchMessage. The link to the MSDN documentation will give you more information, if you are curious.

The DispatchMessage function tells the operating system to call the window procedure of the window that is the target of the message. In other words, the operating system looks up the window handle in its table of windows, finds the function pointer associated with the window, and invokes the function.

For example, suppose that the user presses the left mouse button. This causes a chain of events:

  1. The operating system puts a WM_LBUTTONDOWN message on the message queue.
  2. Your program calls the GetMessage function.
  3. GetMessage pulls the WM_LBUTTONDOWN message from the queue and fills in the MSG structure.
  4. Your program calls the TranslateMessage and DispatchMessage functions.
  5. Inside DispatchMessage, the operating system calls your window procedure.
  6. Your window procedure can either respond to the message or ignore it.

When the window procedure returns, it returns back to DispatchMessage. This returns to the message loop for the next message. As long as your program is running, messages will continue to arrive on the queue. Therefore, you must have a loop that continually pulls messages from the queue and dispatches them. You can think of the loop as doing the following:

As written, of course, this loop would never end. That is where the return value for the GetMessage function comes in. Normally, GetMessage returns a nonzero value. When you want to exit the application and break out of the message loop, call the PostQuitMessage function.

The PostQuitMessage function puts a WM_QUIT message on the message queue. WM_QUIT is a special message: It causes GetMessage to return zero, signaling the end of the message loop. Here is the revised message loop.

As long as GetMessage returns a nonzero value, the expression in the while loop evaluates to true. After you call PostQuitMessage, the expression becomes false and the program breaks out of the loop. (One interesting result of this behavior is that your window procedure never receives a WM_QUIT message. Therefore, you do not have to have a case statement for this message in your window procedure.)

The next obvious question is when to call PostQuitMessage. We’ll return to this question in the topic Closing the Window, but first we have to write our window procedure.

Posted Messages versus Sent Messages

The previous section talked about messages going onto a queue. Sometimes, the operating system will call a window procedure directly, bypassing the queue.

Читайте также:  Пароль для windows 2003

The terminology for this distinction can be confusing:

  • Posting a message means the message goes on the message queue, and is dispatched through the message loop (GetMessage and DispatchMessage).
  • Sending a message means the message skips the queue, and the operating system calls the window procedure directly.

For now, the difference is not very important. The window procedure handles all messages. However, some messages bypass the queue and go directly to your window procedure. However, it can make a difference if your application communicates between windows. You can find a more thorough discussion of this issue in the topic About Messages and Message Queues.

Пошаговое руководство. Вызов API Windows (Visual Basic) Walkthrough: Calling Windows APIs (Visual Basic)

Windows API — это библиотеки динамической компоновки (DLL), которые являются частью операционной системы Windows. Windows APIs are dynamic-link libraries (DLLs) that are part of the Windows operating system. Они используются для выполнения задач, когда трудно писать эквивалентные процедуры. You use them to perform tasks when it is difficult to write equivalent procedures of your own. Например, Windows предоставляет функцию с именем FlashWindowEx , которая позволяет сделать строку заголовка для приложения альтернативой светлой и темной тени. For example, Windows provides a function named FlashWindowEx that lets you make the title bar for an application alternate between light and dark shades.

Преимущество использования API-интерфейсов Windows в коде состоит в том, что они могут сэкономить время разработки, поскольку они содержат десятки полезных функций, которые уже написаны и ожидают использования. The advantage of using Windows APIs in your code is that they can save development time because they contain dozens of useful functions that are already written and waiting to be used. Недостаток заключается в том, что API Windows может быть трудно работать с и унфоргивинг в случае неправильной работы. The disadvantage is that Windows APIs can be difficult to work with and unforgiving when things go wrong.

Интерфейсы API Windows представляют особую категорию взаимодействия. Windows APIs represent a special category of interoperability. Интерфейсы API Windows не используют управляемый код, не имеют встроенных библиотек типов и используют типы данных, отличные от используемых в Visual Studio. Windows APIs do not use managed code, do not have built-in type libraries, and use data types that are different than those used with Visual Studio. Из-за этих различий и, поскольку интерфейсы API Windows не являются объектами COM, взаимодействия с API Windows и платформа .NET Framework выполняются с помощью вызова неуправляемого кода или PInvoke. Because of these differences, and because Windows APIs are not COM objects, interoperability with Windows APIs and the .NET Framework is performed using platform invoke, or PInvoke. Платформенный вызов — это служба, которая позволяет управляемому коду вызывать неуправляемые функции, реализованные в библиотеках DLL. Platform invoke is a service that enables managed code to call unmanaged functions implemented in DLLs. Дополнительные сведения см. в разделе Использование неуправляемых функций DLL. For more information, see Consuming Unmanaged DLL Functions. Вы можете использовать PInvoke в Visual Basic, используя либо Declare инструкцию, либо применяя DllImport атрибут к пустой процедуре. You can use PInvoke in Visual Basic by using either the Declare statement or applying the DllImport attribute to an empty procedure.

Вызовы Windows API были важной частью Visual Basic программирования в прошлом, но они редко требуются для Visual Basic .NET. Windows API calls were an important part of Visual Basic programming in the past, but are seldom necessary with Visual Basic .NET. Везде, где это возможно, следует использовать управляемый код из платформа .NET Framework для выполнения задач, а не вызовов Windows API. Whenever possible, you should use managed code from the .NET Framework to perform tasks, instead of Windows API calls. В этом пошаговом руководстве содержатся сведения о ситуациях, в которых требуется использовать API Windows. This walkthrough provides information for those situations in which using Windows APIs is necessary.

Отображаемые на компьютере имена или расположения некоторых элементов пользовательского интерфейса Visual Studio могут отличаться от указанных в следующих инструкциях. Your computer might show different names or locations for some of the Visual Studio user interface elements in the following instructions. Это зависит от имеющегося выпуска Visual Studio и используемых параметров. The Visual Studio edition that you have and the settings that you use determine these elements. Дополнительные сведения см. в разделе Персонализация среды IDE. For more information, see Personalizing the IDE.

Вызовы API с помощью Declare API Calls Using Declare

Наиболее распространенным способом вызова API Windows является использование Declare инструкции. The most common way to call Windows APIs is by using the Declare statement.

Объявление процедуры DLL To declare a DLL procedure

Определите имя функции, которую необходимо вызвать, а также ее аргументы, типы аргументов и возвращаемое значение, а также имя и расположение библиотеки DLL, содержащей ее. Determine the name of the function you want to call, plus its arguments, argument types, and return value, as well as the name and location of the DLL that contains it.

Полные сведения о API Windows см. в документации по пакету SDK для Win32 в Windows API Platform SDK. For complete information about the Windows APIs, see the Win32 SDK documentation in the Platform SDK Windows API. Дополнительные сведения о константах, используемых API Windows, см. в файлах заголовков, таких как Windows. h, входящих в состав пакета Platform SDK. For more information about the constants that Windows APIs use, examine the header files such as Windows.h included with the Platform SDK.

Откройте новый проект приложения Windows, щелкнув создать в меню файл , а затем выбрав пункт проект. Open a new Windows Application project by clicking New on the File menu, and then clicking Project. Откроется диалоговое окно Новый проект . The New Project dialog box appears.

Выберите приложение Windows в списке шаблонов проектов Visual Basic. Select Windows Application from the list of Visual Basic project templates. Отобразится новый проект. The new project is displayed.

Добавьте следующую Declare функцию либо в класс, либо в модуль, в котором требуется использовать библиотеку DLL: Add the following Declare function either to the class or module in which you want to use the DLL:

Части инструкции DECLARE Parts of the Declare Statement

Declare Инструкция включает следующие элементы. The Declare statement includes the following elements.

Читайте также:  Silverlight mac os big sur

Модификатор Auto Auto modifier

Auto Модификатор указывает среде выполнения преобразовать строку на основе имени метода в соответствии с правилами среды CLR (или именем псевдонима, если оно указано). The Auto modifier instructs the runtime to convert the string based on the method name according to common language runtime rules (or alias name if specified).

Ключевые слова lib и Alias Lib and Alias keywords

Имя, следующее за Function ключевым словом, — это имя, которое программа использует для доступа к импортируемой функции. The name following the Function keyword is the name your program uses to access the imported function. Оно может совпадать с реальным именем вызываемой функции, или можно использовать любое допустимое имя процедуры, а затем применить Alias ключевое слово, чтобы указать реальное имя вызываемой функции. It can be the same as the real name of the function you are calling, or you can use any valid procedure name and then employ the Alias keyword to specify the real name of the function you are calling.

Укажите Lib ключевое слово, а затем имя и расположение библиотеки DLL, содержащей вызываемую функцию. Specify the Lib keyword, followed by the name and location of the DLL that contains the function you are calling. Указывать путь к файлам, расположенным в системных каталогах Windows, не требуется. You do not need to specify the path for files located in the Windows system directories.

Используйте Alias ключевое слово, если имя вызываемой функции не является допустимым Visual Basic именем процедуры или конфликтует с именами других элементов в приложении. Use the Alias keyword if the name of the function you are calling is not a valid Visual Basic procedure name, or conflicts with the name of other items in your application. Alias Указывает на истинное имя вызываемой функции. Alias indicates the true name of the function being called.

Объявления аргументов и типов данных Argument and Data Type Declarations

Объявите аргументы и их типы данных. Declare the arguments and their data types. Эта часть может быть сложной, поскольку типы данных, используемые Windows, не соответствуют типам данных Visual Studio. This part can be challenging because the data types that Windows uses do not correspond to Visual Studio data types. Visual Basic выполняет большой объем работы, преобразуя аргументы в совместимые типы данных, процесс, называемый упаковкой. Visual Basic does a lot of the work for you by converting arguments to compatible data types, a process called marshaling. Можно явно управлять упаковкой аргументов с помощью MarshalAsAttribute атрибута, определенного в System.Runtime.InteropServices пространстве имен. You can explicitly control how arguments are marshaled by using the MarshalAsAttribute attribute defined in the System.Runtime.InteropServices namespace.

Предыдущие версии Visual Basic позволяли объявлять параметры As Any , то есть могут использоваться данные любого типа данных. Previous versions of Visual Basic allowed you to declare parameters As Any , meaning that data of any data type could be used. Visual Basic требует, чтобы для всех инструкций использовался конкретный тип данных Declare . Visual Basic requires that you use a specific data type for all Declare statements.

Константы Windows API Windows API Constants

Некоторые аргументы являются сочетаниями констант. Some arguments are combinations of constants. Например, API, MessageBox показанный в этом пошаговом руководстве, принимает целочисленный аргумент Typ с именем, который управляет отображением окна сообщения. For example, the MessageBox API shown in this walkthrough accepts an integer argument called Typ that controls how the message box is displayed. Можно определить числовое значение этих констант, изучив #define инструкции в файле WinUser. h. You can determine the numeric value of these constants by examining the #define statements in the file WinUser.h. Числовые значения обычно отображаются в шестнадцатеричном виде, поэтому для их добавления и преобразования в десятичный формат может потребоваться калькулятор. The numeric values are generally shown in hexadecimal, so you may want to use a calculator to add them and convert to decimal. Например, если вы хотите объединить константы для стиля с восклицательным знаком MB_ICONEXCLAMATION 0x00000030, а стиль «да/нет MB_YESNO », можно добавить числа и получить результат 0x00000034 или 52 Decimal. For example, if you want to combine the constants for the exclamation style MB_ICONEXCLAMATION 0x00000030 and the Yes/No style MB_YESNO 0x00000004, you can add the numbers and get a result of 0x00000034, or 52 decimal. Хотя вы можете использовать десятичный результат непосредственно, лучше объявить эти значения как константы в приложении и объединить их с помощью Or оператора. Although you can use the decimal result directly, it is better to declare these values as constants in your application and combine them using the Or operator.

Объявление констант для вызовов API Windows To declare constants for Windows API calls

Обратитесь к документации по функции Windows, которую вы вызываете. Consult the documentation for the Windows function you are calling. Определите имена констант, которые он использует, и имя h файла, содержащего числовые значения для этих констант. Determine the name of the constants it uses and the name of the .h file that contains the numeric values for these constants.

Используйте текстовый редактор, например Блокнот, для просмотра содержимого файла заголовка (. h) и поиска значений, связанных с используемыми константами. Use a text editor, such as Notepad, to view the contents of the header (.h) file, and find the values associated with the constants you are using. Например, MessageBox API использует константу MB_ICONQUESTION для отображения вопросительного знака в окне сообщения. For example, the MessageBox API uses the constant MB_ICONQUESTION to show a question mark in the message box. Определение для MB_ICONQUESTION находится в файле WinUser. h и выглядит следующим образом: The definition for MB_ICONQUESTION is in WinUser.h and appears as follows:

#define MB_ICONQUESTION 0x00000020L

Добавьте эквивалентные Const операторы в класс или модуль, чтобы сделать эти константы доступными для приложения. Add equivalent Const statements to your class or module to make these constants available to your application. Пример: For example:

Вызов процедуры DLL To call the DLL procedure

Добавьте кнопку с именем Button1 в форму запуска проекта, а затем дважды щелкните ее, чтобы просмотреть код. Add a button named Button1 to the startup form for your project, and then double-click it to view its code. Появится обработчик событий для кнопки. The event handler for the button is displayed.

Добавьте код в Click обработчик событий для добавленной кнопки, чтобы вызвать процедуру и предоставить соответствующие аргументы: Add code to the Click event handler for the button you added, to call the procedure and provide the appropriate arguments:

Читайте также:  Вирусы для linux статистика

Запустите проект, нажав клавишу F5. Run the project by pressing F5. Появится окно сообщения с кнопками Да и нет . The message box is displayed with both Yes and No response buttons. Щелкните один из них. Click either one.

Маршалирование данных Data Marshaling

Visual Basic автоматически преобразует типы данных параметров и возвращаемые значения для вызовов API Windows, но можно использовать MarshalAs атрибут, чтобы явно указать неуправляемые типы данных, которые ОЖИДАЕТ API. Visual Basic automatically converts the data types of parameters and return values for Windows API calls, but you can use the MarshalAs attribute to explicitly specify unmanaged data types that an API expects. Дополнительные сведения о маршалинге взаимодействия см. в разделе Маршалинг взаимодействия. For more information about interop marshaling, see Interop Marshaling.

Использование Declare и MarshalAs в вызове API To use Declare and MarshalAs in an API call

Определите имя функции, которую необходимо вызвать, а также ее аргументы, типы данных и возвращаемое значение. Determine the name of the function you want to call, plus its arguments, data types, and return value.

Чтобы упростить доступ к MarshalAs атрибуту, добавьте Imports оператор в начало кода для класса или модуля, как показано в следующем примере: To simplify access to the MarshalAs attribute, add an Imports statement to the top of the code for the class or module, as in the following example:

Добавьте прототип функции для импортированной функции в класс или модуль, который вы используете, и примените MarshalAs атрибут к параметрам или возвращаемому значению. Add a function prototype for the imported function to the class or module you are using, and apply the MarshalAs attribute to the parameters or return value. В следующем примере вызов API, который принимает тип, void* маршалируется как AsAny : In the following example, an API call that expects the type void* is marshaled as AsAny :

Вызовы API с помощью DllImport API Calls Using DllImport

DllImport Атрибут предоставляет второй способ вызова функций в библиотеках DLL без библиотек типов. The DllImport attribute provides a second way to call functions in DLLs without type libraries. DllImport примерно эквивалентно использованию оператора, Declare но обеспечивает более полный контроль над вызовом функций. DllImport is roughly equivalent to using a Declare statement but provides more control over how functions are called.

DllImport С большинством вызовов API Windows можно использовать, если вызов ссылается на общий (иногда называемый статическим) метод. You can use DllImport with most Windows API calls as long as the call refers to a shared (sometimes called static) method. Нельзя использовать методы, для которых требуется экземпляр класса. You cannot use methods that require an instance of a class. В отличие от Declare инструкций DllImport вызовы не могут использовать MarshalAs атрибут. Unlike Declare statements, DllImport calls cannot use the MarshalAs attribute.

Вызов API Windows с помощью атрибута DllImport To call a Windows API using the DllImport attribute

Откройте новый проект приложения Windows, щелкнув создать в меню файл , а затем выбрав пункт проект. Open a new Windows Application project by clicking New on the File menu, and then clicking Project. Откроется диалоговое окно Новый проект . The New Project dialog box appears.

Выберите приложение Windows в списке шаблонов проектов Visual Basic. Select Windows Application from the list of Visual Basic project templates. Отобразится новый проект. The new project is displayed.

Добавьте кнопку с именем Button2 в форму запуска. Add a button named Button2 to the startup form.

Дважды щелкните, Button2 чтобы открыть представление кода для формы. Double-click Button2 to open the code view for the form.

Чтобы упростить доступ к DllImport , добавьте Imports оператор в начало кода для класса формы Startup: To simplify access to DllImport , add an Imports statement to the top of the code for the startup form class:

Объявите пустую функцию перед End Class оператором для формы и назовите функцию MoveFile . Declare an empty function preceding the End Class statement for the form, and name the function MoveFile .

Примените Public Shared модификаторы и к объявлению функции и задайте параметры в MoveFile зависимости от аргументов, используемых функцией Windows API: Apply the Public and Shared modifiers to the function declaration and set parameters for MoveFile based on the arguments the Windows API function uses:

Функция может иметь любое допустимое имя процедуры; DllImport атрибут указывает имя в библиотеке DLL. Your function can have any valid procedure name; the DllImport attribute specifies the name in the DLL. Он также обрабатывает упаковку взаимодействия для параметров и возвращаемых значений, поэтому можно выбирать типы данных Visual Studio, аналогичные типам данных, используемым API. It also handles interoperability marshaling for the parameters and return values, so you can choose Visual Studio data types that are similar to the data types the API uses.

Примените DllImport атрибут к пустой функции. Apply the DllImport attribute to the empty function. Первый параметр — это имя и расположение библиотеки DLL, содержащей вызываемую функцию. The first parameter is the name and location of the DLL containing the function you are calling. Указывать путь к файлам, расположенным в системных каталогах Windows, не требуется. You do not need to specify the path for files located in the Windows system directories. Второй параметр — это именованный аргумент, указывающий имя функции в API Windows. The second parameter is a named argument that specifies the name of the function in the Windows API. В этом примере DllImport атрибут принудительно MoveFile перенаправляет вызовы в MoveFileW в KERNEL32.DLL. In this example, the DllImport attribute forces calls to MoveFile to be forwarded to MoveFileW in KERNEL32.DLL. MoveFileW Метод копирует файл из пути src в путь dst . The MoveFileW method copies a file from the path src to the path dst .

Добавьте код в Button2_Click обработчик событий для вызова функции: Add code to the Button2_Click event handler to call the function:

Создайте файл с именем Test.txt и поместите его в каталог К:\тмп на жестком диске. Create a file named Test.txt and place it in the C:\Tmp directory on your hard drive. При необходимости создайте каталог tmp. Create the Tmp directory if necessary.

Нажмите клавишу F5 для запуска приложения. Press F5 to start the application. Откроется Главная форма. The main form appears.

Нажмите кнопку Button2. Click Button2. Если файл можно переместить, отображается сообщение «файл перемещен успешно». The message «The file was moved successfully» is displayed if the file can be moved.

Оцените статью