Понадобилось помещать физический файл на диске в буфер обмена.
На форуме не нашел как это сделать.
Задал вопрос ИИ DeepSeek'у.
Получил его фантазии по этому поводу:
Код: Выделить всё
 PROGRAM
  MAP
    INCLUDE('CWINDOWS.INC')   ! Windows API константы и типы
    INCLUDE('CSHELL.INC')     ! Для Shell API (CF_HDROP)
  END
CopyFileToClipboard PROCEDURE(STRING filePath), BOOL
IsFileExists       PROCEDURE(STRING filePath), BOOL
  ! Объявление внешних Windows API функций
KERNEL32 API(GlobalAlloc), ULONG, DLL, NAME('GlobalAlloc'), RAW
           ULONG(uFlags), ULONG(dwBytes)
KERNEL32 API(GlobalLock), PTR, DLL, NAME('GlobalLock'), RAW
           ULONG(hMem)
KERNEL32 API(GlobalUnlock), BOOL, DLL, NAME('GlobalUnlock'), RAW
           ULONG(hMem)
KERNEL32 API(GlobalFree), ULONG, DLL, NAME('GlobalFree'), RAW
           ULONG(hMem)
USER32   API(OpenClipboard), BOOL, DLL, NAME('OpenClipboard'), RAW
           ULONG(hWndNewOwner)
USER32   API(EmptyClipboard), BOOL, DLL, NAME('EmptyClipboard'), RAW
USER32   API(SetClipboardData), PTR, DLL, NAME('SetClipboardData'), RAW
           ULONG(uFormat), ULONG(hMem)
USER32   API(CloseClipboard), BOOL, DLL, NAME('CloseClipboard'), RAW
  CODE
  ! Пример использования:
  filePath CSTRING(260) ! Максимальная длина пути в Windows
  filePath = 'C:\test\file.txt' ! Путь к файлу (можно ввести динамически)
  
  IF SELF.CopyFileToClipboard(filePath)
    MESSAGE('Файл скопирован в буфер обмена!')
  ELSE
    MESSAGE('Ошибка копирования файла в буфер обмена!')
  END
! Проверка существования файла
IsFileExists PROCEDURE(STRING filePath)
  CODE
  RETURN (GetFileAttributesA(filePath) <> 0FFFFFFFFh) ! INVALID_FILE_ATTRIBUTES
! Основная функция копирования файла в буфер обмена (ANSI-версия)
CopyFileToClipboard PROCEDURE(STRING filePath)
hMem        ULONG
pDropFiles  &DROPFILES
pFilePath   &CSTRING
filePathLen ULONG
dropFilesSize ULONG
success     BOOL(FALSE)
  CODE
  IF ~SELF.IsFileExists(filePath) THEN RETURN FALSE.
  ! Открываем буфер обмена
  IF ~API(OpenClipboard, 0) THEN RETURN FALSE.
  API(EmptyClipboard)
  ! Вычисляем размер данных (ANSI)
  filePathLen = LEN(CLIP(filePath)) + 1   ! +1 для нуль-терминатора
  dropFilesSize = SIZE(DROPFILES) + (filePathLen + 1)  ! +1 для двойного нуль-терминатора
  ! Выделяем память
  hMem = API(GlobalAlloc, GHND | GMEM_SHARE, dropFilesSize)
  IF hMem = 0 THEN 
    API(CloseClipboard)
    RETURN FALSE.
  END
  ! Блокируем память
  pDropFiles = API(GlobalLock, hMem)
  IF pDropFiles = 0 THEN
    API(GlobalFree, hMem)
    API(CloseClipboard)
    RETURN FALSE.
  END
  ! Заполняем структуру DROPFILES (ANSI)
  pDropFiles.pFiles = SIZE(DROPFILES)  ! Смещение к списку файлов
  pDropFiles.pt.x = 0
  pDropFiles.pt.y = 0
  pDropFiles.fNC = FALSE
  pDropFiles.fWide = FALSE             ! ANSI (не Unicode)
  ! Копируем путь к файлу (ANSI)
  pFilePath = pDropFiles + SIZE(DROPFILES)
  pFilePath = filePath
  ! Добавляем второй нуль-терминатор (для списка файлов)
  pFilePath[filePathLen] = 0
  ! Разблокируем память
  API(GlobalUnlock, hMem)
  ! Помещаем данные в буфер обмена
  IF API(SetClipboardData, CF_HDROP, hMem) THEN 
    success = TRUE
  ELSE
    API(GlobalFree, hMem)
  END
  ! Закрываем буфер обмена
  API(CloseClipboard)
  RETURN success
