Программирование >>  Автоматически обновляемые приложения 

1 ... 149 150 151 [ 152 ] 153 154 155 ... 170


Вызов функций Windows API, имеющих выходной строковый параметр char*

Предположим, нам необходимо вызвать функцию GetwindowText, у которой имеется строковый выходной параметр char*. По умолчанию для строк используется LPTSTR, но если мы будем использовать System.string, как было сказано выше, то ничего не произойдет, так как класс System.string не позволяет модифицировать строку. Вам необходимо использовать класс StringBuilder, который позволяет изменять строки. Пример показан в листинге 17.2.

i Листинг 17.1. Объявление и использование функции Windows API

using System.Runtime.InteropServices;

public class Win32 {

[Dlllmport( User32.Dll ) ]

public static extern void SetWindowText(IntPtr hwnd. String IpString);

Атрибут Dlllmport сообщает компилятору, где находится точка входа, что позволяет далее вызывать функцию из нужного места. Вы должны всегда использовать тип intptr для hwnd, hmenu и любых других описателей. Для lpctstr используйте string, а сервисы взаимодействия (interop services) выполнят автоматический маршалинг System, string в lpctstr до передачи в Windows. Компилятор ищет указанную выше функцию SetwindowText в файле User32.dll и перед ее вызовом автоматически преобразует вашу строку в lptstr (tchar*). Почему это происходит? Для каждого типа в С# определен свой тип, используемый при маршалинге по умолчанию (default marshaling type). Для строк это lptstr.

Часть советов, приводимых ниже, были взяты из разных номеров журнала MSDN Magazine .



\ Листинг 17.2. Работа с строковыми параметрами в функциях Windows API

using System.Text; для StringBuiider [Dlllmport( user32.dll )]

public static extern int GetWindowText(IntPtr hwnd, StringBuiider buf, int nMaxCount);

Тип, используемый для маршалинга stringBuiider по умолчанию,- тоже LPTSTR, зато теперь GetWindowText может модифицировать саму вашу строку (листинг 17.3).

Листинг 17.3. Применение функции GetWindowText

StringBuiider sTitleBar = new StringBuiider(255); GetWindowText(this.Handle, sTitleBar, sTitleBar.Capacity); MessageBox.Show(sTitleBar.ToString 0);

Таким образом, ответом на вопрос, как вызывать функцию, у которой есть

выходной строковый параметр, будет- используйте класс stringBuiider.

Изменение типа, применяемого для маршалинга по умолчанию

Например, мы хотим вызвать функцию GetciassName, которая принимает параметр lpstr (char*) даже в Unicode-версиях. Если вы передадите строку, общеязыковая исполняющая среда (CLR) преобразует ее в серию tchar. Но с помощью атрибута MarshalAs можно переопределить то, что предлагается по умолчанию, как показано в листинге 17.4.

J; Листинг 17.4. Переопределение типов при помощи MarshalAs

[Dlllmport( user32.dll )]

public static extern int GetClassName(IntPtr hwnd,

[MarshalAs(UnmanagedType.LPStr)] StringBuiider buf, int nMaxCount);

Теперь, когда вы вызовете GetciassName, .NET передаст вашу строку в виде символов ANSI, а не широких символов .



I Листинг 17.5. Использование типа struct

[StructLayout(LayoutKind.Sequential)] public struct RECT {

public int left ; public int top; public int right; public int bottom;

[Dlllmport( user32.dll )]

public static extern int GetwindowRect(IntPtr hwnd, ref RECT rc);

Важно использовать ref, чтобы CLR передала параметр типа rect как ссылку. В этом случае функция сможет модифицировать ваш объект, а не его безымянную копию в стеке. После такого объявления функции можно ее вызвать в коде (листинг 17.6).

Листинг 17.6. Использование структуры при вызове функции Windows API

int w, h;

RECT rc = new RECT(); GetwindowRect(this.Handle, ref rc) ; w = rc.right - rc.left; h = rc.bottom - rc.top;

MessageBox.Show( Ширина формы: + w + \п\гВысота формы: + h) ;

Обратите внимание, что ref используется и в объявлении, и при вызове функции. Тип, по умолчанию применяемый для маршалинга типов struct - LPStruct, поэтому необходимости в атрибуте MarshalAs нет. Но если вы хотите использовать rect в виде класса, а не struct, вам необходимо реализовать оболочку, показанную в листинге 17.7.

Вызов функций, требующих struct

Возьмем для примера функцию GetwindowRect, которая записывает в структуру RECT экранные координаты окна. Чтобы вызвать функцию GetwindowRect И передать ей структуру RECT, нужно использовать тип struct в сочетании с атрибутом StructLayout, как показано в листинге 17.5.



1 ... 149 150 151 [ 152 ] 153 154 155 ... 170

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика