Читая Эпплмана

Немного теории - 1

О чем должен помнить программист, по Эпплману, для корректной работы с API-функциями.

1. Пропуск ключевого слова ByVal, в объявлении аргументов всегда ведет к нарушению содержимого памяти, и как результат, к фатальным последствиям.
2. Неуказанные типы аргументов, а так же неуказанный тип возвращаемого значения самой функции, воспринимается бейсиком как Variant, что приводит к появлению трудно отлавливаемых ошибок.
3. При вызове API-функций, следите за соответствием типов передаваемых значений.

Соответствие типов в С и VB(Win32)*

Объявление в С Объявление в VB
char Byte
BYTE Byte
short Integer
WORD Integer
int Long
UINT Long
BOOL Long
DWORD Long
LONG Long
float Single
double Double
VARIANT Variant
VARIANTARG Variant
HWND Long
HPEN Long
HGLOBAL Long

_
* Данная таблица верна для VB4(32-разрядная версия), VB5, VB6.
В VB.Net предполагается изменение некоторых типов в бейсике.

И еще немного о типах (красным выделено мной для более легкого восприятия изменений). 
Declare Function LoadCursor Lib "user32" Alias "LoadCursorA" _
(ByVal hInstance As Long, lpCursorName As Any) As Long

Тип As Any подразумевает, что на данной позиции могут использоваться аргументы с различными типами. Поэтому вызов данной функции в бейсике должен выглядеть так:
res& = LoadCursor&(hmodule&, ByVal cursorname$)
где hmodule = манипулятор модуля, содержащего курсор, а cursorname - имя ресурса курсора.
Или так:
res& = LoadCursor&(hmodule&, ByVal cursorid&)
где cursorid идентифицирует ресурс курсора.

Чтобы не забыть про ByVal при вызове функции, можно исправить декларацию следующим образом:
Declare Function LoadCursor Lib "user32" Alias "LoadCursorA" _
(ByVal hInstance As Long,
ByVal lpCursorName As Any) As Long
Естественно, при вызове функции ключевое слово ByVal будет опущено.
res& = LoadCursor&(hmodule&, cursorname$)

Однако сам Эпплман предлагает (и сам постоянно этим пользуется) использовать псевдонимы в объявлении функции, что обеспечит жесткую проверку типов и позволит избежать ошибок. В этом варианте данная API-функция превращается в две, каждая их которых работает со своим типом:
Declare Function LoadCursorByName Lib "user32" Alias "LoadCursorA" _
(ByVal hInstance As Long,
ByVal lpCursorName As String) As Long

Declare Function LoadCursorByID Lib "user32" Alias "LoadCursorA" _
(ByVal hInstance As Long,
ByVal lpCursorName As Long) As Long

 
Назад Далее  

Hosted by uCoz