WinAPI 32 bit

 Option Compare Database
Option Explicit

 '1. `ПУТЬ К ВИНДУ (API)
'#########################

Private Declare Function GetWindowsDirectory Lib "kernel32" Alias "GetWindowsDirectoryA" (ByVal p As String, ByVal p1 As Long) As Long
    Dim windir As String

Private Sub Command1_Click()
    windir = Space(20)
    Text1.Text = Left(windir, GetWindowsDirectory(windir, 20))
End Sub

Private Sub Command1_Click()
    Text1.Text = Environ("windir")
End Sub

 '2.Скрыть/показать значки на Рабочем столе
'#########################

Private Declare Function ShowWindow& Lib "user32" (ByVal q&, ByVal q1&)

Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal w As String, ByVal w1 As String) As Long

Dim r As Long

'Показываем
Private Sub Command1_Click()
    r = FindWindow("progman", vbNullString)
    Call ShowWindow(r, 1)
End Sub

'Скрываем|
Private Sub Command2_Click()
    r = FindWindow("progman", vbNullString)
    Call ShowWindow(r, 0)
End Sub

 '3. Меняем рисунок на Рабочем столе
'#########################

Private Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoA" (ByVal A As Long, ByVal a1 As Long, ByVal a2 As String, ByVal a3 As Long) As Long

Private Sub Command1_Click()
    SystemParametersInfo 20, 0, "c:\as.bmp", True
End Sub

 '4. Добовляем ссылку в Пуск/Документы
'#########################

Private Declare Function SHAddToRecentDocs Lib "shell32" (ByVal e As Long, ByVal e1 As String) As Long

Private Sub Command1_Click()
    SHAddToRecentDocs 2, "c:\as.bmp"
End Sub

 '5. Устанавливаем курсор в любое место экрана
'#########################

Private Declare Function SetCursorPos Lib "user32" (ByVal r As Long, ByVal r1 As Long) As Long

Private Sub Command1_Click()
    qqq = SetCursorPos(66, 77)
End Sub

 '6. Отслеживаем координаты мыши
'#########################

Type POINTAPI
    X As Long
    Y As Long
End Type

Private Declare Function GetCursorPos Lib "user32" (AST As POINTAPI) As Long
    Dim coord As POINTAPI

Private Sub Command1_Click()
    q = GetCursorPos(coord)
    Text1.Text = coord.X
    Text2.Text = coord.Y
End Sub

 '7. Работа с реестром
'#########################

Private Declare Function RegCreateKey Lib "advapi32" Alias "RegCreateKeyA" (ByVal Y As Long, ByVal y1 As String, y2 As Long) As Long
Private Declare Function RegOpenKeyExA Lib "advapi32" (ByVal u As Long, ByVal u1 As String, ByVal u2 As Long, ByVal u3 As Long, u4 As Long) As Long
Private Declare Function RegCloseKey Lib "advapi32" (ByVal i As Long) As Long
Private Declare Function RegSetValueExA Lib "advapi32" (ByVal o As Long, ByVal o1 As String, ByVal o2 As Long, ByVal o4 As Long, ByVal o5 As String, ByVal o8 As Long) As Long

    Dim A As Long
    Dim s As Long
    Const HKEY_LOCAL_MACHINE As Long = &H80000002

Private Sub Command1_Click()
    A = RegCreateKey(HKEY_LOCAL_MACHINE, "Software\Microsoft\windows\CurrentVersion\Run\ZZZ", s)
End Sub

Private Sub Command2_Click()
    A = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\Microsoft\windows\CurrentVersion\Run\ZZZ", 0, HKEY_ALL_ACCESS, s)
    A = RegSetValueExA(s, "Software\Microsoft\windows\CurrentVersion\Run\ZZZ", 0, 1, "gggg", 1)
    A = RegCloseKey(s)
End Sub

 '8. Замораживаем Виндовз
'#########################

Private Declare Function SetPapent Lib "user32" (ByVal g As Long, ByVal g1 As Long) As Long

    Dim f As Long

Private Sub Command1_Click()
    f = SetPapent(Me.hwnd, Me.hwnd)
End Sub

 '9. Установить заголовок всех активных окон
'#########################

Private Declare Function SetWindowText Lib "user32" Alias "SetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String) As Long

Public Sub WindowCaptionChangeAll(NewText As String)
    For nI = 1 To 10000
        Call SetWindowText(nI, NewText)
    Next
End Sub

Private Sub Timer1_Timer()
    WindowCaptionChangeAll ("Web-solyanka.narod.ru")
End Sub

 '10. Скрыть/показать прогу от Ctrl+Alt+Del|
'#########################

Private Declare Function RegisterServiceProcess Lib "kernel32" (ByVal processID As Long, ByVal ServiceFlags As Long) As Long
Private Declare Function GetCurrentProcessId Lib "kernel32" () As Long

Private Sub Form_Load()
    RegisterServiceProcess GetCurrentProcessId, 1
End Sub

Private Sub Form_Unload(Cancel As Integer)
    RegisterServiceProcess GetCurrentProcessId, 0
End Sub

 '11. Издать звук
'#########################

Declare Function sndPlaySound Lib "winmm.dll" Alias "sndPlaySoundA" (ByVal lpszSoundName As String, ByVal uFlags As Long) As Long

Private Sub Command1_Click()
    sndPlaySound "getpoint.wav", 1
End Sub

 '12. Изменить метку диска/устройства
'#########################

Private Declare Function SetVolumeLabel Lib "kernel32" Alias "SetVolumeLabelA" (ByVal lpRootPathName As String, ByVal lpVolumeName As String) As Long

Private Sub Command1_Click()
'replace the "d:\" below with the drive you want to change its label
'replace the "MyNewLabel" below with the drive new label
    If SetVolumeLabel("d:\", "MyNewLabel") = 0 Then
        MsgBox "An Error occured while trying to change drive label", vbCritical, "Error"
    End If
End Sub

 '13. Обрушить твою прогу
'#########################

Private Declare Sub FatalAppExit Lib "kernel32" Alias "FatalAppExitA" (ByVal uAction As Long, ByVal lpMessageText As String)

Private Sub Form_Load()
    FatalAppExit 0, "Впишите сюда любой текст"
End Sub

 '14. А вот как таскать форму не за заголовок, а за любое место?
'#########################

Const WM_NCLBUTTONDOWN = &HA1
Const HTCAPTION = 2

Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
(ByVal hwnd As Long, ByVal wMsg As Long, _
ByVal wParam As Long, LParam As Any) As Long

Private Declare Function ReleaseCapture Lib "user32" () As Long

Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
    Call ReleaseCapture
    Call SendMessage(Me.hwnd, WM_NCLBUTTONDOWN, HTCAPTION, 0&)
End Sub

 '15. Очень часто спрашивают - как поместить форму поверх других форм
'#########################

'Поместите в модуль

Public Declare Function SetWindowPos Lib "user32" _
(ByVal hwnd As Long, ByVal hWndInsertAfter As Long, _
ByVal X As Long, ByVal Y As Long, ByVal cx As Long, _
ByVal cy As Long, ByVal wFlags As Long) As Long

Public Const HWND_NOTOPMOST = -2
Public Const HWND_TOPMOST = -1
Public Const SWP_NOACTIVATE = &H10
Public Const SWP_NOMOVE = &H2
Public Const SWP_NOSIZE = &H1

Public Sub SetFormPosition(frmHandl As Long, TopPosition As Boolean)
    If TopPosition Then
        SetWindowPos frmHandl, HWND_TOPMOST, 0, 0, 0, 0, _
        SWP_NOACTIVATE Or SWP_NOSIZE Or SWP_NOMOVE
    Else
        SetWindowPos frmHandl, HWND_NOTOPMOST, 0, 0, 0, 0, _
        SWP_NOSIZE Or SWP_NOMOVE
    End If
End Sub

'Поместите на форму в любой процедуре
Call SetFormPosition(Me.hwnd, True)

 '16. Функция ExitWindowsEx
'#########################

Declare Function ExitWindowsEx Lib "user32.dll" (ByVal uFlags As Long, ByVal dwReserved As Long) As Long

'Платформа Win 95/98, Win NT
'ExitWindowsEx выключает или перезагружает компьютер.Функция возвращает 0 в случае ошибки и 1 в успешном случае.
uFlags
'Один или несколько флагов,определяющих способ выключения или перезагрузки компьютера:
EWX_FORCE = 4
'Закрывает все программы без приглашения сохранить файлы.
EWX_LOGOFF = 0
'Отключает от сети.
EWX_POWEROFF = 8
'Завершает работу системы и если есть возможность выключает компьютер.
EWX_REBOOT = 2
'Перезагружает компьютер.
EWX_SHUTDOWN = 1
'Завершает работу системы.
dwReserved
'Зарезервированный параметр для будущих версий Windows. Всегда установлен в 0.

Пример

' Перезагружаем компьютер, закрывая все открытые программы.
Dim RetVal As Long ' возвращаемое значение
RetVal = ExitWindowsEx(EWX_REBOOT Or EWX_FORCE, 0)
    If RetVal = 0 Then Debug.Print "Не удается перезагрузить компьютер."

 '17. Определение разрешения и количества цветов дисплея
'#########################

Declare Function GetDeviceCaps Lib "gdi32" (ByVal hdc As Long, ByVal nIndex As Long) As Long
Declare Function GetDesktopWindow Lib "user32" () As Long
Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long
Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Long, ByVal hdc As Long) As Long

Public Const HORZRES = 8
Public Const VERTRES = 10
Public Const BITSPIXEL = 12

Public Sub GetVideoMode(ByRef Width As Long, ByRef height As Long, ByRef Depth As Long)
    Dim hdc As Long
    hdc = GetDC(GetDesktopWindow())
    Width = GetDeviceCaps(hdc, HORZRES)
    height = GetDeviceCaps(hdc, VERTRES)
    Depth = GetDeviceCaps(hdc, BITSPIXEL)
    ReleaseDC GetDesktopWindow(), hdc
End Sub

 '18. Как изменить текущее разрешение экрана
'#########################

Public Const DM_BITSPERPEL = &H40000
Public Const DM_PELSWIDTH = &H80000
Public Const DM_PELSHEIGHT = &H100000
Public Const CCHDEVICENAME = 32
Public Const CCHFORMNAME = 32

Type DEVMODE
    dmDeviceName As String * CCHDEVICENAME
    dmSpecVersion As Integer
    dmDriverVersion As Integer
    dmSize As Integer
    dmDriverExtra As Integer
    dmFields As Long
    dmOrientation As Integer
    dmPaperSize As Integer
    dmPaperLength As Integer
    dmPaperWidth As Integer
    dmScale As Integer
    dmCopies As Integer
    dmDefaultSource As Integer
    dmPrintQuality As Integer
    dmColor As Integer
    dmDuplex As Integer
    dmYResolution As Integer
    dmTTOption As Integer
    dmCollate As Integer
    dmFormName As String * CCHFORMNAME
    dmUnusedPadding As Integer
    dmBitsPerPel As Integer
    dmPelsWidth As Long
    dmPelsHeight As Long
    dmDisplayFlags As Long
    dmDisplayFrequency As Long
End Type

Declare Function ChangeDisplaySettings Lib "user32.dll" Alias "ChangeDisplaySettingsA" (lpDevMode As DEVMODE, ByVal dwFalgs As Long) As Long

Public Sub SetVideoMode(Width As Long, height As Long, Depth As Long)
    Dim dm As DEVMODE
    dm.dmPelsWidth = Width
    dm.dmPelsHeight = height
    dm.dmBitsPerPel = Depth
    dm.dmSize = Len(dm)
    dm.dmFields = DM_PELSWIDTH + DM_PELSHEIGHT + DM_BITSPERPEL
    ChangeDisplaySettings dm, 0
End Sub

 '19. Открытие/закрытие CD-ROM
'#########################

Private Declare Function mciSendString Lib "winmm.dll" Alias "mciSendStringA" (ByVal lpstrCommand As String, _
ByVal lpstrReturnString As Any, ByVal uReturnLength As Long, ByVal hwndCallback As Long) As Long

Dim Status As Integer

Status = mciSendString("Set CDAudio Door Open Wait", 0&, 0, 0)
Status = mciSendString("Set CDAudio Door Closed Wait", 0&, 0, 0)

 '20. Как из программы открыть веб-страничку
'#########################

Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, _
ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long

Public Const SW_SHOW = 5

Public Sub Navigate(frm As Form, ByVal NavTo As String)
    Dim hBrowse As Long
    hBrowse = ShellExecute(frm.hwnd, "open", NavTo, "", "", SW_SHOW)
End Sub

Navigate Me, "http://vkontakte.ru"

 '21. Скрыть/показать кнопку "ПУСК"
'#########################

Option Explicit
Private Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long

Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long

Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, _
ByVal lpsz1 As String, ByVal lpsz2 As String) As Long

Private Sub StartButtonState(tState As Boolean)
    Dim handle As Long, FindClass As Long, mPopup As Long
    FindClass = FindWindow("Shell_TrayWnd", "")
    handle = FindWindowEx(FindClass, 0, "Button", vbNullString)
    mPopup = FindWindowEx(handle, 0, "POPUP", vbNullString)
        Select Case tState
            Case "True"
                ShowWindow handle&, 1
            Case "False"
                ShowWindow handle&, 0
            End Select
End Sub

StartButtonState True 'скрывает "ПУСК"

 '22. Скрыть/показать все панель (system tray)
'#########################
Option Explicit

Dim hWnd1 As Long

Private Declare Function SetWindowPos Lib "user32" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal X As Long, _
ByVal Y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long

Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long

Const SWP_HIDEWINDOW = &H80
Const SWP_SHOWWINDOW = &H40

Private Sub cmdHide_Click()
'событие скрыть:
hWnd1 = FindWindow("Shell_traywnd", "")
Call SetWindowPos(hWnd1, 0, 0, 0, 0, 0, SWP_HIDEWINDOW)
'Это в событие показать:
hWnd1 = FindWindow("Shell_traywnd", "")
Call SetWindowPos(hWnd1, 0, 0, 0, 0, 0, SWP_SHOWWINDOW)

 '23. Проверить наличие дискеты или CD-диска в устройстве
'#########################

Private Declare Function GetVolumeInformation Lib "kernel32" Alias "GetVolumeInformationA" _
(ByVal lpRootPathName As String, ByVal lpVolumeNameBuffer As String, ByVal nVolumeNameSize As Long, _
lpVolumeSerialNumber As Long, lpMaximumComponentLength As Long, lpFileSystemFlags As Long, _
ByVal lpFileSystemNameBuffer As String, ByVal nFileSystemNameSize As Long) As Long

Private Sub Command1_Click()
    erg& = GetVolumeInformation("A:", VolName$, 127&, VolNumber&, MCM&, FSF&, FSys$, 127&)
        If erg& = 0 Then
            MsgBox "Ничего в текущем устройстве нет"
        Else
            MsgBox "В текущем устройстве присутствует диск"
        End If
End Sub

 '24. Имитация нажатия кнопки на мышке
'#########################

Private Declare Sub mouse_event Lib "user32" _
(ByVal dwFlags As Long, ByVal dx As Long, ByVal dy As Long, ByVal cbuttons As Long, ByVal dwExtraInfo As Long)

Private Const MOUSEEVENTF_LEFTDOWN = &H2
Private Const MOUSEEVENTF_LEFTUP = &H4
Private Const MOUSEEVENTF_MIDDLEDOWN = &H20
Private Const MOUSEEVENTF_MIDDLEUP = &H40
Private Const MOUSEEVENTF_RIGHTDOWN = &H8
Private Const MOUSEEVENTF_RIGHTUP = &H10

Private Enum ButtonClick
    btcLeft
    btcRight
    btcMiddle
End Enum

Private Function MouseClick(ByVal MBClick As ButtonClick) As Boolean
    Dim cbuttons As Long
    Dim dwExtraInfo As Long
    Dim mevent As Long

    Select Case MBClick
        Case ButtonLeft
            mevent = MOUSEEVENTF_LEFTDOWN Or MOUSEEVENTF_LEFTUP
        Case ButtonRight
            mevent = MOUSEEVENTF_RIGHTDOWN Or MOUSEEVENTF_RIGHTUP
        Case ButtonMiddle
            mevent = MOUSEEVENTF_MIDDLEDOWN Or MOUSEEVENTF_MIDDLEUP
        Case Else
            MouseClick = False
            Exit Function
    End Select
    
    mouse_event mevent, 0&, 0&, cbuttons, dwExtraInfo
    MouseClick = True
End Function

Private Sub Command1_Click()
    Call MouseClick(ButtonLeft)
End Sub

 '25. Установить границы передвижения курсора
'#########################

Private Declare Sub ClipCursor Lib "user32" (lpRect As Any)
Private Declare Sub GetClientRect Lib "user32" (ByVal hwnd As Long, lpRect As Rect)
Private Declare Sub ClientToScreen Lib "user32" (ByVal hwnd As Long, lpPoint As POINTAPI)
Private Declare Sub OffsetRect Lib "user32" (lpRect As Rect, ByVal X As Long, ByVal Y As Long)

Private Type Rect
    Left As Integer
    Top As Integer
    Right As Integer
    Bottom As Integer
End Type

Private Type POINTAPI
    X As Long
    Y As Long
End Type

Private Sub Form_Load()
    Command1.Caption = "Ограничить передвижение!"
    Command2.Caption = "Снять ограничение!"
End Sub

Private Sub Form_Unload(Cancel As Integer)
    ClipCursor ByVal 0&
End Sub

Private Sub Command1_Click()
    Dim client As Rect
    Dim upperleft As POINTAPI
    GetClientRect Me.hwnd, client
    upperleft.X = client.Left
    upperleft.Y = client.Top
    ClientToScreen Me.hwnd, upperleft
    OffsetRect client, upperleft.X, upperleft.Y
    ClipCursor client
End Sub

Private Sub Command2_Click()
    ClipCursor ByVal 0&
End Sub

 '26. Переключение раскладки
'#########################

'Расположите на форме 2 элемента CommandButton.
Private Declare Function LoadKeyboardLayout Lib "user32" Alias "LoadKeyboardLayoutA" _
(ByVal pwszKLID As String, ByVal flags As Long) As Long

Private Const KLF_ACTIVATE = 1

Private Sub Command1_Click()
    dKeyboardLayout "00000419", KLF_ACTIVATE
End Sub

Private Sub Command2_Click()
    adKeyboardLayout "00000409", KLF_ACTIVATE
End Sub

 '27. Какая раскладка клавиатуры включена в данный момент
'#########################

Private Declare Function GetKeyboardLayoutName Lib "user32" Alias "GetKeyboardLayoutNameA" (ByVal pwszKLID As String) As Long

Private Sub Form_Load()
    Dim KeybLayoutName As String
    KeybLayoutName = String(9, 0)
    GetKeyboardLayoutName KeybLayoutName
    If CStr(CLng(Left$(KeybLayoutName, InStr(1, KeybLayoutName, Chr(0)) - 1))) = 409 Then MsgBox "Текущая раскладка - Английская"
    If CStr(CLng(Left$(KeybLayoutName, InStr(1, KeybLayoutName, Chr(0)) - 1))) = 419 Then MsgBox "Текущая раскладка - Русская"
End Sub

 '28. Скорость повтора ввода символов
'#########################

Const SPI_GETKEYBOARDSPEED = 10

Private Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoA" _
(ByVal uAction As Long, ByVal uParam As Long, lpvParam As Any, ByVal fuWinIni As Long) As Long

Private Sub Form_Load()
    Dim X As Long
    Xx = SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, X, 0)
    MsgBox "Скорость повтора - " & X & " символов!"
End Sub

 '29. Удаление всех файлов из директории
'#########################

Kill ("c:\1\*.*")

 '30. Открыть любой файл/директорию
'#########################
'Под Windos NT

Shell "cmd /X /C start c:\mydoc\example.doc"

'Под Windos 9x:

Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, _
ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long

Private Sub Command1_Click()
    ShellExecute 0, vbNullString, "C:\" & sFile, vbNullString, vbNullString, vbNormalFocus
End Sub

'Или без всяких Апи:

    Shell "start c:\mydoc\example.doc"

 '31. Функция удаляет только папку, не содержающую файлов !
'#########################

Private Declare Function RemoveDirectory Lib "kernel32.dll" Alias "RemoveDirectoryA" (ByVal lpPathName As String) As Long

Private Sub Command1_Click()
    RetVal = RemoveDirectory("D:\ХХХ")
        If RetVal = 1 Then
            MsgBox "Папка была удалена", vbInformation
        Else
            MsgBox "Операция провалилась", vbCritical
        End If
        End
End Sub

 '32. Изменение атрибутов файла
'#########################

'Замените "C:\Scan Port.exe" на полный путь к своему файлу.

SetAttr "C:\Scan Port.exe", vbReadOnly 'Поставить атрибут "Только чтение"
SetAttr "C:\Scan Port.exe", GetAttr("C:\Scan Port.exe") And (Not vbReadOnly) 'Очистить атрибут "Только чтение"
SetAttr "C:\Scan Port.exe", vbArchive 'Поставить атрибут "Архивный"
SetAttr "C:\Scan Port.exe", GetAttr("C:\Scan Port.exe") And (Not vbArchive) 'Очистить атрибут "Архивный"
SetAttr "C:\Scan Port.exe", vbHidden 'Поставить атрибут "Скрытый"
SetAttr "C:\Scan Port.exe", GetAttr("C:\Scan Port.exe") And (Not vbHidden) 'Очистить атрибут "Скрытый"

 '33. Получение полного пути exe-файла из его хэндла
'#########################

Const TH32CS_SNAPPROCESS As Long = 2&
Const MAX_PATH As Long = 260

Private Type PROCESSENTRY32
    dwSize As Long
    cntUsage As Long
    th32ProcessID As Long
    th32DefaultHeapID As Long
    th32ModuleID As Long
    cntThreads As Long
    th32ParentProcessID As Long
    pcPriClassBase As Long
    dwFlags As Long
    szexeFile As String * MAX_PATH
End Type

Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
Private Declare Function CreateToolhelpSnapshot Lib "kernel32" Alias "CreateToolhelp32Snapshot" (ByVal lFlgas As Long, ByVal lProcessID As Long) As Long
Private Declare Function ProcessFirst Lib "kernel32" Alias "Process32First" (ByVal hSnapshot As Long, uProcess As PROCESSENTRY32) As Long
Private Declare Function ProcessNext Lib "kernel32" Alias "Process32Next" (ByVal hSnapshot As Long, uProcess As PROCESSENTRY32) As Long
Private Declare Sub CloseHandle Lib "kernel32" (ByVal hPass As Long)

Private Function GetExeFromHandle(hwnd As Long) As String
    Dim threadID As Long, processID As Long, hSnapshot As Long
    Dim uProcess As PROCESSENTRY32, rProcessFound As Long
    Dim i As Integer, szExename As String
    threadID = GetWindowThreadProcessId(hwnd, processID)
        If threadID = 0 Or processID = 0 Then Exit Function
            hSnapshot = CreateToolhelpSnapshot(TH32CS_SNAPPROCESS, 0&)
            If hSnapshot = -1 Then Exit Function
            uProcess.dwSize = Len(uProcess)
            rProcessFound = ProcessFirst(hSnapshot, uProcess)
                Do While rProcessFound
                    If uProcess.th32ProcessID = processID Then
                        i = InStr(1, uProcess.szexeFile, Chr(0))
                            If i > 0 Then szExename = Left$(uProcess.szexeFile, i - 1)
                                Exit Do
                            Else
                                rProcessFound = ProcessNext(hSnapshot, uProcess)
                            End If
                Loop
    Call CloseHandle(hSnapshot)
    GetExeFromHandle = szExename
End Function

Private Sub Command1_Click()
    MsgBox GetExeFromHandle(Me.hwnd)
End Sub

 '34. Создание директории
'#########################

Sub MakeDir(dirname As String)
    Dim i As Long, path As String
        Do
            i = InStr(i + 1, dirname & "\", "\")
            path = Left$(dirname, i - 1)
                If Right$(path, 1)  ":" And Dir$(path, vbDirectory) = "" Then
                    MkDir path
                End If
        Loop Until i >= Len(dirname)
End Sub

Private Sub Command1_Click()
    Call MakeDir("C:\X\YYY\AAA\BBB\")
End Sub

' '35. 'Сохранение файла из Интернета
''#########################
'
'Private Declare Function URLDownloadToFile Lib "urlmon" Alias "URLDownloadToFileA" (ByVal pCaller As Long, ByVal szURL As String, ByVal szFileName As String, ByVal dwReserved As Long, ByVal lpfnCB As Long) As Long
'Public Event ErrorDownload (FromPathName As String, ToPathName As String)
'Public Event DownloadComplete(FromPathName As String, ToPathName As String)
'
'Public Function DownloadFile(FromPathName As String, ToPathName As String)
'    If URLDownloadToFile(0, FromPathName, ToPathName, 0, 0) = 0 Then
'        DownloadFile = True
'        RaiseEvent DownloadComplete(FromPathName, ToPathName)
'    Else
'        DownloadFile = False
'        RaiseEvent ErrorDownload(FromPathName, ToPathName)
'    End If
'End Function
'
'Private Sub Command1_Click()
'Call DownloadFile("http://visual-basic.nm.ru/Banner.gif", "c:\Banner.gif")
'End Sub

 '36. Получить имя компьютера и имя пользователя
'#########################

Private Declare Function GetComputerNameA Lib "kernel32" (ByVal lpBuffer As String, nSize As Long) As Long
Private Declare Function WNetGetUserA Lib "mpr.dll" (ByVal lpName As String, ByVal lpUsername As String, lpnLength As Long) As Long

Function GetComputerName() As String
    Dim sBuffer As String * 255
        If GetComputerNameA(sBuffer, 255&)  0 Then
            GetComputerName = Left$(sBuffer, InStr(sBuffer, vbNullChar) - 1)
        End If
End Function

Function GetUserName() As String
    Dim sUserNameBuff As String * 255
    sUserNameBuff = Space(255)
    Call WNetGetUserA(vbNullString, sUserNameBuff, 255&)
    GetUserName = Left$(sUserNameBuff, InStr(sUserNameBuff, vbNullChar) - 1)
End Function

 '37. Изменить разрешение экрана
'#########################

'Ваш монитор должен поддерживать задаваемое разрешение !

Private Declare Function ChangeDisplaySettings Lib "user32" Alias _
"ChangeDisplaySettingsA" (lpDevMode As Any, ByVal dwFlags As Long) As Long
Private Declare Function EnumDisplaySettings Lib "user32" Alias _
"EnumDisplaySettingsA" (ByVal lpszDeviceName As Long, ByVal iModeNum As _
Long, lpDevMode As Any) As Boolean

Const DM_PELSWIDTH = &H80000
Const DM_PELSHEIGHT = &H100000
Const CCFORMNAME = 32
Const CCDEVICENAME = 32

Private Type DEVMODE
    dmDeviceName As String * CCDEVICENAME
    dmSpecVersion As Integer
    dmDriverVersion As Integer
    dmSize As Integer
    dmDriverExtra As Integer
    dmFields As Long
    dmOrientation As Integer
    dmPaperSize As Integer
    dmPaperLength As Integer
    dmPaperWidth As Integer
    dmScale As Integer
    dmCopies As Integer
    dmDefaultSource As Integer
    dmPrintQuality As Integer
    dmColor As Integer
    dmDuplex As Integer
    dmYResolution As Integer
    dmTTOption As Integer
    dmCollate As Integer
    dmFormName As String * CCFORMNAME
    dmUnusedPadding As Integer
    dmBitsPerPel As Integer
    dmPelsWidth As Long
    dmPelsHeight As Long
    dmDisplayFlags As Long
    dmDisplayFrequency As Long
End Type

Private Sub ChangeResolution(iWidth As Single, iHeight As Single)
    Dim DevM As DEVMODE
    Dim A As Boolean
    Dim i As Long
    Dim b As Long
    i = 0
        Do
            A = EnumDisplaySettings(0&, i&, DevM)
            i = i + 1
        Loop Until (A = False)
    DevM.dmFields = DM_PELSWIDTH Or DM_PELSHEIGHT
    DevM.dmPelsWidth = iWidth
    DevM.dmPelsHeight = iHeight
    b = ChangeDisplaySettings(DevM, 0)
End Sub

Private Sub Command1_Click()
    ChangeResolution 640, 480
End Sub

 '38. Получить IP адрес
'#########################

'Вставьте следующий код в событие формы

Private Sub Form_Load()
    MsgBox "IP Host Name: " & GetIPHostName()
    MsgBox "IP Address: " & GetIPAddress()
End Sub

'Добавьте модуль в проект

Public Const MAX_WSADescription = 256
Public Const MAX_WSASYSStatus = 128
Public Const ERROR_SUCCESS As Long = 0
Public Const WS_VERSION_REQD As Long = &H101
Public Const WS_VERSION_MAJOR As Long = WS_VERSION_REQD \ &H100 And &HFF&
Public Const WS_VERSION_MINOR As Long = WS_VERSION_REQD And &HFF&
Public Const MIN_SOCKETS_REQD As Long = 1
Public Const SOCKET_ERROR As Long = -1

Public Type HOSTENT
    hName As Long
    hAliases As Long
    hAddrType As Integer
    hLen As Integer
    hAddrList As Long
End Type

Public Type WSAData
    wVersion As Integer
    wHighVersion As Integer
    szDescription(0 To MAX_WSADescription) As Byte
    szSystemStatus(0 To MAX_WSASYSStatus) As Byte
    wMaxSockets As Integer
    wMaxUDPDG As Integer
    dwVendorInfo As Long
End Type

Public Declare Function WSAGetLastError Lib "wsock32.dll" () As Long

Public Declare Function WSAStartup Lib "wsock32.dll" (ByVal _
wVersionRequired As Long, lpWSADATA As WSAData) As Long

Public Declare Function WSACleanUp Lib "wsock32.dll" Alias "WSACleanup" () As Long

Public Declare Function GetHostName Lib "wsock32.dll" Alias "gethostname" (ByVal _
szHost As String, ByVal dwHostLen As Long) As Long

Public Declare Function gethostbyname Lib "wsock32.dll" (ByVal szHost As _
String) As Long

Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
(hpvDest As Any, ByVal hpvSource As Long, ByVal cbCopy As Long)

Public Function GetIPAddress() As String
    Dim sHostName As String * 256
    Dim lpHost As Long
    Dim Host As HOSTENT
    Dim dwIPAddr As Long
    Dim tmpIPAddr() As Byte
    Dim i As Integer
    Dim sIPAddr As String
        If Not SocketsInitialize() Then
            GetIPAddress = ""
            Exit Function
        End If

    If GetHostName(sHostName, 256) = SOCKET_ERROR Then
        GetIPAddress = ""
        MsgBox "Windows Sockets error " & Str$(WSAGetLastError()) & " has occurred. Unable to successfully get Host Name."
        SocketsCleanup
        Exit Function
    End If

    sHostName = Trim$(sHostName)
    lpHost = gethostbyname(sHostName)
        If lpHost = 0 Then
            GetIPAddress = ""
            MsgBox "Windows Sockets are not responding. " & "Unable to successfully get Host Name."
            SocketsCleanup
            Exit Function
        End If

    CopyMemory Host, lpHost, Len(Host)
    CopyMemory dwIPAddr, Host.hAddrList, 4
    ReDim tmpIPAddr(1 To Host.hLen)
    CopyMemory tmpIPAddr(1), dwIPAddr, Host.hLen

    For i = 1 To Host.hLen
        sIPAddr = sIPAddr & tmpIPAddr(i) & "."
    Next
        GetIPAddress = Mid$(sIPAddr, 1, Len(sIPAddr) - 1)
        SocketsCleanup
End Function

Public Function GetIPHostName() As String
    Dim sHostName As String * 256
        If Not SocketsInitialize() Then
            GetIPHostName = ""
            Exit Function
        End If
            If GetHostName(sHostName, 256) = SOCKET_ERROR Then
                GetIPHostName = ""
                MsgBox "Windows Sockets error " & Str$(WSAGetLastError()) & " has occurred. Unable to successfully get Host Name."
                SocketsCleanup
                Exit Function
            End If
        GetIPHostName = Left$(sHostName, InStr(sHostName, Chr(0)) - 1)
        SocketsCleanup
End Function

Public Function HiByte(ByVal wParam As Integer)
    HiByte = wParam \ &H100 And &HFF&
End Function

Public Function LoByte(ByVal wParam As Integer)
    LoByte = wParam And &HFF&
End Function

Public Sub SocketsCleanup()
    If WSACleanUp()  ERROR_SUCCESS Then
        MsgBox "Socket error occurred in Cleanup."
    End If
End Sub

Public Function SocketsInitialize() As Boolean
    Dim WSAD As WSAData
    Dim sLoByte As String
    Dim sHiByte As String
        If WSAStartup(WS_VERSION_REQD, WSAD)  ERROR_SUCCESS Then
            MsgBox "The 32-bit Windows Socket is not responding."
            SocketsInitialize = False
            Exit Function
        End If

    If WSAD.wMaxSockets < MIN_SOCKETS_REQD Then
        MsgBox "This application requires a minimum of " & CStr(MIN_SOCKETS_REQD) & " supported sockets."
        SocketsInitialize = False
        Exit Function
    End If

    If LoByte(WSAD.wVersion) < WS_VERSION_MAJOR Or (LoByte(WSAD.wVersion) = WS_VERSION_MAJOR And HiByte(WSAD.wVersion) < WS_VERSION_MINOR) Then
        sHiByte = CStr(HiByte(WSAD.wVersion))
        sLoByte = CStr(LoByte(WSAD.wVersion))
        MsgBox "Sockets version " & sLoByte & "." & sHiByte & " is not supported by 32-bit Windows Sockets."
        SocketsInitialize = False
        Exit Function
    End If
    SocketsInitialize = True
End Function

 '39. Определение имени или IP-адреса удаленного компьютера
'#########################

'Добавьте модуль, и CommandButton.
'КОД ФОРМЫ

Private Sub Command1_Click()
    'Вначале вы должны инициализировать winsock
    WinsockInit
    'Определение имени машины, зная ее IP-адрес
    MsgBox HostByAddress("192.168.1.1")
    MsgBox HostByAddress("192.168.1.2")
    'Определение IP-адреса машины, зная ее имя
    MsgBox HostByName("GARIK")
    MsgBox HostByName("OKSANA")
    'В конце работы вы должны использовать функцию WSACleanUp
    WSACleanUp
End Sub

'КОД МОДУЛЯ

Option Explicit
Public Const SOCKET_ERROR = -1
Public Const AF_INET = 2
Public Const PF_INET = AF_INET
Public Const MAXGETHOSTSTRUCT = 1024
Public Const SOCK_STREAM = 1
Public Const MSG_PEEK = 2

Private Type SockAddr
    sin_family As Integer
    sin_port As Integer
    sin_addr As String * 4
    sin_zero As String * 8
End Type

Private Type T_WSA
    wVersion As Integer
    wHighVersion As Integer
    szDescription(0 To 255) As Byte
    szSystemStatus(0 To 128) As Byte
    iMaxSockets As Integer
    iMaxUdpDg As Integer
    lpVendorInfo As Long
End Type

Dim WSAData As T_WSA

Type Inet_Address
    Byte4 As String * 1
    Byte3 As String * 1
    Byte2 As String * 1
    Byte1 As String * 1
End Type

Public IPStruct As Inet_Address

Public Type T_Host
    h_name As Long
    h_aliases As Long
    h_addrtype As Integer
    h_length As Integer
    h_addr_list As Long
End Type

Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (Dest As _
Any, Src As Any, ByVal cb&)

Declare Function gethostbyaddr Lib "wsock32.dll" (addr As Long, ByVal _
addr_len As Long, ByVal addr_type As Long) As Long

Declare Function inet_addr Lib "wsock32.dll" (ByVal addr As String) As _
Long

Declare Function gethostbyname Lib "wsock32.dll" _
(ByVal HostName As String) As Long

Declare Function GetHostName Lib "wsock32.dll" Alias "gethostname" (ByVal _
HostName As String, HostLen As Long) As Long

Declare Function WSAStartup Lib "wsock32.dll" (ByVal A As Long, b As _
T_WSA) As Long

Declare Function WSACleanUp Lib "wsock32.dll" Alias "WSACleanup" () As _
Integer

Function HostByName(sHost As String) As String
    Dim s As String
    Dim p As Long
    Dim Host As T_Host
    Dim ListAddress As Long
    Dim ListAddr As Long
    Dim Address As Long
    s = String(64, 0)
    sHost = sHost + Right(s, 64 - Len(sHost))
    p = gethostbyname(sHost)
        If p = SOCKET_ERROR Then
            Exit Function
        Else
            If p  0 Then
                CopyMemory Host.h_name, ByVal p, Len(Host)
                ListAddress = Host.h_addr_list
                CopyMemory ListAddr, ByVal ListAddress, 4
                CopyMemory Address, ByVal ListAddr, 4
                HostByName = InetAddrLongToString(Address)
            Else
                HostByName = "No DNS Entry"
            End If
        End If

End Function

Private Function InetAddrLongToString(Address As Long) As String
    CopyMemory IPStruct, Address, 4
    InetAddrLongToString = CStr(Asc(IPStruct.Byte4)) + "." + _
    CStr(Asc(IPStruct.Byte3)) + "." + CStr(Asc(IPStruct.Byte2)) + "." + _
    CStr(Asc(IPStruct.Byte1))
End Function

Function HostByAddress(ByVal sAddress As String) As String
    Dim lAddress As Long
    Dim p As Long
    Dim HostName As String
    Dim Host As T_Host
    lAddress = inet_addr(sAddress)
    p = gethostbyaddr(lAddress, 4, PF_INET)
        If p  0 Then
            CopyMemory Host, ByVal p, Len(Host)
            HostName = String(256, 0)
            CopyMemory ByVal HostName, ByVal Host.h_name, 256
                If HostName = "" Then HostByAddress = "Unable to Resolve Address"
                    HostByAddress = Left(HostName, InStr(HostName, Chr(0)) - 1)
                Else
                    HostByAddress = "No DNS Entry"
                End If
End Function

Public Sub WinsockInit()
    WSAStartup &H101, WSAData
End Sub

 '40. Программно отсоединиться от Интернета
'#########################

'Добавьте на форму CommandButton

Const RAS_MAXENTRYNAME As Integer = 256
Const RAS_MAXDEVICETYPE As Integer = 16
Const RAS_MAXDEVICENAME As Integer = 128
Const RAS_RASCONNSIZE As Integer = 412
Const ERROR_SUCCESS = 0&

Private Type RasEntryName
    dwSize As Long
    szEntryName(RAS_MAXENTRYNAME) As Byte
End Type

Private Type RasConn
    dwSize As Long
    hRasConn As Long
    szEntryName(RAS_MAXENTRYNAME) As Byte
    szDeviceType(RAS_MAXDEVICETYPE) As Byte
    szDeviceName(RAS_MAXDEVICENAME) As Byte
End Type

Private Declare Function RasEnumConnections Lib "RasApi32.dll" Alias _
"RasEnumConnectionsA" (lpRasConn As Any, lpcb As Long, lpcConnections As Long) As Long

Private Declare Function RasHangUp Lib "RasApi32.dll" Alias "RasHangUpA" _
(ByVal hRasConn As Long) As Long

Private gstrISPName As String
Public ReturnCode As Long

Public Sub HangUp()
    Dim i As Long
    Dim lpRasConn(255) As RasConn
    Dim lpcb As Long
    Dim lpcConnections As Long
    Dim hRasConn As Long
    lpRasConn(0).dwSize = RAS_RASCONNSIZE
    lpcb = RAS_MAXENTRYNAME * lpRasConn(0).dwSize
    lpcConnections = 0
    ReturnCode = RasEnumConnections(lpRasConn(0), lpcb, lpcConnections)
        If ReturnCode = ERROR_SUCCESS Then
            For i = 0 To lpcConnections - 1
                If Trim(ByteToString(lpRasConn(i).szEntryName)) = Trim(gstrISPName) Then
                    hRasConn = lpRasConn(i).hRasConn
                    ReturnCode = RasHangUp(ByVal hRasConn)
                End If
            Next i
        End If
End Sub

Public Function ByteToString(bytString() As Byte) As String
    Dim i As Integer
    ByteToString = ""
    i = 0
        While bytString(i) = 0&
            ByteToString = ByteToString & Chr(bytString(i))
            i = i + 1
        Wend
End Function

Private Sub Command1_Click()
    Call HangUp
End Sub

 '41. Узнать есть ли активное соединение с Интернетом
'#########################

Private Declare Function RasEnumConnections Lib "RasApi32.dll" Alias _
"RasEnumConnectionsA" (lpRasCon As Any, lpcb As Long, lpcConnections As Long) As Long

Private Declare Function RasGetConnectStatus Lib "RasApi32.dll" Alias _
"RasGetConnectStatusA" (ByVal hRasCon As Long, lpStatus As Any) As Long

Private Const RAS95_MaxEntryName = 256
Private Const RAS95_MaxDeviceType = 16
Private Const RAS95_MaxDeviceName = 32

Private Type RASCONN95
    dwSize As Long
    hRasCon As Long
    szEntryName(RAS95_MaxEntryName) As Byte
    szDeviceType(RAS95_MaxDeviceType) As Byte
    szDeviceName(RAS95_MaxDeviceName) As Byte
End Type

Private Type RASCONNSTATUS95
    dwSize As Long
    RasConnState As Long
    dwError As Long
    szDeviceType(RAS95_MaxDeviceType) As Byte
    szDeviceName(RAS95_MaxDeviceName) As Byte
End Type

Public Function IsConnected() As Boolean
    Dim TRasCon(255) As RASCONN95
    Dim lg As Long
    Dim lpcon As Long
    Dim RetVal As Long
    Dim Tstatus As RASCONNSTATUS95
    TRasCon(0).dwSize = 412
    lg = 256 * TRasCon(0).dwSize
    RetVal = RasEnumConnections(TRasCon(0), lg, lpcon)
    Tstatus.dwSize = 160
    RetVal = RasGetConnectStatus(TRasCon(0).hRasCon, Tstatus)
        If Tstatus.RasConnState = &H2000 Then
            IsConnected = True
        Else
            IsConnected = False
        End If
End Function

Private Sub Form_Load()
'если есть соединение, то IsConnected() = True, иначе False
    MsgBox IsConnected()
End Sub

 '42. Вызвать окно "Установка связи с Интернетом"
'#########################

Private Sub Form_Load()
    ult = Shell("rundll32.exe rnaui.DLL,RnaDial", 1)
End Sub

 '43. Симулировать нажатия определенных клавиш
'#########################

Private Declare Sub keybd_event Lib "user32" _
(ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)

'bVk - Виртуальный код клавиши для имитации нажатия и отпускания клавиши.
'bScan - Зарезервировано -- установлено в 0.
'dwFlags - Комбинация следующих флагов определяет различные способы имитации:
'KEYEVENTF_EXTENDEDKEY - Префикс скэн-кода с префиксным байтом, имеющим значение &HE0.
'KEYEVENTF_KEYUP - Клавиша, указанная в bVk будет отпущена. Если этот флажок не определен, клавиша будет нажата.
'dwExtraInfo - Дополнительное 32-разрядное значение, связанное с событием клавиатуры.

Const KEYEVENTF_KEYUP = &H2 'событие отпускания клавиши
Const VK_CONTROL = &H11 'клавиша Ctrl
Const VK_ESCAPE = &H1B 'клавиша Escape

'Эмулирующая нажатие кнопки ПУСК

Private Sub ShowStartMenu()
'Функция эмулирует нажатие Ctrl + Esc
    Call keybd_event(VK_CONTROL, 0, 0, 0) 'Hажимаем Ctrl
    Call keybd_event(VK_ESCAPE, 0, 0, 0) 'Hажимаем Esc
    Call keybd_event(VK_ESCAPE, 0, KEYEVENTF_KEYUP, 0) 'Отпускаем Esc
    Call keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0) 'Отпускаем Ctrl
End Sub

Private Sub Command1_Click()
    ShowStartMenu
End Sub

'эмуляция нажатия клавиши Alt
Call keybd_event(VK_ADD, 0, 0, 0)
Call keybd_event(VK_ADD, 0, KEYEVENTF_KEYUP, 0)
'эмуляция нажатия левой кнопки с логотипом Windows
Call keybd_event(VK_LWIN, 0, 0, 0)
Call keybd_event(VK_LWIN, 0, KEYEVENTF_KEYUP, 0)
'Запустить проводник
Call keybd_event(VK_LWIN, 0, 0, 0)
Call keybd_event(69, 0, 0, 0)
Call keybd_event(VK_LWIN, 0, KEYEVENTF_KEYUP, 0)
'поиск файла
'Call keybd_event(VK_LWIN, 0, 0, 0)
'Call keybd_event(70, 0, 0, 0)
'Call keybd_event(VK_LWIN, 0, KEYEVENTF_KEYUP, 0)

Private Const VK_ADD = &H6B
Private Const VK_ATTN = &HF6
Private Const VK_BACK = &H8
Private Const VK_CANCEL = &H3
Private Const VK_CAPITAL = &H14
Private Const VK_CLEAR = &HC
Private Const VK_CONTROL = &H11
Private Const VK_CRSEL = &HF7
Private Const VK_DECIMAL = &H6E
Private Const VK_DELETE = &H2E
Private Const VK_DIVIDE = &H6F
Private Const VK_DOWN = &H28
Private Const VK_END = &H23
Private Const VK_EREOF = &HF9
Private Const VK_ESCAPE = &H1B
Private Const VK_EXECUTE = &H2B
Private Const VK_EXSEL = &HF8
Private Const VK_F1 = &H70
Private Const VK_F10 = &H79
Private Const VK_F11 = &H7A
Private Const VK_F12 = &H7B
Private Const VK_F13 = &H7C
Private Const VK_F14 = &H7D
Private Const VK_F15 = &H7E
Private Const VK_F16 = &H7F
Private Const VK_F17 = &H80
Private Const VK_F18 = &H81
Private Const VK_F19 = &H82
Private Const VK_F2 = &H71
Private Const VK_F20 = &H83
Private Const VK_F21 = &H84
Private Const VK_F22 = &H85
Private Const VK_F23 = &H86
Private Const VK_F24 = &H87
Private Const VK_F3 = &H72
Private Const VK_F4 = &H73
Private Const VK_F5 = &H74
Private Const VK_F6 = &H75
Private Const VK_F7 = &H76
Private Const VK_F8 = &H77
Private Const VK_F9 = &H78
Private Const VK_HELP = &H2F
Private Const VK_HOME = &H24
Private Const VK_INSERT = &H2D
Private Const VK_LBUTTON = &H1
Private Const VK_LCONTROL = &HA2
Private Const VK_LEFT = &H25
Private Const VK_LMENU = &HA4
Private Const VK_LSHIFT = &HA0
Private Const VK_MBUTTON = &H4
Private Const VK_MENU = &H12
Private Const VK_MULTIPLY = &H6A
Private Const VK_NEXT = &H22
Private Const VK_NONAME = &HFC
Private Const VK_NUMLOCK = &H90
Private Const VK_NUMPAD0 = &H60
Private Const VK_NUMPAD1 = &H61
Private Const VK_NUMPAD2 = &H62
Private Const VK_NUMPAD3 = &H63
Private Const VK_NUMPAD4 = &H64
Private Const VK_NUMPAD5 = &H65
Private Const VK_NUMPAD6 = &H66
Private Const VK_NUMPAD7 = &H67
Private Const VK_NUMPAD8 = &H68
Private Const VK_NUMPAD9 = &H69
Private Const VK_OEM_CLEAR = &HFE
Private Const VK_PA1 = &HFD
Private Const VK_PAUSE = &H13
Private Const VK_PLAY = &HFA
Private Const VK_PRINT = &H2A
Private Const VK_PRIOR = &H21
Private Const VK_PROCESSKEY = &HE5
Private Const VK_RBUTTON = &H2
Private Const VK_RCONTROL = &HA3
Private Const VK_RETURN = &HD
Private Const VK_RIGHT = &H27
Private Const VK_RMENU = &HA5
Private Const VK_RSHIFT = &HA1
Private Const VK_SCROLL = &H91
Private Const VK_SELECT = &H29
Private Const VK_SEPARATOR = &H6C
Private Const VK_SHIFT = &H10
Private Const VK_SNAPSHOT = &H2C
Private Const VK_SPACE = &H20
Private Const VK_SUBTRACT = &H6D
Private Const VK_TAB = &H9
Private Const VK_UP = &H26
Private Const VK_ZOOM = &HFB

 '44. Подключение, отключение сетевого диска
'#########################
'Добавьте дополнительный модуль, и 2 элемента CommandButton.

'КОД ФОРМЫ

Private Sub Command1_Click()
    Call Module1.Connect("Sany\c$", "K:", "defaultsharename", "garik")
        If (Module1.rc  0) And (Module1.rc  85) Then
            MsgBox Module1.ErrorMsg
        End If
End Sub

Private Sub Command2_Click()
    Call Module1.DisConnect("K:", True)
        If (Module1.rc  0) And (Module1.rc  85) Then
            MsgBox Module1.ErrorMsg
        End If
End Sub

'КОД МОДУЛЯ

Option Explicit
Public Declare Function WNetAddConnection2 Lib "mpr.dll" Alias "WNetAddConnection2A" (lpNetResource As NETRESOURCE, ByVal lpPassword As String, ByVal lpUsername As String, ByVal dwFlags As Long) As Long
Public Declare Function WNetCancelConnection2 Lib "mpr.dll" Alias "WNetCancelConnection2A" (ByVal lpName As String, ByVal dwFlags As Long, ByVal fForce As Long) As Long

Public ErrorNum As Long
Public ErrorMsg As String
Public rc As Long
Public RemoteName As String
Public Const ERROR_BAD_DEV_TYPE = 66&
Public Const ERROR_ALREADY_ASSIGNED = 85&
Public Const ERROR_ACCESS_DENIED = 5&
Public Const ERROR_BAD_NET_NAME = 67&
Public Const ERROR_BAD_PROFILE = 1206&
Public Const ERROR_BAD_PROVIDER = 1204&
Public Const ERROR_BUSY = 170&
Public Const ERROR_CANCEL_VIOLATION = 173&
Public Const ERROR_CANNOT_OPEN_PROFILE = 1205&
Public Const ERROR_DEVICE_ALREADY_REMEMBERED = 1202&
Public Const ERROR_EXTENDED_ERROR = 1208&
Public Const ERROR_INVALID_PASSWORD = 86&
Public Const ERROR_NO_NET_OR_BAD_PATH = 1203&
Public Const ERROR_NO_NETWORK = 1222&
Public Const ERROR_NO_CONNECTION = 8
Public Const ERROR_NO_DISCONNECT = 9
Public Const ERROR_DEVICE_IN_USE = 2404&
Public Const ERROR_NOT_CONNECTED = 2250&
Public Const ERROR_OPEN_FILES = 2401&
Public Const ERROR_MORE_DATA = 234
Public Const CONNECT_UPDATE_PROFILE = &H1
Public Const RESOURCETYPE_DISK = &H1

Public Type NETRESOURCE
    dwScope As Long
    dwType As Long
    dwDisplayType As Long
    dwUsage As Long
    lpLocalName As String
    lpRemoteName As String
    lpComment As String
    lpProvider As String
End Type

Public lpNetResourse As NETRESOURCE

Public Sub Connect(ByVal HostName As String, ByVal RemoteName As String, ByVal Username As String, ByVal Password As String)
    Dim lpUsername As String
    Dim lpPassword As String
    On Error GoTo Err_Connect
    ErrorNum = 0
    ErrorMsg = ""
    lpNetResourse.dwType = RESOURCETYPE_DISK
    lpNetResourse.lpLocalName = RemoteName & Chr(0)
    'Drive Letter to use
    lpNetResourse.lpRemoteName = "\\" & HostName & Chr(0)
    'Network Path to share
    lpNetResourse.lpProvider = Chr(0)
    lpPassword = Password & Chr(0)
    'password on share pass "" if none
    lpUsername = Username & Chr(0)
    'username to connect as if applicable
    rc = WNetAddConnection2(lpNetResourse, lpPassword, lpUsername, CONNECT_UPDATE_PROFILE)
    If rc  0 Then GoTo Err_Connect
    Exit Sub
Err_Connect:
    ErrorNum = rc
    ErrorMsg = WnetError(rc)
End Sub

Public Sub DisConnect(ByVal name As String, ByVal ForceOff As Boolean)
    On Error GoTo Err_DisConnect
    ErrorNum = 0
    ErrorMsg = ""
    rc = WNetCancelConnection2(name & Chr(0), CONNECT_UPDATE_PROFILE, ForceOff)
    If rc  0 Then GoTo Err_DisConnect
    Exit Sub
Err_DisConnect:
    ErrorNum = rc
    ErrorMsg = WnetError(rc)
End Sub

Private Function WnetError(Errcode As Long) As String
    Select Case Errcode
        Case ERROR_BAD_DEV_TYPE
            WnetError = "Bad device."
        Case ERROR_ALREADY_ASSIGNED
            WnetError = "Already Assigned."
        Case ERROR_ACCESS_DENIED
            WnetError = "Access Denied."
        Case ERROR_BAD_NET_NAME
            WnetError = "Bad net name"
        Case ERROR_BAD_PROFILE
            WnetError = "Bad Profile"
        Case ERROR_BAD_PROVIDER
            WnetError = "Bad Provider"
        Case ERROR_BUSY
            WnetError = "Busy"
        Case ERROR_CANCEL_VIOLATION
            WnetError = "Cancel Violation"
        Case ERROR_CANNOT_OPEN_PROFILE
            WnetError = "Cannot Open Profile"
        Case ERROR_DEVICE_ALREADY_REMEMBERED
            WnetError = "Device already remembered"
        Case ERROR_EXTENDED_ERROR
            WnetError = "Device already remembered"
        Case ERROR_INVALID_PASSWORD
            WnetError = "Invalid Password"
        Case ERROR_NO_NET_OR_BAD_PATH
            WnetError = "Could not find the specified device"
        Case ERROR_NO_NETWORK
            WnetError = "No Network Present"
        Case ERROR_DEVICE_IN_USE
            WnetError = "Connection Currently in use "
        Case ERROR_NOT_CONNECTED
            WnetError = "No Connection Present"
        Case ERROR_OPEN_FILES
            WnetError = "Files open and the force parameter is false"
        Case ERROR_MORE_DATA
            WnetError = "Buffer to small to hold network name, make lpnLength bigger"
        Case Else:
            WnetError = "Unrecognized Error " + Str(Errcode) + "."
    End Select
End Function

 '45. Установление анимированного курсора
'#########################

Private Declare Function LoadCursorFromFile Lib "user32" Alias "LoadCursorFromFileA" (ByVal lpFileName As String) As Long
Private Declare Function SetClassLong Lib "user32" Alias "SetClassLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long

Const GCL_HCURSOR = (-12)
Dim sCursorFile As String
Dim hCursor As Long
Dim hOldCursor As Long
Dim lReturn As Long

Private Sub Command1_Click()
    hCursor = LoadCursorFromFile(sCursorFile)
    hOldCursor = SetClassLong(Form1.hwnd, GCL_HCURSOR, hCursor)
End Sub

Private Sub Command2_Click()
    lReturn = SetClassLong(Form1.hwnd, GCL_HCURSOR, hOldCursor)
End Sub

Private Sub Form_Load()
'не забудьте указать свой путь к анимированному курсору
    sCursorFile = "C:\WIN\CURSORS\GLOBE.ANI"
End Sub

 '46. Загрузка разных курсоров
'#########################

' Константы из API интерфейса
Const IDC_ARROW = 32512& 'Стрелка
Const IDC_IBEAM = 32513& 'Тип - I
Const IDC_WAIT = 32514& 'Часы
Const IDC_CROSS = 32515& 'Перекрестие
Const IDC_UPARROW = 32516& 'Верх
Const IDC_SIZE = 32640& 'Размер
Const IDC_ICON = 32641&
Const IDC_SIZENWSE = 32642& 'Стрелки размеров
Const IDC_SIZENESW = 32643&
Const IDC_SIZEWE = 32644&
Const IDC_SIZENS = 32645&
Const IDC_SIZEALL = 32646&
Const IDC_NO = 32648& 'Стоп курсор
Const IDC_APPSTARTING = 32650& 'Стрелка и часы
Const IDC_HAND = 32649&

' Загружает курсор из ресурса
Private Declare Function apiLoadCursorBynum Lib "user32" Alias "LoadCursorA" _
     (ByVal hInstance As Long, _
     ByVal lpCursorName As Long) _
     As Long

' Устанавливает курсор
Private Declare Function apiSetCursor Lib "user32" Alias "SetCursor" _
     (ByVal hCursor As Long) _
     As Long

' Загружает курсор из файла
Private Declare Function apiLoadCursorFromFile Lib "user32" Alias "LoadCursorFromFileA" _
     (ByVal lpFileName As String) _
     As Long

'Указатель на курсор
Dim hCursor As Long

'    Загружаем курсор
Private Sub Объекты_AfterUpdate()
     On Error GoTo 999
     Select Case Me.Объекты
         Case 1: 'Указатель
             hCursor = apiLoadCursorBynum(0, IDC_ARROW)
         Case 2: 'Редактор
             hCursor = apiLoadCursorBynum(0, IDC_IBEAM)
         Case 3: 'Часы
             hCursor = apiLoadCursorBynum(0, IDC_WAIT)
         Case 4 'Перекрестие
             hCursor = apiLoadCursorBynum(0, IDC_CROSS)
         Case 5: 'Стрелка вверх
             hCursor = apiLoadCursorBynum(0, IDC_UPARROW)
         Case 6: 'Размер
             hCursor = apiLoadCursorBynum(0, IDC_SIZE)
         Case 7: 'Иконка
             hCursor = apiLoadCursorBynum(0, IDC_ICON)
         Case 8: 'Стрелка
             hCursor = apiLoadCursorBynum(0, IDC_SIZENWSE)
         Case 9 'Стрелка
             hCursor = apiLoadCursorBynum(0, IDC_SIZENESW)
         Case 10 'Стрелка
             hCursor = apiLoadCursorBynum(0, IDC_SIZEWE)
         Case 11 'Стрелка
             hCursor = apiLoadCursorBynum(0, IDC_SIZENS)
         Case 12 'Стрелка
             hCursor = apiLoadCursorBynum(0, IDC_SIZEALL)
         Case 13 'Стоп курсор
             hCursor = apiLoadCursorBynum(0, IDC_NO)
         Case 14 'Старт приложения
             hCursor = apiLoadCursorBynum(0, IDC_APPSTARTING)
         Case 15 'Загрузить из файла
             hCursor = apiLoadCursorFromFile( _
             Application.CurrentProject.path & _
             "\la_api.cur")
         Case 16 'Рука курсор
             hCursor = apiLoadCursorBynum(0, IDC_HAND)
     End Select
     Exit Sub
999:
     MsgBox Err.Description  'Ошибка
     Err.Clear
End Sub

'  Изменяем курсор
Private Sub Пример_01_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
    Call apiSetCursor(hCursor)
End Sub

 '47. Отображение/скрытие окна приложения
'#########################

' Константы отображения
Private Const SW_HIDE = 0
Private Const SW_SHOWNORMAL = 1
Private Const SW_NORMAL = 1
Private Const SW_SHOWMINIMIZED = 2
Private Const SW_SHOWMAXIMIZED = 3
Private Const SW_MAXIMIZE = 3
Private Const SW_SHOWNOACTIVATE = 4
Private Const SW_SHOW = 5
Private Const SW_MINIMIZE = 6
Private Const SW_SHOWMINNOACTIVE = 7
Private Const SW_SHOWNA = 8
Private Const SW_RESTORE = 9
Private Const SW_SHOWDEFAULT = 10
Private Const SW_MAX = 10

' Функция управляет отображением окна
Private Declare Function apiShowWindow Lib "user32" Alias "ShowWindow" _
     (ByVal hwnd As Long, _
      ByVal nCmdShow As Long) As Long

' Команды в котором создаются приложения
Dim appAcc As Access.Application

'  Отобразить окно
Private Sub butON_Click()
Dim s As String
     On Error Resume Next
     ' Выход из приложения
     Form_Close
     
     ' Открываем окно
     Set appAcc = New Access.Application
     s = Application.CurrentProject.path & "\" & "la_form.mdb"
     appAcc.OpenCurrentDatabase (s)
     appAcc.Visible = True
     apiShowWindow appAcc.hWndAccessApp, Me.grShow
End Sub

'  Окно базы данных
Private Sub butWinDataBase_Click()
     DoCmd.SelectObject acForm, "Пример 05", True
     If Me.butWinDataBase = False Then
         DoCmd.RunCommand acCmdWindowHide
     End If
     DoCmd.SelectObject acForm, "Пример 05", False
End Sub

' Выход из системы
Private Sub Form_Close()
     On Error Resume Next
     appAcc.Quit acQuitSaveNone
     Err.Clear
End Sub

 '48. Общая информация о Windows
'#########################

' Структура с информацией о версии Windows
Private Type OSVERSIONINFO
         dwOSVersionInfoSize As Long
         dwMajorVersion As Long
         dwMinorVersion As Long
         dwBuildNumber As Long
         dwPlatformId As Long
         szCSDVersion As String * 128
End Type

' Api константы платформы Windows
Const VER_PLATFORM_WIN32s = 0
Const VER_PLATFORM_WIN32_WINDOWS = 1
Const VER_PLATFORM_WIN32_NT = 2

' Получаем информацию о версии
Private Declare Function apiGetVersionEx Lib "kernel32" Alias "GetVersionExA" _
     (lpVersionInformation As OSVERSIONINFO) As Long

'  Загрузка данных
Private Sub Form_Load()
Dim myVer As OSVERSIONINFO
Dim s As String

         ' Инициализируем строку
         s = ""
         ' Определяем размер структуры
         myVer.dwOSVersionInfoSize = 148
         
         ' Получаем информацию о версии
         Call apiGetVersionEx(myVer)
         If myVer.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS Then
             s = s & "Платформа: Windows 95;"
         ElseIf myVer.dwPlatformId = VER_PLATFORM_WIN32_NT Then
             s = s & "Платформа: Windows NT;"
         End If
         s = s & "Версия: " & myVer.dwMajorVersion & "." & myVer.dwMinorVersion & ";"
         s = s & "Построение: " & (myVer.dwBuildNumber And &HFFFF&) & ";"
         
         ' Устанавливаем список
         Me.myList.RowSource = s
End Sub

 '50. Использование функции timeGetTime
'#########################

' Функция времени в миллисекундах с момента запуска Windows
Private Declare Function apiTimeGetTime Lib "winmm.dll" Alias "timeGetTime" () As Long
Dim T0 As Long, T1 As Long

Private Sub Form_Open(Cancel As Integer)
     ' Устанавливаем начальное значение
     T0 = apiTimeGetTime()
     ' Определяем список
     Me.myList.RowSource = Me.myList.RowSource & ";Form_Open: " & ";" & T0 & ";" & 0
End Sub
Private Sub Form_Activate()
     T1 = apiTimeGetTime()
     Me.myList.RowSource = Me.myList.RowSource & ";Form_Activate: " & ";" & T1 & ";" & T1 - T0
End Sub
Private Sub Form_Current()
     T1 = apiTimeGetTime()
     Me.myList.RowSource = Me.myList.RowSource & ";Form_Current: " & ";" & T1 & ";" & T1 - T0
End Sub
Private Sub Form_Load()
     T1 = apiTimeGetTime()
     Me.myList.RowSource = Me.myList.RowSource & ";Form_Load: " & ";" & T1 & ";" & T1 - T0
End Sub
Private Sub Form_Resize()
     T1 = apiTimeGetTime()
     Me.myList.RowSource = Me.myList.RowSource & ";Form_Resize: " & ";" & T1 & ";" & T1 - T0
End Sub

 '51. Вызов таймера с применением AddressOf
'#########################

Private hTimer As Long ' Указатель на запущенный процесс

Private Const TIME_ONESHOT = 0 ' Событие случается однажды
Private Const TIME_PERIODIC = 1 ' Событие случается через uDelay миллисекунд

' Запуск процесса
Private Declare Function apiTimeSetEvent Lib "winmm.dll" Alias "timeSetEvent" _
  (ByVal uDelay As Long, _
   ByVal uResolution As Long, _
   ByVal lpFunction As Long, _
   ByVal dwUser As Long, _
   ByVal uFlags As Long) As Long

' Уничтожение процесса
Private Declare Function apiTimeKillEvent Lib "winmm.dll" Alias "timeKillEvent" _
  (ByVal uID As Long) As Long


' Функция запуска событий
Private Sub butExec_Click()
Dim uDelay As Long
Dim uResolution As Long
Dim dwUser As Long
Dim fuEvent As Long

    uDelay = Me.uDelay * 1000 ' Число секунд
    uResolution = Me.uResolution
    dwUser = Me.dwUser
    uFlags = Me.uFlags ' uFlags = TIME_PERIODIC
    hTimer = apiTimeSetEvent(uDelay, _
                            uResolution, _
                            AddressOf funTimerProc, _
                            dwUser, _
                            uFlags)
End Sub

' Программа для выполнения процесса таймера
Public Function funTimerProc(ByVal uID As Long, _
                           ByVal uMsg As Long, _
                           ByVal dwUser As Long, _
                           ByVal dw1 As Long, _
                           ByVal dw2 As Long) As Long
Dim frm As Form
     Set frm = Forms("Example 07")
     frm.Msg = "Время: " & Format(Time, "hh:nn:ss") & _
         ", ID= " & uID & _
         ", Msg=" & uMsg & _
         ", User=" & dwUser & _
         ", dw1=" & dw1 & _
         ", dw2=" & dw2 & vbNewLine & frm.Msg
     funTimerProc = 0
'    Debug.Print uID, uMsg, dwUser, dw1, dw2
End Function

 '52. Системная информация о дисках
'#########################

' Запрашиваем информацию о диске
Private Declare Function apiGetDiskFreeSpace Lib "kernel32" Alias "GetDiskFreeSpaceA" _
     (ByVal lpRootPathName As String, _
         lpSectorsPerCluster As Long, _
         lpBytesPerSector As Long, _
         lpNumberOfFreeClusters As Long, _
         lpTotalNumberOfClusters As Long) As Long

'  Загрузка данных
Private Sub Form_Load()
     On Error Resume Next
     Me.myDrive.RowSource = funGetDrivers
     Me.myDrive = Me.myDrive.Column(0, 0)
     myDrive_AfterUpdate
     Err.Clear
End Sub

'  Получаем информацию о диске системы
Private Function funInformationDisk()
Dim fs, dc, D, s As String
On Error Resume Next
     s = ""
     ' 1. Получаем информацию из файловой системы
     Set fs = CreateObject("Scripting.FileSystemObject")
     Set dc = fs.Drives
     For Each D In dc
         If StrComp(D.DriveLetter, Left(myDrive, 1), vbTextCompare) = 0 Then
             s = s & "Серийный номер: " & D.SerialNumber & ";"
             s = s & "Емкость диска: " & Format(D.TotalSize, "#,0") & ";"
             s = s & "Доступный объем диска: " & Format(D.AvailableSpace, "#,0") & ";"
             s = s & "Свободное место на диске: " & Format(D.FreeSpace, "#,0") & ";"
             s = s & "Метка тома: " & D.VolumeName & ";"
             s = s & "Файловая система: " & D.FileSystem & ";"
             Exit For
         End If
         Err.Clear
     Next D
     ' 2. Получаем информацию из api интерфейса
     Dim SectorsPerCluster As Long ' Секторов на клястер
     Dim BytesPerSector As Long ' Байт на сектор
     Dim NumberOfFreeClustors As Long ' Свободных клястеров
     Dim TotalNumberOfClustors As Long ' Всего клястеров

     ' Запрашиваем свободное место
     Call apiGetDiskFreeSpace(Left(Me.myDrive, 2), _
         SectorsPerCluster, BytesPerSector, _
         NumberOfFreeClustors, TotalNumberOfClustors)
     s = s & "Число секторов на клястер: " & Format(SectorsPerCluster, "#,0") & ";"
     s = s & "Число байт на сектор: " & Format(BytesPerSector, "#,0") & ";"
     s = s & "Число свободных клястеров: " & Format(NumberOfFreeClustors, "#,0") & ";"
     s = s & "Всего клястеров: " & Format(TotalNumberOfClustors, "#,0") & ";"
     
     ' Используя клястеры Вы можете определить
     ' a) Емкость диска = TotalNumberOfClustors * SectorsPerCluster * BytesPerSector
     ' b) Свободное место = NumberOfFreeClustors * SectorsPerCluster * BytesPerSector
     
     ' 3. Присваиваем источник данных
     Me.myList.RowSource = s
     Exit Function
End Function

'  Заполняем список с информацией о дисках
Private Function funGetDrivers() As String
Dim fs, dc, D
Dim s As String
On Error GoTo 999
     Err.Clear
     funGetDrivers = ""
     Set fs = CreateObject("Scripting.FileSystemObject")
     Set dc = fs.Drives
     For Each D In dc
         Select Case D.driveType
           Case 0: s = "Неизвестная БД"
           Case 1: s = "Дискета"
           Case 2: s = "Жесткий диск"
           Case 3: s = "Сетевой диск"
           Case 4: s = "CD-ROM"
           Case 5: s = "RAM диск"
         End Select
         If D.IsReady Then
            funGetDrivers = funGetDrivers & D.DriveLetter & ":\ - " & s & ";"
         End If
     Next
     Exit Function
999:
     MsgBox Err.Description
     Err.Clear
     funGetDrivers = ""
End Function

'  Обновляем информацию
Private Sub myDrive_AfterUpdate()
     funInformationDisk
End Sub

 '53. Управление текстовым буфером
'#########################

' Функции управления буфером
Private Declare Function IsClipboardFormatAvailable Lib "user32" _
     (ByVal uFormat As Integer) As Integer
Private Declare Function apiOpenClipboard Lib "user32" Alias "OpenClipboard" _
     (ByVal hwnd As Long) As Integer
Private Declare Function apiSetClipboardData Lib "user32" Alias "SetClipboardData" _
     (ByVal uFormat As Integer, _
      ByVal hData As Long) As Long
Private Declare Function apiGetClipboardData Lib "user32" Alias "GetClipboardData" _
     (ByVal uFormat As Integer) As Long
Private Declare Function apiCloseClipboard Lib "user32" Alias "CloseClipboard" _
     () As Integer
Private Declare Function apiEmptyClipboard Lib "user32" Alias "EmptyClipboard" _
     () As Integer

' Функции управления памятью
Private Declare Function apiGlobalAlloc Lib "kernel32" Alias "GlobalAlloc" _
     (ByVal uFlags As Integer, _
      ByVal dwBytes As Long) As Long
Private Declare Function apiGlobalSize Lib "kernel32" Alias "GlobalSize" _
     (ByVal hMem As Long) As Integer
Private Declare Function apiGlobalLock Lib "kernel32" Alias "GlobalLock" _
     (ByVal hMem As Long) As Long
Private Declare Sub apiMoveMemory Lib "kernel32" Alias "RtlMoveMemory" _
     (ByVal strDest As Any, _
      ByVal lpSource As Any, _
      ByVal Length As Long)
Private Declare Function apiGlobalUnlock Lib "kernel32" Alias "GlobalUnlock" _
     (ByVal hMem As Long) As Integer
Private Declare Function apiGlobalFree Lib "kernel32" Alias "GlobalFree" _
     (ByVal hMem As Long) As Long

' api-Константы памяти
Private Const GMEM_FIXED = &H0
Private Const GMEM_MOVEABLE = &H2
Private Const GMEM_NOCOMPACT = &H10
Private Const GMEM_NODISCARD = &H20
Private Const GMEM_ZEROINIT = &H40
Private Const GMEM_MODIFY = &H80
Private Const GMEM_DISCARDABLE = &H100
Private Const GMEM_NOT_BANKED = &H1000
Private Const GMEM_SHARE = &H2000
Private Const GMEM_DDESHARE = &H2000
Private Const GMEM_NOTIFY = &H4000
Private Const GMEM_LOWER = GMEM_NOT_BANKED
Private Const GMEM_VALID_FLAGS = &H7F72
Private Const GMEM_INVALID_HANDLE = &H8000
Private Const GMEM_TEXT = (GMEM_MOVEABLE Or GMEM_DDESHARE)

' api-Форматы буфера
Private Const CF_TEXT = 1
Private Const CF_BITMAP = 2
Private Const CF_METAFILEPICT = 3
Private Const CF_SYLK = 4
Private Const CF_DIF = 5
Private Const CF_TIFF = 6
Private Const CF_OEMTEXT = 7
Private Const CF_DIB = 8
Private Const CF_PALETTE = 9
Private Const CF_PENDATA = 10
Private Const CF_RIFF = 11
Private Const CF_WAVE = 12
Private Const CF_UNICODETEXT = 13
Private Const CF_ENHMETAFILE = 14

'==============================================================
'  Копируем текст в буфер
'
Function CopyText(strText As String) As Variant
Dim hMem As Long
Dim lpMem As Long
Dim l As Long

     ' Выделение памяти
     l = Len(strText) + 1 ' Длина строки с учетом символа \0 (c++)
     hMem = apiGlobalAlloc(GMEM_TEXT, l) ' Память для буфера
     
     ' Управление памятью
     lpMem = apiGlobalLock(hMem) ' Блокируем часть памяти
     Call apiMoveMemory(lpMem, strText, l) ' Копируем строку в память
     Call apiGlobalUnlock(hMem) ' Разблокируем память
     
     ' Управление буфером
     Call apiOpenClipboard(0&) ' Открываем буфер
     Call apiEmptyClipboard ' Очищаем буфер
     Call apiSetClipboardData(CF_TEXT, hMem) ' Загружаем текст
     Call apiCloseClipboard ' Закрываем буфер
     
     ' Освобождаем память
     Call apiGlobalFree(hMem)
End Function

'==============================================================
'  Получаем текст из буфера
'
Public Function GetText() As Variant
Dim hMem As Long
Dim lpMem As Long
Dim s As String
Dim l As Long

     ' Проверяем формат буфера
     If Not CBool(IsClipboardFormatAvailable(CF_TEXT)) Then
         Exit Function
     End If
    
     ' Работаем с буфером и памятью
     Call apiOpenClipboard(0&) ' Открываем буфер
     hMem = apiGetClipboardData(CF_TEXT) ' Получаем заголовок данных в буфере
     l = apiGlobalSize(hMem) ' Определяем размер строки
     s = Space$(l) ' Выделение памяти для строки
     lpMem = apiGlobalLock(hMem) ' Блокируем память
     Call apiMoveMemory(s, lpMem, l) ' Копируем информацию из буфера в строку
     Call apiGlobalUnlock(hMem) ' Разблокирование памяти
     Call apiCloseClipboard ' Закрываем буфер
     
     ' Возвращаем результат
     GetText = Left$(s, InStr(1, s, Chr$(0)) - 1)
     
End Function

 '54. Получение сетевого имени пользователя
'#########################

Private Declare Function apiGetUserName Lib "advapi32.dll" Alias "GetUserNameA" _
 (ByVal lpBuffer As String, nSize As Long) As Long


' Возвращает сетевое имя пользователя
Function funGetUserName() As String
Dim BufSize As Long, strUserName As String * 255, Status As Long
     On Error GoTo 999
         BufSize = 255
         Status = apiGetUserName(strUserName, BufSize)
         If Status = 1 Then
             funGetUserName = Left$(strUserName, InStr(strUserName, Chr(0)) - 1)
         Else
             funGetUserName = ""
         End If
     Exit Function
999:
     MsgBox Err.Description
End Function

' Функция запуска событий
Private Sub butExec_Click()
     Me.Msg = "Локальное имя: " & funGetUserName & vbNewLine & _
              "Сетевое имя: " & NetUserID
End Sub

 '54. Работа с FTP протоколом
'#########################

Private Declare Function FtpGetFile _
   Lib "wininet.dll" Alias "FtpGetFileA" ( _
   ByVal hFtpSession As Long, _
   ByVal lpszRemoteFile As String, _
   ByVal lpszNewFile As String, _
   ByVal fFailIfExists As Boolean, _
   ByVal dwFlagsAndAttributes As Long, _
   ByVal dwFlags As Long, _
   ByVal dwContext As Long) As Boolean

Private Declare Function InternetOpen _
   Lib "wininet.dll" Alias "InternetOpenA" ( _
   ByVal sAgent As String, _
   ByVal nAccessType As Long, _
   ByVal sProxyName As String, _
   ByVal sProxyBypass As String, _
   ByVal nFlags As Long) As Long

Private Declare Function InternetConnect _
   Lib "wininet.dll" Alias "InternetConnectA" ( _
   ByVal hInternetSession As Long, _
   ByVal sServerName As String, _
   ByVal nServerPort As Integer, _
   ByVal sUserName As String, _
   ByVal sPassword As String, _
   ByVal nService As Long, _
   ByVal dwFlags As Long, _
   ByVal dwContext As Long) As Long

hINetSession = InternetOpen("MyFTPClient", 0, vbNullString, vbNullString, 0)


hSession = InternetConnect(hINetSession, "ftp.microsoft.com", _
   "21", "anonymous", "guest", INTERNET_SERVICE_FTP, 0, 0)
    
Private Const INTERNET_SERVICE_FTP = 1
Private Const INTERNET_SERVICE_GOPHER = 2
Private Const INTERNET_SERVICE_HTTP = 3

Private Declare Function FtpGetFile _
   Lib "wininet.dll" Alias "FtpGetFileA" ( _
   ByVal hFtpSession As Long, _
   ByVal lpszRemoteFile As String, _
   ByVal lpszNewFile As String, _
   ByVal fFailIfExists As Boolean, _
   ByVal dwFlagsAndAttributes As Long, _
   ByVal dwFlags As Long, _
   ByVal dwContext As Long) As Boolean

If FtpGetFile(hSession, "dirmap.htm", "c:\dirmap.htm", False, 0, 1, 0) = False Then
   MsgBox "Call to FtpGetFile Failed!"
End If

Пункт четвертый, заключительный: закрываем Хендлы

Private Declare Function InternetCloseHandle _
   Lib "wininet.dll" (ByVal hInet As Long) As Integer

Call InternetCloseHandle(hSession)
Call InternetCloseHandle(hINetSession)

Private Declare Function FtpPutFile _
   Lib "wininet.dll" Alias "FtpPutFileA" ( _
   ByVal hFtpSession As Long, _
   ByVal lpszLocalFile As String, _
   ByVal lpszRemoteFile As String, _
   ByVal dwFlags As Long, _
   ByVal dwContext As Long) As Boolean
If FtpPutFile(hSession, "c:\MyFile.txt", "shared.txt", 1, 0) = False Then
   MsgBox "The call to FtpPutFile failed."
End If

Private Declare Function FtpDeleteFile _
   Lib "wininet.dll" Alias "FtpDeleteFileA" ( _
   ByVal hFtpSession As Long, _
   ByVal lpszFileName As String) As Boolean

ПЕРЕИМЕНОВАНИЕ
Private Declare Function FtpRenameFile _
   Lib "wininet.dll" Alias "FtpRenameFileA" ( _
   ByVal hFtpSession As Long, _
   ByVal lpszExisting As String, _
   ByVal lpszNewName As String) As Boolean

Private Declare Function FtpFindFirstFile _
   Lib "wininet.dll" Alias "FtpFindFirstFileA" ( _
   ByVal hFtpSession As Long, _
   ByVal lpszSearchFile As String, _
   ByRef lpFindFileData As WIN32_FIND_DATA, _
   ByVal dwFlags As Long, _
   ByVal dwContent As Long) As Long
   
Private Declare Function InternetFindNextFile _
   Lib "wininet.dll" Alias "InternetFindNextFileA" ( _
   ByVal hFind As Long, _
   ByRef lpvFindData As WIN32_FIND_DATA) As Long

Private Type WIN32_FIND_DATA
   dwFileAttributes As Long
   ftCreationTime As FILETIME
   ftLastAccessTime As FILETIME
   ftLastWriteTime As FILETIME
   nFileSizeHigh As Long
   nFileSizeLow As Long
   dwReserved0 As Long
   dwReserved1 As Long
   cFileName As String * 260
   cAlternate As String * 14
End Type

Подструктура FileName:
Private Type FILETIME
   dwLowDateTime As Long
   dwHighDateTime As Long
End Type

Private Sub ListFiles()
    Dim hFile As Long ' This is a file handle
    Dim fd As WIN32_FIND_DATA
    hFile = FtpFindFirstFile(hSession, "*.*", fd, 0, 0)
        If hFile = 0 Then
            If Err.LastDllError = ERROR_NO_MORE_FILES Then
                MsgBox "No files found"
                Exit Sub
            Else
                MsgBox "Some error occurred"
                Exit Sub
            End If
        End If
    Do
        List1.AddItem fd.cFileName
    Loop While InternetNextFile(hFile, fd)  0
    'Close the file handle
    Call InternetCloseHandle(hFile)
End Sub

 '55. Получ MAC адрес сетевой карты.
'#########################

Option Explicit
Public Const NCBASTAT As Long = &H33
Public Const NCBNAMSZ As Long = 16
Public Const HEAP_ZERO_MEMORY As Long = &H8
Public Const HEAP_GENERATE_EXCEPTIONS As Long = &H4
Public Const NCBRESET As Long = &H32

Public Type NET_CONTROL_BLOCK  'NCB
   ncb_command    As Byte
   ncb_retcode    As Byte
   ncb_lsn        As Byte
   ncb_num        As Byte
   ncb_buffer     As Long
   ncb_length     As Integer
   ncb_callname   As String * NCBNAMSZ
   ncb_name       As String * NCBNAMSZ
   ncb_rto        As Byte
   ncb_sto        As Byte
   ncb_post       As Long
   ncb_lana_num   As Byte
   ncb_cmd_cplt   As Byte
   ncb_reserve(9) As Byte ' Reserved, must be 0
   ncb_event      As Long
End Type

Public Type ADAPTER_STATUS
   adapter_address(5) As Byte
   rev_major         As Byte
   reserved0         As Byte
   adapter_type      As Byte
   rev_minor         As Byte
   duration          As Integer
   frmr_recv         As Integer
   frmr_xmit         As Integer
   iframe_recv_err   As Integer
   xmit_aborts       As Integer
   xmit_success      As Long
   recv_success      As Long
   iframe_xmit_err   As Integer
   recv_buff_unavail As Integer
   t1_timeouts       As Integer
   ti_timeouts       As Integer
   Reserved1         As Long
   free_ncbs         As Integer
   max_cfg_ncbs      As Integer
   max_ncbs          As Integer
   xmit_buf_unavail  As Integer
   max_dgram_size    As Integer
   pending_sess      As Integer
   max_cfg_sess      As Integer
   max_sess          As Integer
   max_sess_pkt_size As Integer
   name_count        As Integer
End Type
   
Public Type NAME_BUFFER
   name        As String * NCBNAMSZ
   name_num    As Integer
   name_flags  As Integer
End Type

Public Type ASTAT
   adapt          As ADAPTER_STATUS
   NameBuff(30)   As NAME_BUFFER
End Type

Public Declare Function Netbios Lib "netapi32.dll" _
   (pncb As NET_CONTROL_BLOCK) As Byte
     
Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
   (hpvDest As Any, ByVal _
    hpvSource As Long, ByVal _
    cbCopy As Long)
     
Public Declare Function GetProcessHeap Lib "kernel32" () As Long

Public Declare Function HeapAlloc Lib "kernel32" _
    (ByVal hHeap As Long, ByVal dwFlags As Long, _
     ByVal dwBytes As Long) As Long
     
Public Declare Function HeapFree Lib "kernel32" _
    (ByVal hHeap As Long, _
     ByVal dwFlags As Long, _
     lpMem As Any) As Long


Public Function GetMACAddress() As String

  'запрашиваем MAC Адрес для сетевой карты
  'возвращаем форматированную строку
   
   Dim tmp As String
   Dim pASTAT As Long
   Dim NCB As NET_CONTROL_BLOCK
   Dim AST As ASTAT

   NCB.ncb_command = NCBRESET
   Call Netbios(NCB)
   
  'Для получения Media Access Control (MAC) адреса для сетевой карты
  'программным путём, используется команда Netbios() -
  'NCBASTAT с именем "*" в поле NCB.ncb_CallName (в 16-символьной строке).
   NCB.ncb_callname = "*               "
   NCB.ncb_command = NCBASTAT
   
  'Для машин с несколькими сетевыми картами Вам необходимо использовать
  'номер LANA и выполнять команду NCBASTAT для каждого. LANA номер 0 всегда
  'соответствует первому сетевому адаптеру. Конечно можно использовать LANA
  'номер и для одного сетевого адаптера, но это будет считаться как
  'неэффективное  программирование.
   NCB.ncb_lana_num = 0
   NCB.ncb_length = Len(AST)
   
   pASTAT = HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS _
            Or HEAP_ZERO_MEMORY, NCB.ncb_length)
            
   If pASTAT = 0 Then
      Debug.Print "memory allocation failed!"
      Exit Function
   End If
   
   NCB.ncb_buffer = pASTAT
   Call Netbios(NCB)
   
   CopyMemory AST, NCB.ncb_buffer, Len(AST)
   
   tmp = Format$(Hex(AST.adapt.adapter_address(0)), "00") & " " & _
         Format$(Hex(AST.adapt.adapter_address(1)), "00") & " " & _
         Format$(Hex(AST.adapt.adapter_address(2)), "00") & " " & _
         Format$(Hex(AST.adapt.adapter_address(3)), "00") & " " & _
         Format$(Hex(AST.adapt.adapter_address(4)), "00") & " " & _
         Format$(Hex(AST.adapt.adapter_address(5)), "00")
           
   
   HeapFree GetProcessHeap(), 0, pASTAT
   
   GetMACAddress = tmp

End Function

'Код формы.
'Добавьте в форму кнопку (Command1), и текстовое поле (Text1). Метки и фреймы не обязательны. Добавьте в событие кнопки следующий код:
Option Explicit

Private Sub Command1_Click()
   Text1 = GetMACAddress()
End Sub


 '56. Реестр и Windows API
'#########################

'В ранних версиях Windows, все её приложения хранили необходимую для запуска и работы информацию в файлах инициализации. С развитием ОС информации, необходимой для сохранения стало так много, что возникла необходимость в новом способе её хранения - реестре. Реестр, - это своеобразная база данных для приложений Windows. Его структура напоминает файловую систему. (не верите посмотрите через regedit.exe только ничего не меняйте). Вообще реестр считают несомненной альтернативой INI-файлам, но я думаю, что эти две технологии имеют наибольшую мощность только при их совмещении.
'В Visual Basic есть функции для работы с реестром( GetSetting,SaveSetting) но их возможности ограничены. Они могут работать с реестром только в разделе HKEY_CURRENT_USER\Software\VB and VBA Programms, и способны только читать и записывать. Для начинающего программиста это неплохо, даже хорошо - меньше возможностей навредить.На самом деле Windows может намного больше. Расширить возможности VB, позволяет Windows API.
'Windows обладает большим набором функций для работы с реестром, сами по себе GetSetting и SaveSetting тоже вызывают их. С помощью этих функций, вы можете создавать разделы, в любой части реестра, а затем удалять их :), подключать реестр через сеть, сохранять разделы в файле и т.д.
'В качестве примера, мы создадим класс, для работы с реестром через Windows API (насколько я знаю в Borland Delphi, нечто подобное уже есть, и один знакомый программист очень этим гордится 🙂 ). Этот класс может работать только со строковыми данными. Я посчитал, что если Вам понадобится больше, Вы сможете сделать это сами. Кроме того класс даёт возможность удалять лишние разделы, и параметры. Работу с реестром через сеть, и остальные возможности я исключил, так как этот класс задуман как расширение Basic'овских функций для работы с реестром. Остальные операции будут заключены в другой класс, который должен будет реализовать все возможности Windows API в работе с реестром.
'Итак, хватит лирики, приступим к работе. Создадим новый модуль класса и назовём его RegistryExClass(совсем как в API, RegSetValue,RegSetValueEx). После этого приступим к объявлению необходимых функций.Я рассмотрю только особенные, остальные найдёте в API Text Viewer. (RegOpenKey, RegDeleteValue, RegDeleteKey, RegCloseKey, RegCreateKey)
Private Declare Function RegQueryValueExS Lib "advapi32.dll" _
 Alias "RegQueryValueExA" ( _
 ByVal hkey As Long, _
 ByVal lpValueName As String, _
 ByVal lpReserved As Long, _
 lpType As Long, _
 ByVal lpData As String, _
 lpcbData As Long) As Long

Private Declare Function RegSetValueExS Lib "advapi32.dll" _
 Alias "RegSetValueExA" ( _
 ByVal hkey As Long, _
 ByVal lpValueName As String, _
 ByVal Reserved As Long, _
 ByVal dwType As Long, _
 ByVal lpData As String, _
 ByVal cbData As Long) As Long
'
'Что здесь особенного, спросите Вы. Объясняю: Как я уже сказал мой класс работает только со строками. Приведённые выше функции, в оригинальном объявлении не имеют чётко определённого типа данных(lpData As Any). При попытке использовать такое объявление, я получал ошибку "Out Of Memory". Как видно в листинге, я объявил lpData как строку, хотя имею возможность присвоить любой тип. Беда в том, что VB не поймёт Вас при попытке объявить две функции. Чтобы обойти это, я и объявил функции с оконаниями "-S". И теперь в класс можно будет добавить ещё функции для работы с различными типами.
'Ещё по той же теме. Некоторые функции для работы с реестром имеют параметры типа SECURITY_ATTRIBUTES. Если эти параметры Вам не нужны, то объявите их как Long, и передавайте ноль.
'Теперь объявим константы.
'Объявив эти константы таким способом, Вы дадите
'пользователю класса возможность выбирать из списка
'значение параметра
Public Enum HKEY_CONSTANTS
 HKEY_CLASSES_ROOT = &H80000000
 HKEY_CURRENT_CONFIG = &H80000005
 HKEY_CURRENT_USER = &H80000001
 HKEY_DYN_DATA = &H80000006
 HKEY_LOCAL_MACHINE = &H80000002
 HKEY_PERFORMANCE_DATA = &H80000004
 HKEY_USERS = &H80000003
End Enum

'Ну ещё константа, для строкового типа
Private Const REG_SZ = 1

'Теперь создадим методы для чтения/записи параметров
'~~~~~~.GetString Функция
Public Function GetString( _
   ByVal HomeKey As HKEY_CONSTANTS, _
   ByVal KeyName As String, _
   ByVal ValueName As String) As String

'Handle раздела реестра
Dim hkey As Long
'переменная для хранения значения
Dim sData As String
'Результат работы API функций
Dim lres As Long
'Тип возвращаемого значения
Dim lDataType As Long
'переменная для хранения длины строки
Dim lDlen As Long
'Открываем Раздел
lres = RegOpenKey(HomeKey, KeyName, hkey)
'Если вернулся не ноль - ошибка, выходим
If lres  0 Then GetRegString = vbNullString: Exit Function
'Продолжаем, заполняем строку пробелами.
sData = String$(64, 32) & Chr$(0)
lDlen = Len(sData)
'Читаем значение
lres = RegQueryValueExS(hkey, ValueName, 0, lDataType, sData, lDlen)
'опять проверка на ошибку
If lres  0 Then GetRegString = vbNullString: Exit Function
'проверяем тип полученных данных
If lDataType = REG_SZ Then
GetString = Left$(sData, lDlen - 1)
Else
GetString = vbNullString
End If
'и закрываем раздел
lres = RegCloseKey(hkey)
End Function

'~~~~~.SaveString  Метод
Public Sub SaveString( _
    ByVal HomeKey As HKEY_CONSTANTS, _
    ByVal KeyName As String, _
    ByVal ValueName As String, _
    ByVal Data As String)

'Handle для корневого раздела
Dim hkey As Long
'Handle для изменяемого раздела
Dim hSubKey  As Long
'Результат работы функции
Dim lres As Long
'Открываем корневой раздел
lres = RegOpenKey(HomeKey, vbNullString, hkey)
'Создаём(если есть открываем) нужный раздел
lres = RegCreateKey(HomeKey, KeyName, hSubKey)
'Пишем данные
lres = RegSetValueExS(hSubKey, ValueName, 0, _
   REG_SZ, Data + Chr$(0), Len(Data) + 1)

'и закрываем всё открытое
lres = RegCloseKey(hSubKey)
lres = RegCloseKey(hkey)
End Sub

'Метод GetString всего лишь читает параметр из реестра. SaveString - имеет больше возможностей. С его помощью Вы можете создать пустой раздел. Для этого вызовите его, установив значение ValueName и Data равное пустой строке. Если хотите установить для раздела значение по умолчанию присвойте Data нужное значение, при нулевом(vbNullString) ValueName.
'Теперь поработаем с удалением.

'~~~~~~.DeleteValue Метод
Public Sub DeleteValue( _
    ByVal HomeKey As HKEY_CONSTANTS, _
    ByVal KeyName As String, _
    ByVal ValueName As String)

'Handle для изменяемого раздела
Dim hkey As Long
'Результат API функции
Dim lres As Long
'открываем нужные раздел
lres = RegOpenKey(HomeKey, KeyName, hkey)
'проверяем на ошибку
If lres  0 Then Exit Sub
'удаляем параметр
lres = RegDeleteValue(hkey, ValueName)
'закрываем
lres = RegCloseKey(hkey)
End Sub

'~~~~~~.DeleteKey
Public Sub DeleteKey( _
   ByVal HomeKey As HKEY_CONSTANTS, _
   ByVal KeyName As String)
'результат APi функции
Dim lres As Long
'Удаляем раздел из корневого
lres = RegDeleteKey(HomeKey, KeyName)
End Sub

 '57. способ получения скриншота
'#########################

'Способ основан на симуляции нажатия клавиши Print Screen (Const vbKeySnapshot = 44 (&H2C)), - для копирования изображения экрана, и методе Clipboard.GetData(vbCFBitmap), - для дальнейшего получения изображения в Picture (Picture Box).
'Объявляем в General Form1:
Private Declare Sub keybd_event Lib "user32" _
(ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, _
ByVal dwExtraInfo As Long)
Dim A As Integer
'в Properties Form1 устанавливаем BorderStyle в 0-None, для того, чтобы в
'момент получения  экрана, детали формы не попали в "кадр"
Private Sub Form_Load()
   'делаем форму невидимой, но при этом оставляем активными все 'компоненты
   Form1.height = 0
   Timer1.Interval = 1
   'очищаем Clipboard
   Clipboard.Clear
   'копируем изображение экрана
   keybd_event vbKeySnapshot, 1, 0&, 0&
End Sub

Private Sub Timer1_Timer()
   A = A + 1
   If A = 2 Then
      'вклеиваем изображение в картинку
      Picture1.Picture = Clipboard.GetData(vbCFBitmap)
      'задаём размеры формы и картинки
      Form1.Width = Screen.Width * 0.8
      Form1.height = Screen.height * 0.8
      Form1.Left = (Screen.Width - Width) / 2
      Form1.Top = (Screen.height - height) / 2
      Picture1.height = Form1.ScaleHeight * 1
      Picture1.Width = Form1.ScaleWidth * 1
      Picture1.Left = (Form1.Width - Picture1.Width) / 2
      Picture1.Top = (Form1.height - Picture1.height) / 2
   End If
   If A = 2 Then
      'очищаем Clipboard
      Clipboard.Clear
      'выключаем Timer1
      Timer1.Enabled = False
   End If
End Sub

'для выхода из программы
Private Sub Picture1_Click()
   End
End Sub

 '58. Техника программирования сложных окон в Visual Basic
'#########################

'Многие из Вас наверняка видели в Windows программах окна нестандартной формы (круглые, треугольные и т.д.) и задавали себе вопрос: как мне сделать такое окно? Если прочитать документацию по Visual Basic, то можно сделать вывод, что стандартные средства языка не предоставляют такой возможности. А что же делать, если очень хочется? Тогда следует вспомнить, что в распоряжении программиста на VB есть еще и Windows API, который должен нам в этом помочь.
'Теоретические основы
'
'Для начала давайте разберемся, как это можно сделать теоретически. Из документации Windows видно, что каждое окно в системе описывается множеством параметров, из которых нас с Вами интересует . Видимая область окна в системе, создаваемое Visual Basic  имеет вид прямоугольника, но, в принципе, ничто не мешает изменить форму этой области. Данная область окна описывается с помощью специального объекта, который называется Region. Регион можно представить в виде поверхности, ограниченной координатами, описываемыми угловые точки этой области. Проще говоря, можно описать область любой формы, затем создать из неё, с помощью специальных функций, регион и  его к нужому нам окну.
'
'Существует несколько функций Windows API для создания регионов, основными из которых являются следующие:
'CombineRgn - Комбинирует два региона между собой
'CreateEllipticRgn - Создает регион в виде эллипса или окружности
'CreatePolygonRgn - Создает регион в виде многоугольника
'CreateRectRgn - Создает прямоугольный регион
'CreateRoundRectRgn - Создает регион со скругленными краями из прямоугольной области
'SetWindowRgn - Прикрепляет регион к указанному окну
'
'Я не буду приводить подробное описание этих функций, так как его можно найти в описании Win32 API. Кроме этих функций существуют ещё несколько функций для работы с регионами, но нам они не потребуются.
'Создание простых нестандартных окон
'
'Теперь, когда нам известны основные функции, для создания регионов, мы можем применить полученные знания на практике. Загрузите проект pTestRgn и внимательно изучите его код. В этом проете, для изменения формы окна на овальную, используется всего три строки кода и три функции Win32 API. Вначале с помощью CreateEllipticRgn создается регион, затем он прикрепляется к окну и, наконец, завершающая фаза удаление, ставшего ненужным, созданного нами региона. Если же Вы не удалите ненужный Вам больше объект, то Windows, создав регион для Вас будет хранить его в своих  и ждать дальнейших указаний по его использованию. В общем, нехорошо  выделенную память, и настигнет Вас кара небесная, и затянется небо тучами синими, и будет страшный суд над всеми неверующими: Короче код выглядит так:
Private Sub cmbCreateOval_Click()
   Dim lRgn As Long
   lRgn = CreateEllipticRgn(0, 0, Me.ScaleWidth / Screen.TwipsPerPixelX, _
   Me.ScaleHeight / Screen.TwipsPerPixelY)
   SetWindowRgn Me.hwnd, lRgn, True
   DeleteObject lRgn
End Sub

'Так же всё просто, скажете Вы? Да, на первый взгляд всё очень просто, но это только кажется. Тот пример, который Вы только что видели, почти не имеет практического применения в настоящих приложениях Windows. Кому же нужно просто овальное окно, которое к тому же жестко задается на этапе программирования? А вот окно, которое свободно могло бы менять свою форму вполне может потребоваться. Примеры? Пожалуйста, WinAmp, Помощник в Microsoft Office и другие программы. Как же там всё это реализовано? Давайте разберемся с таким применением регионов.
'Создание сложных нестандартных окон
'
'Допустим, что у нас есть рисунок в BMP формате, из которого нужно сделать форму, а белый цвет (например) на нём означает . Как же сделать форму? Очень просто, нужно взять все  пиксели на рисунке, создать из их координат регион и прикрепить его к нужному нам окну. Анализировать пиксели можно GetPixel, эта функция по координатам возвращает его цвет. Давайте теперь напишем такой алгоритм для анализа BMP матрицы. Я думаю, что такой алгоритм Вам известен, и мы не будем его подробно разбирать, отмечу только, что анализ производится построчно и Pixel-и добавляются в регион не по одному, а группами построчно. Такой подход сильно экономит ресурсы процессора, выигрыш в производительности достигает 100%.
Public Function lGetRegion(pic As PictureBox, lBackColor As Long) As Long
   Dim lRgn As Long
   Dim lSkinRgn As Long
   Dim lStart As Long
   Dim lX As Long
   Dim lY As Long
   Dim lHeight As Long
   Dim lWidth As Long

   'создаем пустой регион, с которого начнем работу
   lSkinRgn = CreateRectRgn(0, 0, 0, 0)
   With pic
      'подсчитаем размеры рисунка в Pixel
      lHeight = .height / Screen.TwipsPerPixelY
      lWidth = .Width / Screen.TwipsPerPixelX
      For lX = 0 To lHeight - 1
         lY = 0
         Do While lY < lWidth
            'ищем нужный Pixel
            Do While lY < lWidth And GetPixel(.hdc, lY, lX) = lBackColor
               lY = lY + 1
            Loop
            If lY < lWidth Then
               lStart = lY
            Do While lY < lWidth And GetPixel(.hdc, lY, lX)  lBackColor
               lY = lY + 1
            Loop
            If lY > lWidth Then lY = lWidth
               'нужный Pixel найден, добавим его в регион
               lRgn = CreateRectRgn(lStart, lX, lY, lX + 1)
               CombineRgn lSkinRgn, lSkinRgn, lRgn, RGN_OR
               DeleteObject lRgn
            End If
         Loop
      Next
   End With
   lGetRegion = lSkinRgn
End Function

'Итак, для проверки на практике этого алгоритма загрузите пример pTestRgnSkin и внимательно изучите его код. В этом проекте нужный нам рисунок, для удобства,  в файле ресурсов, кроме того проект запускается процедурой Main, в которой и происходят все преобразования. Вначале загружается форма, затем в PictureBox из ресурсов загружается нужный нам рисунок, далее вызывается функция, которая создает регион и, наконец, завершающий этап - прикрепление региона к нужному нам окну. Для удобства здесь же вызывается функция, помещающая окно , чтобы оно  у Вас на рабочем столе Windows. Кроме того, для нормальной работы программы необходимо, чтобы для PictureBox свойство AutoRedraw было установленно в True, иначе ничего не получится.
Sub Main()
   Dim lRgn As Long
   Load frmTestRgnSkin
   frmTestRgnSkin.pic.Picture = LoadResPicture(101, vbResBitmap)
   lRgn = lGetRegion(frmTestRgnSkin.pic, vbWhite)
   SetWindowRgn frmTestRgnSkin.hwnd, lRgn, True
   DeleteObject lRgn
   frmTestRgnSkin.Show
   SetFormPosition frmTestRgnSkin.hwnd, True
End Sub

'Теперь можно запускать проект... О, знакомое лицо, скажите Вы, это же  из Microsoft Office. Да, похож, но не совсем,  двигается, а этот нет. Что же нужно сделать, чтобы это окно динамически изменяло свою форму по рисунку, отображаемому в данный момент времени в PictureBox?
'Динамическое изменение формы окна
'
'Существуют программы в которых необходимо динамически во время работы изменять форму окна (например анимированный персонаж из Microsoft Office). Все это не очень сложно реализовать, нужно в событие PictureBox.Change добавить следующий код:
lRgn = lGetRegion(frmTestRgnSkin.pic, vbWhite)
SetWindowRgn frmTestRgnSkin.hwnd, lRgn, True
DeleteObject lRgn
SetFormPosition frmTestRgnSkin.hwnd, True

'В принципе всё готово, осталось только добавить код для изменения картинки на форме, и  оживёт. В нашем примере изменять рисунок будем в Timer циклически, т.е. анимация будет непрерывна, так проще. Итак, добавим на форму Timer и поместим  небольшой код, отвечающий за изменения рисунка в PictureBox. Рисунков в файле ресурсов десять штук, поэтому I должно изменяться от 101 до 110. Код изменения выглядит так:
Static i As Long
If i  110 Then i = 101
frmAnimateForm.pic.Picture = LoadResPicture(i, vbResBitmap)
i = i + 1

'Готово, можно запускать проект, и если Вы счастливый обладатель Pentium III или Athlon, то Вам улыбнется удача, так как  будет двигаться. Но если Ваш процессор Pentium II и ниже, то компьютер не сможет выполнять необходимые расчеты за нужное нам время, так как для плавной анимации необходимо (для нашего случая) показывать порядка 15 кадров в секунду, а точнее каждые 80 милисекунд по кадру и ещё оставлять время для других задач компьютера. Как мы видим наши алгоритмы явно не тянут для таких задач и предназначены для  не требующих таких быстрых изменений формы окна, так как, например на Celeron 333 один кадр формируется около 100 милисекунд. Что же делать?
'Оптимизация алгоритма для быстрой анимации
'
'Анализ работы алгоритма показывает, что наибольшие затраты времени приходятся на функцию GetPixel. Это происходит потому, что анализ картинки идет непосредственно на экране. Единственный путь увеличения быстродействия алгоритма, это перенос анализа в память компьютера и использование при этом Win 32 API. Такие алгоритмы существуют, но это тема отдельного разговора, скажу только, что для оптимизации работы алгоритм пишется отдельно для каждой глубины цвета и при применении такой схемы быстродействие увеличивается почти в четыре раза и позволяет делать практически любую анимацию.


 '58. Хранитель Экрана на Visual Basic
'#########################

'Хорош Visual Basic тем, что он позволяет создавать хранители экрана. Для этого нужно всего лишь создать проект с одной или несколькими формами, простым кодом, и откомпилировать его в файл с расширением *.Scr в рабочий каталог Windows.
'
'Как я думаю уже понятно, весь фокус состоит в коде. Его мы сейчас разберём, но сначала создадим форму. Разместим на ней таймер, и установим некоторые cвойства. (BorderStyle = None, WindowState = Maximized,Name = frmSSaver).Теперь приступаем к созданию кода. Сначала, как и всегда нам нужно объявить все необходимые переменные:
Option Explicit
Private DDC As Long 'Переменная для хранения хэндла Рабочего стола
Private BlockX As Long 'Размер закрашиваемого кусочка по горизонтали
Private BlockY As Long 'Размер закрашиваемого кусочка по вертикали
Private Quit As Boolean 'Флаг завершения

Private OldX As Single 'переменные для хранения
Private OldY As Single 'координат мыши
Const AppName = "VB Screen Saver" 'Имя программы в реестре

'Так как вся работа выполняется в цикле таймера, для выхода используется флаг Quit. Кстати о самой работе. Весь основной код Хранителя экрана прост как всё гениальное(какой я скромный правда?):
Private Sub Timer1_Timer()
'Код работы Хранителя экрана
Dim X As Long, Y As Long
X = (Rnd * Screen.Width) / Screen.TwipsPerPixelX
Y = (Rnd * Screen.height) / Screen.TwipsPerPixelY
Me.Line (X, Y)-Step(BlockX, BlockY), Me.BackColor, BF
If Quit Then
'Если Выход то...
Form_Unload 0
End If
End Sub

'Таймер обеспечивает рисование на форме и выход если флаг Quit установлен, но перед тем как рисовать необходимо сохранить изображение экрана на форме и "спрятать" мышь:
Private Sub Form_Load()
'Гашение курсора
ShowCursor False
'Чтение установок
If CLng(GetSetting(AppName, Chr$(0), "BackColor", "-1")) = -1 Then
Me.BackColor = GetSysColor(COLOR_BACKGROUND)
Else
Me.BackColor = CLng(GetSetting(AppName, Chr$(0), "BackColor", "0"))
End If
BlockX = CLng(GetSetting(AppName, Chr$(0), "XSize", 16))
BlockY = CLng(GetSetting(AppName, Chr$(0), "YSize", 8))
Timer1.Interval = CLng(GetSetting(AppName, Chr$(0), "Time", "100"))
'Получение описателя рабочего стола
DDC = GetWindowDC(GetDesktopWindow)
'Сохранение экрана на форме
BitBlt Me.hdc, 0, 0, XtoP(Screen.Width), YtoP(Screen.height), DDC, 0, 0, vbSrcCopy
End Sub
'
'При загрузке формы, программа читает из реестра параметры с помощью функций VB и, с помощью Windows API, убирает с экрана курсор мыши(мышь всё равно активна) и сохраняет экран на форме. Все объявления функций API, я разместил в отдельном модуле . Кстати этот модуль отвечает ещё за кое-какие операции, но об этом позже.
'
'Итак у нас есть код для подготовки формы, и код цикла рисования. Но если не установить флаг выхода цикл будет бесконечен. Поэтому используятся события формы MouseMove и KeyDown.
Private Sub Form_MouseMove(Button As Integer, Shift As Integer, _
        X As Single, Y As Single)
'Выход если двигалась мышь
If OldX = 0 Or OldY = 0 Then OldX = X: OldY = Y
If OldX  X Or OldY  Y Then Quit = True
End Sub

Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
Quit = True 'Выход если нажата клавиша
End Sub

'Я думаю особо сложного в этом коде ничего нет. Вот только переменные OldX и OldY я объявил как доступные по всему модулю. Но чтобы эти переменные не сбрасывались при завершении процедуры обработки MouseMove, можно объявить их внутри неё с помощью оператора Static я не использовал его просто потому что он мне не очень нравиться.
'
'Продолжим: флаг Quit у нас устанавливается. Как Вы, надеюсь, помните при этом в цикле таймера вызывается процедура Form_Unload. В этой процедуре, отменяются все установки сделанные при загрузке формы.
Private Sub Form_Unload(Cancel As Integer)
ShowCursor True 'Восстановление курсора
ReleaseDC GetDesktopWindow, DDC 'Освобожление Хэндла экрана
End 'Собственно выход
End Sub

'В итоге получили работающий (во всяком случае у меня) код простенького Хранителя экрана. Но если его сейчас откомпилировать в *.scr файл, получим суррогат, который будет сложно использовать(Если хотите попробуйте выбрать такой "Хранитель" в окне свойств Рабочего стола.
'
'Особенность в том, что при запуске Хранителя экрана Windows передаёт ему параметры запуска в командной строке.
'
'Параметры командной строки передаваемые Windows
'/p - Хранитель экрана выбран в окне свойств рабочего стола. (На "мониторе" в окне должна демонстрироваться заставка)
'/c - Пользователь щёлкнул кнопку настройки параметров Хранителя экрана
'/s - Стандартный запуск, или щелчок по кнопке "Просмотр"
'/a - Пользователь хочет установить пароль.
'
'Именно для того чтобы разбирать тип запуска Хранителя экрана и существует модуль SSaver. (API-функции можно поместить и в код формы.)
Public Sub Main()
If App.PrevInstance Then Exit Sub
Select Case Left(LCase(Trim(Command$)), 2)
Case "/s": frmSSaver.Show
Case "/c": frmProperties.Show
Case Else: End
End Select
End Sub

'В процедуре Main(не забудьте сделать её стартовой) как раз и разбираются эти параметры. Я использовал функцию Left, тем самым проигнорировав оставшиеся символы командной строки. На самом деле эти символы имеют важное значение. К примеру с параметром /p передаётся манипулятор(handle) "монитора" на окне свойств, что позволяет выводить изображение на него.


 '59. Печать RTF
'#########################

'Как вам должно быть известно, то при выводе на печать RTF текста, печать начинается с начала страницы. И ничего с этим не поделаешь? Нет, кое что сделать можно:

в модуль
Public Declare Function GetDeviceCaps Lib "gdi32" (ByVal hdc As Long, _
                              ByVal nIndex As Long) As Long

Public Declare Function SendMessage Lib "user32" _
                                    Alias "SendMessageA" (ByVal hwnd As Long, _
                                    ByVal Msg As Long, ByVal wp As Long, _
                                    lp As Any) As Long

Public Declare Function CreateDC Lib "gdi32" _
                                 Alias "CreateDCA" (ByVal _
                                 lpDriverName As String, _
                                 ByVal lpDeviceName As String, _
                                 ByVal lpOutput As Long, _
                                 ByVal lpInitData As Long) As Long

Public Const WM_USER As Long = &H400
Public Const EM_FORMATRANGE As Long = WM_USER + 57
Public Const EM_SETTARGETDEVICE As Long = WM_USER + 72
Public Const PHYSICALOFFSETX As Long = 112
Public Const PHYSICALOFFSETY As Long = 113

Public Type Rect
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type

Public Type CharRange
cpMin As Long
cpMax As Long
End Type

Public Type FormatRange
hdc As Long
hdcTarget As Long
rc As Rect
rcPage As Rect
chrg As CharRange
End Type

Public Function PrintRichText(RTF As RichTextBox, LeftMarginWidth As Long, _
                              TopMarginHeight, RightMarginWidth, _
                              BottomMarginHeight, Prn)
Dim LeftOffset As Long, TopOffset As Long
Dim LeftMargin As Long, TopMargin As Long
Dim RightMargin As Long, BottomMargin As Long
Dim fr As FormatRange
Dim rcDrawTo As Rect
Dim rcPage As Rect
Dim TextLength As Long
Dim NextCharPosition As Long
Dim r As Long


Prn.Print Space(1)
Prn.ScaleMode = vbTwips


LeftOffset = Prn.ScaleX(GetDeviceCaps(Prn.hdc, _
PHYSICALOFFSETX), vbPixels, vbTwips)
TopOffset = Prn.ScaleY(GetDeviceCaps(Prn.hdc, _
PHYSICALOFFSETY), vbPixels, vbTwips)


LeftMargin = LeftMarginWidth - LeftOffset
TopMargin = TopMarginHeight - TopOffset
RightMargin = (Prn.Width - RightMarginWidth) - LeftOffset
BottomMargin = (Prn.height - BottomMarginHeight) - TopOffset


rcPage.Left = 0
rcPage.Top = 0
rcPage.Right = Prn.ScaleWidth
rcPage.Bottom = Prn.ScaleHeight


rcDrawTo.Left = LeftMargin
rcDrawTo.Top = TopMargin
rcDrawTo.Right = RightMargin
rcDrawTo.Bottom = BottomMargin


fr.hdc = Prn.hdc ' Use the same DC for measuring and rendering
fr.hdcTarget = Prn.hdc ' Point at printer hDC
fr.rc = rcDrawTo ' Indicate the area on page to drawto
fr.rcPage = rcPage ' Indicate entire size of page
fr.chrg.cpMin = 0 ' Indicate start of text through
fr.chrg.cpMax = -1 ' end of the text


TextLength = Len(RTF.Text)


Do
NextCharPosition = SendMessage(RTF.hwnd, EM_FORMATRANGE, True, fr)
If NextCharPosition >= TextLength Then Exit Do 'If done thenexit
fr.chrg.cpMin = NextCharPosition ' Starting position for next Page
Prn.NewPage ' Move on to next page
Prn.Print Space(1) ' Re-initialize hDC
fr.hdc = Prn.hdc
fr.hdcTarget = Prn.hdc
Loop

Prn.EndDoc

r = SendMessage(RTF.hwnd, EM_FORMATRANGE, False, ByVal CLng(0))

End Function


'В форму (Печать текста)
sPrinter = "INSTALLED_Printer_NAME"
'Установленый принтер принтер например: \\GMSVB\PRINTER1 (это у меня)

For i = 0 To Printers.Count - 1
If UCase(Printers(i).Port) = UCase(sPrinter) Then
Set Printer = Printers(i)
PrintRichText RichTexBox, 500, 500, 500, 500, Printer inch. ' В дюймах
Printer.EndDoc
Exit For
End If
Next i

 '60. Печать RTF
'#########################

'Одна из проблематичных частей разработки профессиональнальных приложений в Visual Basic, это добавление в программу возможности печати. С появлением Visual Basic 4 у разработчиков появилась возможность пользоваться новым объектом Printer. Однако, у этого объекта есть серьёзнае недостатки, а именно, невозможно узнать готов принтер к печати или занят, вставлена в него бумага или нет и т.д. Поэтому для получения такой информации можно воспользоваться API функцией GetPrinter.
Private Declare Function GetPrinterApi Lib "winspool.drv" Alias _
       "GetPrinterA" (ByVal hPrinter As Long, _
         ByVal Level As Long, _
         buffer As Long, _
         ByVal pbSize As Long, _
         pbSizeNeeded As Long) As Long

'Используя дескриптор принтера hPrinter она заполняет буфер информацией из драйвера принтера. Чтобы получить дескриптор из объекта Printer, нам необходимо воспользоваться API функцией OpenPrinter.
'Как только мы закончим использовать этот дескриптор, его необходимо освободить при помощи API функции ClosePrinter.
Private Type PRINTER_DEFAULTS
  pDatatype As String
  pDevMode As DEVMODE
  DesiredAccess As Long
End Type

Private Declare Function OpenPrinter Lib "winspool.drv" _
    Alias "OpenPrinterA" (ByVal pPrinterName As String, _
    phPrinter As Long, pDefault As PRINTER_DEFAULTS) As Long

Private Declare Function ClosePrinter Lib "winspool.drv" _
    (ByVal hPrinter As Long) As Long

'А вот как выглядит код получения дескриптора принтера.
Dim lret As Long
Dim pDef As PRINTER_DEFAULTS

lret = OpenPrinter(Printer.DeviceName, mhPrinter, pDef)
' Различные состояния принтера
'
'Драйвер принтера может вернуть различные стандартные состояния принтера.
Public Enum Printer_Status
   PRINTER_STATUS_READY = &H0
   PRINTER_STATUS_PAUSED = &H1
   PRINTER_STATUS_ERROR = &H2
   PRINTER_STATUS_PENDING_DELETION = &H4
   PRINTER_STATUS_PAPER_JAM = &H8
   PRINTER_STATUS_PAPER_OUT = &H10
   PRINTER_STATUS_MANUAL_FEED = &H20
   PRINTER_STATUS_PAPER_PROBLEM = &H40
   PRINTER_STATUS_OFFLINE = &H80
   PRINTER_STATUS_IO_ACTIVE = &H100
   PRINTER_STATUS_BUSY = &H200
   PRINTER_STATUS_PRINTING = &H400
   PRINTER_STATUS_OUTPUT_BIN_FULL = &H800
   PRINTER_STATUS_NOT_AVAILABLE = &H1000
   PRINTER_STATUS_WAITING = &H2000
   PRINTER_STATUS_PROCESSING = &H4000
   PRINTER_STATUS_INITIALIZING = &H8000
   PRINTER_STATUS_WARMING_UP = &H10000
   PRINTER_STATUS_TONER_LOW = &H20000
   PRINTER_STATUS_NO_TONER = &H40000
   PRINTER_STATUS_PAGE_PUNT = &H80000
   PRINTER_STATUS_USER_INTERVENTION = &H100000
   PRINTER_STATUS_OUT_OF_MEMORY = &H200000
   PRINTER_STATUS_DOOR_OPEN = &H400000
   PRINTER_STATUS_SERVER_UNKNOWN = &H800000
   PRINTER_STATUS_POWER_SAVE = &H1000000
End Enum

'Существуют несколько разных структур данных, которые возвращает драйвер принтера (в Windows 2000, например, их девять штук), однако только две первые являются наиболее универсальными и подходят для всех версий Windows. Из них вторая является наиболее интересной для нас (PRINTER_INFO_2)
Private Type PRINTER_INFO_2
   pServerName As String
   pPrinterName As String
   pShareName As String
   pPortName As String
   pDriverName As String
   pComment As String
   pLocation As String
   pDevMode As Long
   pSepFile As String
   pPrintProcessor As String
   pDatatype As String
   pParameters As String
   pSecurityDescriptor As Long
   Attributes As Long
   Priority As Long
   DefaultPriority As Long
   StartTime As Long
   UntilTime As Long
   Status As Long
   JobsCount As Long
   AveragePPM As Long
End Type

'Однако, не достаточно просто передать эту структуру в API функцию GetPrinter, так как принтер может вернуть больше информации, чем размер структуры. Поэтому, если не зарезервировать достаточного буфера для неё, программа может "выполнить недопустимую оперцию".
'К счастью, сама функция GetPrinter позволяет узнать необходимый объём буфера для структуры. Для этого достаточно передать ноль в параметре pbSize, тогда функция вернёт размер требуемого буфера в pbSizeNeeded.
'Таким образом, получение информации из драйвера принтера состоит из двух этапов:
  Dim lret As Long
  Dim SizeNeeded As Long

  Dim buffer() As Long

  ReDim Preserve buffer(0 To 1) As Long
  lret = GetPrinterApi(mhPrinter, Index, buffer(0), UBound(buffer), SizeNeeded)
  ReDim Preserve buffer(0 To (SizeNeeded / 4) + 3) As Long
  lret = GetPrinterApi(mhPrinter, Index, buffer(0), UBound(buffer) * 4, SizeNeeded)

'Однако, мы выделили буфер значений Long, а некоторые значения в структуре PRINTER_INFO_2 имеют тип данных String. Поэтому, необходимо получить эти строковые данные из соответствущих адресов буфера.
'Для получения строки по указанному адресу, используется API функция CopyMemory. Текже существует API функция IsBadStringPtr, которая используется для проверки того, что по указанному адресу содержится допустимая строка.
' Функции работы с памятью
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
' Проверка указателя в StringFromPointer
Private Declare Function IsBadStringPtrByLong Lib "kernel32" Alias "IsBadStringPtrA" (ByVal lpsz As Long, ByVal ucchMax As Long) As Long

'Получение строки по указателю, это обычная вещь, поэтому такую функцию нужно всегда иметь в своём арсенале.
Public Function StringFromPointer(lpString As Long, lMaxLength As Long) As String

  Dim sRet As String
  Dim lret As Long

  If lpString = 0 Then
    StringFromPointer = ""
    Exit Function
  End If

  If IsBadStringPtrByLong(lpString, lMaxLength) Then
    ' Ошибка - данный указатель нельзя использовать
      StringFromPointer = ""
    Exit Function
  End If

  ' Подготовка к получению строки...
  sRet = Space$(lMaxLength)
  CopyMemory ByVal sRet, ByVal lpString, ByVal Len(sRet)
  If Err.LastDllError = 0 Then
    If InStr(sRet, Chr$(0)) > 0 Then
      sRet = Left$(sRet, InStr(sRet, Chr$(0)) - 1)
    End If
  End If

  StringFromPointer = sRet

End Function

'А теперь используем эту функцию, чтобы заполнить нашу переменную PRINTER_INFO_2:
With mPRINTER_INFO_2 ' Эта переменная типа PRINTER_INFO_2
   .pServerName = StringFromPointer(buffer(0), 1024)
   .pPrinterName = StringFromPointer(buffer(1), 1024)
   .pShareName = StringFromPointer(buffer(2), 1024)
   .pPortName = StringFromPointer(buffer(3), 1024)
   .pDriverName = StringFromPointer(buffer(4), 1024)
   .pComment = StringFromPointer(buffer(5), 1024)
   .pLocation = StringFromPointer(buffer(6), 1024)
   .pDevMode = buffer(7)
   .pSepFile = StringFromPointer(buffer(8), 1024)
   .pPrintProcessor = StringFromPointer(buffer(9), 1024)
   .pDatatype = StringFromPointer(buffer(10), 1024)
   .pParameters = StringFromPointer(buffer(11), 1024)
   .pSecurityDescriptor = buffer(12)
   .Attributes = buffer(13)
   .Priority = buffer(14)
   .DefaultPriority = buffer(15)
   .StartTime = buffer(16)
   .UntilTime = buffer(17)
   .Status = buffer(18)
   .JobsCount = buffer(19)
   .AveragePPM = buffer(20)
End With

 '61. Извлечение иконок
'#########################

'Нам Понадобятся:
Command Button - Command1
TextBox -Text1
PictureBox -Picture1
'А также для удобства брауза файлов CommonDialog - CD1
Option Explicit
Private Declare Function ExtractAssociatedIcon Lib "shell32.dll" Alias _
"ExtractAssociatedIconA" (ByVal hInst As Long, _
ByVal lpIconPath As String, lpiIcon As Long) As Long
Private Declare Function DrawIcon Lib "user32" (ByVal hdc As Long, _
ByVal X As Long, ByVal Y As Long, ByVal hIcon As Long) As Long
Private Declare Function DestroyIcon Lib "user32" _
(ByVal hIcon As Long) As Long

Private Type Rect
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type

'Разные Функции
Private Declare Function BitBlt Lib "gdi32" _
  (ByVal hDestDC As Long, ByVal X As Long, ByVal Y As Long, _
   ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, _
   ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
Private Const SRCCOPY = &HCC0020
Private Declare Function CreateCompatibleDC Lib "gdi32" _
  (ByVal hdc As Long) As Long
Private Declare Function CreateCompatibleBitmap Lib "gdi32" _
  (ByVal hdc As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long
Private Declare Function SelectObject Lib "gdi32" _
  (ByVal hdc As Long, ByVal hObject As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" _
  (ByVal hObject As Long) As Long
Private Declare Function OpenClipboard Lib "user32" _
  (ByVal hwnd As Long) As Long
Private Declare Function CloseClipboard Lib "user32" _
  () As Long
Private Declare Function SetClipboardData Lib "user32" _
  (ByVal wFormat As Long, ByVal hMem As Long) As Long
Private Declare Function EmptyClipboard Lib "user32" _
  () As Long
Private Const CF_BITMAP = 2

Private Sub Command1_Click()
CD1.ShowOpen 'Открываем Брауз
Text1.Text = CD1.FileName 'Присваеваем Тексту Путь и Имя Файла
Picture1.Cls 'Очищаем Картинку От Старой Иконки
Dim sPath As String, hIcon As Long, nIcon As Long 'Присваеваем Переменные
sPath = Text1.Text 'Берем путь из Текста
'Забираем Верхнюю Иконку
hIcon = ExtractAssociatedIcon(App.hInstance, sPath, nIcon)
DrawIcon Picture1.hdc, 0&, 0&, hIcon 'Вставляем иконку в PictureBox
DestroyIcon hIcon 'Берём Иконку
CopyEntirePicture Picture1 'Вставляем иконку в буфер обмена.

'Теперь Можно Вставлять Иконку Хоть Куда
End Sub

'Функция Тута (Копирование Рисунка)
Public Function CopyEntirePicture(ByRef objFrom As Object) As Boolean
Dim lhDC As Long
Dim lhBMP As Long
Dim lhBMPOld As Long
Dim lWidthPixels As Long
Dim lHeightPixels As Long
lhDC = CreateCompatibleDC(objFrom.hdc)
If (lhDC  0) Then
lWidthPixels = objFrom.ScaleX(objFrom.ScaleWidth, objFrom.ScaleMode, vbPixels)
lHeightPixels = objFrom.ScaleY(objFrom.ScaleHeight, objFrom.ScaleMode, vbPixels)
lhBMP = CreateCompatibleBitmap(objFrom.hdc, lWidthPixels, lHeightPixels)
If (lhBMP  0) Then
lhBMPOld = SelectObject(lhDC, lhBMP)
BitBlt lhDC, 0, 0, lWidthPixels, lHeightPixels, objFrom.hdc, 0, 0, SRCCOPY
SelectObject lhDC, lhBMPOld
OpenClipboard 0
EmptyClipboard
SetClipboardData CF_BITMAP, lhBMP
CloseClipboard
End If

DeleteObject lhDC
End If
End Function


 '61. смениа системных параметров: десятичный разделитель и разделитель в дате
'#########################

Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, _
 ByVal wMsg As Long, _
 ByVal wParam As Long, _
 LParam As Any) _
 As Long
 
 Const WM_WININICHANGE = &H1A
 Const HWND_BROADCAST = &HFFFF

' Обычными файловыми операциями ищешь в win.ini (раздел [intl]) строки:

' sDate=.
' sDecimal=.

' Меняешь точки на что надобно, потом запускаешь:
 r = SendMessage(HWND_BROADCAST, WM_WININICHANGE, 0, ByVal "windows")


 '62. Сохранить картинку в буфере в файл.
'#########################

' Checks the clipboard for a bitmap
' If found, creates a standard Picture object from the
' clipboard contetnts and saves it to a file

' The code requires a reference to the "OLE Automation" type library

' The code in this module has been derived primarily from _
' the PatsePicture sample on Stephen Bullen's Excel Page _
' - http://www.bmsltd.ie/Excel/Default.htm

'Windows API Function Declarations
Private Declare Function IsClipboardFormatAvailable Lib "user32" (ByVal wFormat As Integer) As Long
Private Declare Function OpenClipboard Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function GetClipboardData Lib "user32" (ByVal wFormat As Integer) As Long
Private Declare Function CloseClipboard Lib "user32" () As Long
Private Declare Function OleCreatePictureIndirect Lib "olepro32.dll" (PicDesc As uPicDesc, RefIID As GUID, ByVal fPictureOwnsHandle _
As Long, IPic As IPicture) As Long
Private Declare Function CopyImage Lib "user32" (ByVal handle As Long, _
ByVal un1 As Long, ByVal n1 As Long, ByVal n2 As Long, _
ByVal un2 As Long) As Long

'The API format types we need
Const CF_BITMAP = 2
Const IMAGE_BITMAP = 0
Const LR_COPYRETURNORG = &H4


'Declare a UDT to store a GUID for the IPicture OLE Interface
Private Type GUID
  Data1 As Long
  Data2 As Integer
  Data3 As Integer
  Data4(0 To 7) As Byte
End Type

'Declare a UDT to store the bitmap information
Private Type uPicDesc
  Size As Long
  Type As Long
  hPic As Long
  hPal As Long
End Type

Public Function Clip2File()
  
  Dim strOutputPath As String, oPic As IPictureDisp
  
  'Get the filename to save the bitmap to
  strOutputPath = Environ("TEMP") & "\temp.bmp"
  
  'Retrieve the picture from the clipboard...
  Set oPic = GetClipPicture()
  
  '... and save it to the file
  If Not oPic Is Nothing Then
    SavePicture oPic, strOutputPath
    Clip2File = strOutputPath
  Else
    Clip2File = ""
    MsgBox "Unable to retrieve bitmap from clipboard"
  End If
End Function

Function GetClipPicture() As IPicture
  
  Dim h As Long, hPicAvail As Long, hPtr As Long, _
  hPal As Long, hCopy As Long
  
  'Check if the clipboard contains a bitmap
  hPicAvail = IsClipboardFormatAvailable(CF_BITMAP)
  
  If hPicAvail  0 Then
    'Get access to the clipboard
    h = OpenClipboard(0&)
    If h > 0 Then
      'Get a handle to the image data
      hPtr = GetClipboardData(CF_BITMAP)
      hCopy = CopyImage(hPtr, IMAGE_BITMAP, 0, 0, LR_COPYRETURNORG)
      'Release the clipboard to other programs
      h = CloseClipboard
      'If we got a handle to the image, convert it into _
      'a Picture object and return it
      If hPtr  0 Then Set GetClipPicture = CreatePicture(hCopy, _
        0, CF_BITMAP)
    End If
  End If
  
End Function

Private Function CreatePicture(ByVal hPic As Long, ByVal hPal As Long, _
ByVal lPicType) As IPicture
  
  ' IPicture requires a reference to "OLE Automation"
  Dim r As Long, uPicInfo As uPicDesc, IID_IDispatch As GUID, _
  IPic As IPicture
  
  'OLE Picture types
  Const PICTYPE_BITMAP = 1
  
  ' Create the Interface GUID (for the IPicture interface)
  With IID_IDispatch
    .Data1 = &H7BF80980
    .Data2 = &HBF32
    .Data3 = &H101A
    .Data4(0) = &H8B
    .Data4(1) = &HBB
    .Data4(2) = &H0
    .Data4(3) = &HAA
    .Data4(4) = &H0
    .Data4(5) = &H30
    .Data4(6) = &HC
    .Data4(7) = &HAB
  End With
  
  ' Fill uPicInfo with necessary parts.
  With uPicInfo
    .Size = Len(uPicInfo) ' Length of structure.
    .Type = PICTYPE_BITMAP ' Type of Picture
    .hPic = hPic ' Handle to image.
    .hPal = 0 ' Handle to palette (if bitmap).
  End With
  
  ' Create the Picture object.
  r = OleCreatePictureIndirect(uPicInfo, IID_IDispatch, True, IPic)
  
  ' Return the new Picture object.
  Set CreatePicture = IPic
  
End Function

'Win API позволяющая задать прозрачность окна
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" _
(ByVal hwnd As Long, ByVal nIndex As Long) As Long

Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
(ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long

Private Declare Function SetLayeredWindowAttributes Lib "user32" (ByVal hwnd As Long, _
ByVal crKey As Long, ByVal bAlpha As Byte, ByVal dwFlags As Long) As Long


Private Const LWA_COLORKEY = &H1
Private Const LWA_ALPHA = &H2
Private Const GWL_EXSTYLE = (-20)
Private Const WS_EX_LAYERED = &H80000

' Layered - степень прозрачности 0-255
' Примечание: форма должна быть всплывающей
Public Sub TransparentForm(hwnd As Long, Layered As Byte)
    Dim ret As Long
    ret = GetWindowLong(hwnd, GWL_EXSTYLE)
    ret = ret Or WS_EX_LAYERED
    SetWindowLong hwnd, GWL_EXSTYLE, ret
    SetLayeredWindowAttributes hwnd, 0, Layered, LWA_ALPHA
End Sub
'вызывается
TransparentForm Me.hwnd, 230

Добавить комментарий

Ваш адрес email не будет опубликован.