11.04.2014 Views

Advanced MFC Programming

Advanced MFC Programming

Advanced MFC Programming

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Chapter 9. Font<br />

GHND<br />

GPTR<br />

Same with GMEM_MOVEABLE | GMEM_ZEROINIT<br />

Same with GMEM_FIXED | GMEM_ZEROINIT<br />

The most commonly used flag is GHND, which specifies that the memory block should be movable and<br />

all buffers should be initialized to zeros. For the clipboard usage, we also need to specify flag GMEM_SHARE,<br />

which will enhance the performance of clipboard operation.<br />

Actually, in Win32 programming, the memory block allocated by one process can not be shared by<br />

other processes. Flag GMEM_SHARE exists just for the backward compatibility purpose. For a general<br />

application, we can not allocate a block of memory using flag GMEM_SHARE and share it with other<br />

applications. In Win32, this flag is solely used for clipboard and DDE (see chapter 15) implementation.<br />

The memory size that will be allocated is specified by dwBytes parameter of function<br />

::GlobalAlloc(…).<br />

Apart from these functions, there is another set of functions whose functionality is exactly the same,<br />

the only difference is that they have a different set of function names:<br />

HLOCAL ::LocalAlloc(UINT uFlags, UINT uBytes);<br />

LPVOID ::LocalLock(HLOCAL hMem);<br />

HLOCAL ::LocalReAlloc(HLOCAL hMem, UINT uBytes, UINT uFlags);<br />

BOOL ::LocalUnlock(HLOCAL hMem);<br />

HLOCAL ::LocalFree(HLOCAL hMem);<br />

Everything is exactly the same except that all the “Global” keywords are changed to “Local” here.<br />

These functions are originated from the old Win16 programming, which uses 16-bit memory mode. In that<br />

case the memory can be allocated either from the local heap or global heap. In Win32 programming, there<br />

is only one heap, so two sets of functions become exactly the same. They exist just for the compatibility<br />

purpose. We can use either of them in our program. We can even call ::GlobalAlloc(…) to allocate<br />

memory and release it using ::LocalFree(…).<br />

Clipboard Funcitons<br />

To copy our own data to the clipboard, we need to first prepare the data. The following lists the<br />

necessary steps for allocating memory blcok and fill it with our data: 1) Allocate enough buffers by calling<br />

function ::GlobalAlloc(…). 2) Lock the memory by calling function ::GlobalLock(…), which will return<br />

a pointer that can be used to access the memory buffers. 3) Fill these buffers with data. 4) Call<br />

::GlobalUnlock(…) to unlock the memory.<br />

We need to use a series of functions in order to put the data to the clipboard: 1) First we need to call<br />

function CWnd::OpenClipboard(…), which will let the clipboard be owned by our application (Only the<br />

window that owns the clipboard can modify the data contained in the clipboard, any other application is<br />

forbidden to access the clipboard during this period). 2) Before putting any data to the clipboard, we must<br />

call ::EmptyClipboard() to clear any existing data. 3) We can call ::SetClipboardData() to put new data<br />

to the clipboard. 4) Finally we need to call ::CloseClipboard() to close the clipboard, this will let the<br />

clipboard be accessible to other windows.<br />

When calling function ::SetClipboardData(…), besides passing the handle of the global memory, we<br />

also need to specify the data format. There are many standard clipboard data formats such as CF_TEXT,<br />

CF_DIB, which represent text data and bitmap data respectively. We can also define our own data format by<br />

calling function ::RegisterClipboardFormat(…).<br />

To copy data from the clipboard, we need to open the clipboard first, then call function<br />

::GetClipboardData(), which will return a global memory handle. With this handle, we can call<br />

::GlobalLock(…) to lock the memory, copy the data from the global memory to our own buffers, call<br />

::GlobalUnlock(…) to unlock the memory, and close the clipboard. We can not free the global memory<br />

obtained from the clipboard because after the clipboard is closed, some other applications may also want to<br />

access it.<br />

Deleting Selected Text<br />

Sample 9.9\GDI is based on sample 9.8\GDI, it allows the user to cut or copy the selected text to the<br />

clipboard, and paste the data from clipboard.<br />

269

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!