Свойства выделяемого блока памяти

Макрос Значение
GHND Блок может передвигаться и заполняется нулями
GMEM_DDESHARE Память может употребляться для операций c буфером обмена
GMEM_DISCARDABLE Память может быть выгружена
GMEM_LOWER Память не перемещается
GMEM_NOCOMPACT Блок может передвигаться в памяти
Блок не может изменять размер при операциях сборки мусора
GMEM_NODISCARD Блок Свойства выделяемого блока памяти не может быть выгружен
GMEM_SHARE To же, что и GMEM_DDESHARE
GMEM_ZEROINIT Выделенный блок памяти заполняется нулями
GPTR Блок памяти не может передвигаться и заполняется нулями

Память, выделенная с помощью функции GlobalAlloc(),становится глобальным системным объектом. Память, выделяемая для использования в буфере обмена, должна быть перемещаемой и разделяемой.

Как уже Свойства выделяемого блока памяти упоминалось, функция GlobalAlloc() возвращает дескриптор, а не указа­тель на выделенную память. Для получения указателя на область памяти, выделенную с помощью GlobalAlloc(), следует использовать функцию GlobalLock():

LPVOID GlobalLock(HGLOBAL hObj);

Функция GlobalLock() фиксирует в памяти объект (блок), дескриптор которого передается в параметре hObj. Зафиксированный объект не перемещается в памяти Свойства выделяемого блока памяти и не выгружается. Функция GlobalLock() возвращает адресок начала блока в случае удачного окончания либо NULL при появлении ошибки. Чтоб выполнить воззвание к глобальным блокам памяти, эти блоки необходимо непременно зафиксиро­вать. Таким макаром, вызов функции GlobalLock() – это метод получения указателя на блок глобальной памяти. Фиксация блока также защищает память Свойства выделяемого блока памяти от обраще­ния к ней других программ, пока с этой памятью работает Ваша программка.

После получения указателя на глобальный блок памяти нужно скопировать в этот блок данные, которые Вы желаете поместить в буфер обмена. Когда копирование закончится, блок памяти можно разблокировать, вызвав функцию GlobalUnlock():

BOOL GlobalUnlock(HGLOBAL Свойства выделяемого блока памяти hObj);

Функция GlobalUnlock()возвращает нулевое значение в случае удачного завер­шения и ненулевое при появлении ошибки. Дескриптор разблокируемого объек­та передается в параметре hObj.

После копирования данных в глобальный блок памяти необходимо открыть буфер обмена с помощью вызова функции OpenClipboard():

BOOL OpenClipboard(HWND hWnd) ;

Функция OpenClipboard()разрешает вызывающей Свойства выделяемого блока памяти программке доступ к буферу обмена (т.е. открывает его). После того как программка открыла буфер обмена, другие приложения использовать его не могут. Функция возвращает ненулевое значение, если буфер обмена удачно открыт, и нуль, если на этот момент буфер открыть нереально. Параметр hWnd задает дескриптор окна, открывающего буфер обмена.

Когда Свойства выделяемого блока памяти буфер обмена удачно открыт, приложение должно очистить буфер обмена, вызвав функцию EmptyClipboard():

BOOL EmptyClipboard(void);

Функция EmptyClipboard() уничтожает всю ранее хранившуюся в буфере обмена информацию, освобождая все выделенные блоки памяти, и предоставляет буфер обмена текущему приложению. Перед вызовом этой функции буфер обмена должен быть открыт. Функция возвращает ненулевое значение в случае удачного Свойства выделяемого блока памяти заверше­ния и нуль при появлении ошибки.

Чтоб записать данные в буфер обмена, его следует настроить на память, содержа­щую эти данные. Это делается с помощью вызова функции SetClipboardData():

HANDLE SetClipboardData(UINT Format, HANDLE hData);

Функция SetClipboardData() настраивает буфер обмена на внедрение глобаль­ной памяти, дескриптор Свойства выделяемого блока памяти которой указывается в параметре hData. Она возвращает новый дескриптор памяти, на которую настроен буфер обмена, или NULL в случае появления ошибки.

Формат данных, записываемых в буфер обмена, задается параметром Format. Этот параметр может принимать предопределенные значения из таблицы 13.5, или задавать свой формат данных юзера.

Таблица 13.5

Форматы и типы данных

Формат Тип данных
CF Свойства выделяемого блока памяти_BITMAP Растр (bitmap) в чистом виде
CF_DIB Растр (bitmap) с заголовком BITMAPINFO
CF_DIF Универсальный формат обмена (Data Interchange Format)
CF_DSPBITMAP Пользовательское растровое изображение
CF_DSPENHMETAFILE Пользовательский расширенный метафайл
CF_DSPMETAFILEPICT Пользовательский метафайл
CF_DSPTEXT Пользовательский текст
С F_ENHMETAFILE Расширенный метафайл
CF_METAFILEPICT Метафайл Свойства выделяемого блока памяти в стиле METAFILEPICT
CF_OEMTEXT Текст в шифровке OEM
CF_OWNERDISPLAY Пользовательский формат данных
CF_PALETTE Палитра цветов
CF_PENDATA Формат для данных, связанных с электрическим пером
CF_RIFF Файл ресурсов (Resource Interchange File Format)
CF_SYLK Символическая ссылка
CF_TEXT Текст
CF_TIFF Графика в формате TIFF
CF_WAVE Звук Свойства выделяемого блока памяти в формате WAVE
CF_UNICODETEXT Текст в шифровке UNICODE


Для форматов CF_TEXT, CF_OEMTEXT и CF_UNICODETEXT текстовые блоки должны заканчиваться нулевым эмблемой, а строчки – композицией CR/LF – «возврат каретки»/«новая строка». Значения в спектре от CF_PRTVATEFIRST до CF_PRIVATELAST резервируются для локальных пользовательских форматов данных, а Свойства выделяемого блока памяти значе­ния в спектре от CF_GDIOBJFIRST до CF_GDIOBJLAST – для пользовательских графических объектов.

После записи данных программка должна сразу высвободить буфер обмена с помощью функции CloseClipboard():

BOOL CloseClipboard (void);

Эта функция возвращает ненулевое значение в случае удачного окончания и нуль при появлении ошибки.

Чтение данных аз буфера Свойства выделяемого блока памяти обмена. Для чтения данных из буфера обмена употребляется последующая процедура, состоящая из 4 шагов:

1) открыть буфер обмена;

2) получить указатель на данные, записанные в буфер обмена;

3) скопировать данные из буфера обмена;

4) закрыть буфер обмена.

Перечисленные шаги производятся в последующем куске программки:

if(OpenClipboard(hwnd))

{

hGin=GetClipboardData(CF_TEXT);

p Свойства выделяемого блока памяти=(char*)GlobalLock(hGin);

//

// Операторы копирования данных

// из глобальной памяти

//

GlobalUnlock(hGin);

CloseClipboard();

}

Чтоб получить доступ к данным, хранящимся в буфере обмена, последний должен быть открыт. После чего необходимо получить дескриптор глобальной памяти, в какой хранятся данные хбуфера обмена. Это делается с помощью функции GetClipboardData():

HANDLE GetClipboardData(UINT Format);

Функция GetClipboardData() возвращает дескриптор глобальной Свойства выделяемого блока памяти памяти, содер­жащей информацию в данном формате. Требуемый формат данных задается в параметре Format. Если в буфере обмена к моменту запроса нет данных, имеющих требуемый формат, функция возвращает значение NULL. В приведенном куске программки запрашиваемый формат данных CF_TEXT.Для получения указателя по дескриптору, возвращаемому функцией GetClipboardData Свойства выделяемого блока памяти(), употребляется функция GlobalLock(),описанная выше.

Сейчас программка должна скопировать данные из памяти буфера обмена в свой локальный буфер. Так как функция GetClipboardData()возвращает дескриптор памяти, на которую настроен буфер обмена, программка должна скопи­ровать данные до того, как управление будет возвращено Windows. Причину этого просто осознать: после возврата управления Windows содержимое буфера Свойства выделяемого блока памяти обмена может быть изменено другим приложением.

Пример 13-3. Программка работы с буфером обмена Clipboard

Приведенная ниже программка показывает доступ к буферу обмена: она записывает данные в этот буфер и читает их. Профамма создана для чтения только текстовых данных, хотя ее можно видоизменять таким макаром, чтоб она могла читать данные Свойства выделяемого блока памяти и других форматов. Программка записывает текст в буфер обмена по команде меню Записать в буфери читает данные по команде Прочитать из буфера.В буфер обмена можно также записать блок текста из другой программки (редактора текста) и потом прочитать его с помощью данной программки.

// Демонстрация работы с буфером обмена Clipboard

#include

#include Свойства выделяемого блока памяти

#include "Clip.h"

#define Maxsize 100

LRESULT CALLBACK WindowFunc(HWND, UINT,

WPARAM, LPARAM);

char szWinName[]="МоеОкно"; // Имя класса окна

HGLOBAL hGout, hGin;

char text[]="Это текст для буфера обмена";

int WINAPI WinMain(HINSTANCE hThisInst,

HINSTANCE hPrevInst,

LPSTR lpszArgs,

int nWinMode)

{

HWND hwnd;

MSG msg;

HACCEL hAccel; // Для обработки акселераторов

WNDCLASS Свойства выделяемого блока памяти wcl; // Найти класс окна

wcl.hInstance=hThisInst; // Дескриптор приложения

wcl.lpszClassName=szWinName; // Имя класса окна

wcl.lpfnWndProc=WindowFunc; // Функция окна

wcl.style=0; // Стиль по дефлоту

wcl.hIcon=LoadIcon(NULL,IDI_APPLICATION); // Иконка

wcl.hCursor=LoadCursor(NULL,IDC_ARROW); // Курсор

wcl.lpszMenuName="Mymenu"; // Главное меню

wcl.cbClsExtra=0; // Без дополнительной инфы

wcl.cbWndExtra=0;

wcl.hbrBackground=

(HBRUSH)GetStockObject(WHITE_BRUSH); //Белоснежный фон

if(!RegisterClass(&wcl Свойства выделяемого блока памяти)) // Регистрируем класс окна

return 0;

hwnd=CreateWindow(szWinName, // Сделать окно

"Работа с буфером обмена Clipboard ",

WS_OVERLAPPEDWINDOW, // Стиль окна

CW_USEDEFAULT, // x-координата

CW_USEDEFAULT, // y-координата

CW_USEDEFAULT, // Ширина

CW_USEDEFAULT, // Высота

HWND_DESKTOP, // Нет родител. окна

NULL, // Нет меню

hThisInst,// Дескриптор приложения

NULL); // Нет дополнит. аргументов

ShowWindow (hwnd, nWinMode); // Показать окно

UpdateWindow (hwnd); // и перерисовать

hAccel=LoadAccelerators(hThisInst,"Mymenu Свойства выделяемого блока памяти");

// Загрузить акселераторы

while(GetMessage(&msg,NULL,0,0))

if(!TranslateAccelerator(hwnd,hAccel,&msg))

{

TranslateMessage(&msg); // Исполь. клавиатуру

DispatchMessage (&msg); // Возврат к Windows

}

return msg.wParam;

}

// Последующая функция вызывается операционной

// системой Windows и получает в качестве

// характеристик сообщения из очереди сообщений

// данного приложения

LRESULT CALLBACK WindowFunc(HWND hwnd,

UINT message,

WPARAM wParam,

LPARAM lParam)

{

int i;

char *p;

char Свойства выделяемого блока памяти str[255];

switch(message)

{

case WM_COMMAND:

switch(LOWORD(wParam))

{

case ID_OUTTOCLIP:

hGout=GlobalAlloc(GHND|GMEM_DDESHARE,

(DWORD)Maxsize);

p=(char*)GlobalLock(hGout);

strcpy(p,text); // Копирование текста

// в глобальную память

GlobalUnlock (hGout);

if(OpenClipboard(hwnd))

{

EmptyClipboard();

SetClipboardData(CF_TEXT,hGout);

CloseClipboard();

MessageBox(hwnd, text,

"Записано в буфер обмена",

MB_OK);

}

break;

case Свойства выделяемого блока памяти ID_READFROMCLIP:

if(OpenClipboard(hwnd))

{

hGin=GetClipboardData(CF_TEXT);

p=(char*)GlobalLock(hGin);

// Начинаем копировать текст

// из глобальной памяти */

for(i=0; i

str[i]= *p++;

str[i]= '\0'; // конец строчки

// Окончили копировать текст

GlobalUnlock(hGin);

CloseClipboard();

MessageBox(hwnd, text,

"Прочитано из буфера обмена",

MB_OK);

}

}

break;

case WM_DESTROY: // Окончание программки

PostQuitMessage Свойства выделяемого блока памяти(0);

break;

default:

// Все сообщения, не обрабатываемые в

// данной функции, направляются на обработку

// по дефлоту

return DefWindowProc(hwnd,message,

wParam,lParam);

}

return 0;

}

Для этой программки нужен последующий файл ресурсов Clipboard.rc:

#include

#include "Clip.h"

MYMENU MENU

{

POPUP "Данные"

{

MENUITEM "Записать в буфер", ID_OUTTOCLIP

MENUITEM "Прочитать из буфера",ID_READFROMCLIP

}

}

MYMENU ACCELERATORS

{

VK_F1, ID_OUTTOCLIP, VIRTKEY

VK Свойства выделяемого блока памяти_F2, ID_READFROMCLIP, VIRTKEY

}

Не считая того, будет нужно файл определений Clip.h:

#define ID_OUTTOCLIP 101

#define ID_READFROMCLIP 102


Работу этой программки иллюстрирует рис. 13.3.

Рис. 13.3. Пример работы с буфером обмена Clipboard

Литература

1. Емельянов А.А., Власова Е.А., Денисов Д.В., Емельянова Н.З. Базы программирования для информатиков и инженеров. Часть 1: Алгоритмизация Свойства выделяемого блока памяти и программирование на языке «С». – М.: ММИЭИФП, 2004. – 208 с.

2. Керниган Б., Ритчи Д. Язык программирования Си. – М.: Деньги и статистика, 2001. – 352 с.

3. Круглински Д. Дж., Уингоу С., Шеферд Дж. Программирование на Microsoft Visual С++ 6.0 для экспертов. – СПб.: Питер; М.: Российская редакция, 2001. – 864 с.

4. Крупник А.Б. Изучаем Си. – СПб.: Питер, 2002. – 256 с Свойства выделяемого блока памяти.

5. Крупник А.Б. Изучаем С++. – СПб.: Питер, 2002. – 251 с.

6. Ламот А. Программирование игр для Windows: советы специалиста. – М.: Издательский дом «Вильямс», 2004. – 880 с.

7. Шилдт Г. Программирование на С и С++ для Windows. – К.: Торгово-издательское бюро BHV, 2001. – 408 с.


* Селекторные кнопки время от времени именуют «радиокнопками» (Прим. ред.)

* Если в папке уже Свойства выделяемого блока памяти есть файл с таким именованием, то нужно держать в голове, что его старенькое содержимое после сохранения будет потеряно, если не принять особых мер по сохранению запасной копии


svojstva-teplovogo-izlucheniya.html
svojstva-trapecii.html
svojstva-videlyaemogo-bloka-pamyati.html