HINSTANCE hinst; // handle of current instance
HWND hwndSubclass; // handle of a subclassed window
HANDLE hIcon, hCursor;
HGLOBAL hMem;
char *lpMem;
TCHAR tchPath[] = "c:\\winnt\\samples\\winprop.c";
// Load resources.
hIcon = LoadIcon(hinst, MAKEINTRESOURCE(400));
hCursor = LoadCursor(hinst, MAKEINTRESOURCE(220));
// Allocate and fill a memory buffer.
hMem = GlobalAlloc(GPTR, BUFFER);
lpMem = GlobalLock(hMem);
lstrcpy(lpMem, tchPath);
GlobalUnlock(hMem);
// Set the window properties for hwndSubclass.
SetProp(hwndSubclass, "PROP_ICON", hIcon);
SetProp(hwndSubclass, "PROP_CURSOR", hCursor);
SetProp(hwndSubclass, "PROP_BUFFER", hMem); Jim
GlobalAlloc merely allocates space, but it doesn't yet exist as a chunk of
memory at any specified location. GlobalLock is what pins it down to one
specific location, so allowing you to write into it.
--
Lucian Wischik, Queens' College, Cambridge CB3 9ET. www.wischik.com/lu
> Jim <jim.o...@jimbo.com> wrote:
>>Looking at the following code taken from MSDN library I can't
>>understand why the GlobalAlloc call is followed by a GlobalLock. What
>>is the need for a GlobalLock call? Can anyone shed some light on this?
>
> GlobalAlloc merely allocates space, but it doesn't yet exist as a
> chunk of memory at any specified location. GlobalLock is what pins it
> down to one specific location, so allowing you to write into it.
Well, MSDN says this about GlobalLock: "This function is provided only for
compatibility with 16-bit versions of Windows."
The way I see it, it is used for historical reasons and because it
explicitly converts a HGLOBAL to a pointer type.
--
Matti Vuori, <http://sivut.koti.soon.fi/mvuori/index-e.htm>
Why then the following code:
pbih = (PBITMAPINFOHEADER) pbi;
lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbih->biSizeImage);
if (!lpBits)
errhandler("GlobalAlloc", hwnd);
// Retrieve the color table (RGBQUAD array) and the bits
// (array of palette indices) from the DIB.
if (!GetDIBits(hDC, hBMP, 0, (WORD) pbih->biHeight, lpBits, pbi,
DIB_RGB_COLORS))
{
errhandler("GetDIBits", hwnd);
}
Why isn't GlobalLock called in this situation with the handle from the
GlobalAlloc call used immediately???
Jim
Heh, that'll teach me to write replies without first having read the MSDN
article on it. Ignore what I said, and pay attention to what Matti says :)
<quote>
GMEM_FIXED Allocates fixed memory. The return value is a pointer.
GMEM_MOVEABLE Allocates movable memory. In Win32, memory blocks are never
moved in physical memory, but they can be moved within the default heap.
The return value is a handle to the memory object. To translate the handle
into a pointer, use the GlobalLock function.
This flag cannot be combined with the GMEM_FIXED flag.
</quote>
Damian
> Why then the following code:
>
> pbih = (PBITMAPINFOHEADER) pbi;
> lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbih->biSizeImage);
>
> if (!lpBits)
> errhandler("GlobalAlloc", hwnd);
>
> // Retrieve the color table (RGBQUAD array) and the bits
> // (array of palette indices) from the DIB.
> if (!GetDIBits(hDC, hBMP, 0, (WORD) pbih->biHeight, lpBits, pbi,
> DIB_RGB_COLORS))
> {
> errhandler("GetDIBits", hwnd);
> }
>
> Why isn't GlobalLock called in this situation with the handle from the
> GlobalAlloc call used immediately???
>
GlobalLock() is only needed if you are calling GlobalAlloc() with the
GMEM_MOVEABLE flag. If you alloc it with GMEM_FIXED, as done in the code
above, the return value is a direct pointer.
Notice that even in the case of GMEM_MOVEABLE, the poster was incorrect (I
think he was probably thinking of VirtualAlloc()). What happens with this
flag is that the memory is indeed allocated, but the actual memory might be
moved around in the heap, so its actual virtual address could potentially
change during the program's execution. GlobalLock() tells the memory manager
to leave it locked in place for a while.
--
Tomas Restrepo
tom...@mvps.org
> ... except that Win32 OS's never (ever) move blocks around in the heap.
> Everything about GlobalAlloc and friends is really just a holdover from
> Real-Mode 16-bit Windows, where memory blocks could be moved by the OS and
> when so moved, the visible value of the pointer would in fact change.
> Everything since Win3.1 has operated in protected mode, and if blocks are
> ever moved in physical memory, it's done "behind the scenes" and the
> addresses seen by application programs never change.
AFAIK, you're right, but better safe than sorry, I say.
Besides this, notice that I didn't say anything moved in *physical* memory.
I said it could move in the *heap* (which is all virtual memory, anyway).
Potentially, one could conceive GMEM_MOVEABLE could be used to allow heap
compaction, although I doubt it is ever done.
--
Tomas Restrepo
tom...@mvps.org
.... except that Win32 OS's never (ever) move blocks around in the heap.
Everything about GlobalAlloc and friends is really just a holdover from
Real-Mode 16-bit Windows, where memory blocks could be moved by the OS and
when so moved, the visible value of the pointer would in fact change.
Everything since Win3.1 has operated in protected mode, and if blocks are
ever moved in physical memory, it's done "behind the scenes" and the
addresses seen by application programs never change.
-cd
GlobalAlloc and GlobalLock are largely irrelevant. Use malloc or new; if you
can't use those, use HeapAlloc.
The only time you _need_ to use GlobalAlloc is when using IDataObject under
some circumstances, or when using DDE.
--
Tim Robinson, MVP (Windows SDK)
http://www.themobius.co.uk/
In any case, the OP's question regarded GlobalAlloc() used with the GPTR
flag which forces the return value to be a valid pointer. With this flag
GlobalLock() is unnecessary even in Dark Ages Windows.
Norm
Or when putting data on the Clipboard.
Norm