Именно с этого совета (№ 3) три года назад мы начали свои публикации для пользователей VB в КомпьютерПресс № 396. Напомнить о нем мы решили для иллюстрации применения функции CopyMemory.
Дело в том, что в DOS-овских версиях Microsoft Basic (Quick, PDS, Visual) имелась группа очень полезных встроенных функций MKx$/CVx (x тип числовых данных: I, L, S, D), которые
С помощью этих функций производится преобразование числовых (целых, вещественных и пр.) данных в строковый формат и наоборот. Точнее говоря, никакого преобразования значений здесь не выполняется, а просто
Основной смысл такого преобразования это возможность хранения и передачи разнотипных данных в виде одной строковой переменной, что является отличной альтернативой структурам данных Type с их жестким описанием полей на уровне исходного текста. В свое время мы очень широко использовали в своей практике этот прием для создания гибких, динамически настраиваемых структур данных.
Применение данных функций позволяет осуществлять весьма изящные преобразования данных. Например, в Совете 117 мы говорили о проблеме обработки беззнаковых целых чисел и приводили пример слияния двух
Сравните приведенный там пример со следующим вариантом:
IntHigh% = CVI(LEFT$(MKL$(LongValue&), 2)) IntLow% = CVI(RIGHT$(MKL$(LongValue&), 2)) ' вместо Совета 117 IntegetHigh% = LongValue& \ &H10000 IntegerLow% = LongValue& And &H7FFF If (LongValue& AND &H8000) <> 0 Then IntegerLow% = IntegerLow% Or &H8000 End If
LongValue& = CVL(MKI$(IntHigh%) + MKI$(IntLow%)) ' вместо Совета 117 LongValue& = IntHigh% * &H10000 + (IntegerLow% AND &H7FFF) If IntegerLow% < 0 Then LongValue& = LongValue& or &h8000&
С помощью функций Win API в VB/Win можно довольно просто реализовать эти полезные Basic-функции. Набор таких процедур приведен в модуле MKXCVX.BAS, а пример их применения в модуле MKXCVXTS.BAS.
Attribute VB_Name = "MKxCVxTS"
Sub main()
'
' Пример обращения к функциям MKx$, CVx
' в стиле "a-la" Microsoft Basic for DOS (QB/PDS/VBDOS)
IntValue% = 12345
x$ = MKI$(IntValue%)
MsgBox Str$(CVI(x$)), , "Integer"
'
LongValue& = 12345678
x$ = MKL$(LongValue&)
MsgBox Str$(CVL(x$)), , "Long"
'
SingleValue! = 123.45
x$ = MKS$(SingleValue!)
MsgBox Str$(CVS(x$)), , "Single"
'
DoubleValue# = 1.2345
x$ = MKD$(DoubleValue#)
MsgBox Str$(CVD(x$)), , "Double"
'
End Sub
===============================================================
Attribute VB_Name = "MKxCVx32"
#If Win32 Then
Public Declare Sub HMemCpy Lib "kernel32" Alias _
"RtlMoveMemory" (Destination As Any, Source As Any, _
ByVal Length As Long)
#Else
Declare Sub HMemCpy Lib "kernel" (hpvDest As Any, _
hpvSource As Any, ByVal cbCopy As Long)
#End If
'
' Реализация функций CVx/MKx$ с помощью обращения к
' функциям Windows API — HmemCpy или RtlMoveMemory
' (копирование заданного числа байт из одной области
' памяти в другую)
'
' ПРИМЕЧАНИЕ. Передача строковой переменной по значению
' (ByVal) означает, что в функцию HMemCpy передается
' адрес не описателя, а самой строки
'
Function CVD(x$) As Double
HMemCpy Temp#, ByVal x$, 8
CVD = Temp#
End Function
Function CVI(x$) As Integer
HMemCpy Temp%, ByVal x$, 2
CVI = Temp%
End Function
Function CVL(x$) As Long
HMemCpy Temp&, ByVal x$, 4
CVL = Temp&
End Function
Function CVS(x$) As Single
HMemCpy Temp!, ByVal x$, 4
CVS = Temp!
End Function
Function MKD$(x#)
Dim Temp As String * 8
HMemCpy ByVal Temp, x#, 8
MKD$ = Temp
End Function
Function MKI$(x%)
Dim Temp As String * 2
HMemCpy ByVal Temp, x%, 2
MKI$ = Temp
End Function
Function MKL$(x&)
Dim Temp As String * 4
HMemCpy ByVal Temp, x&, 4
MKL$ = Temp
End Function
Function MKS$(x!)
Dim Temp As String * 4
HMemCpy ByVal Temp, x!, 4
MKS$ = Temp
End Function