I was attempting to initialize a PageSetupDlg() box so that the paper would automatically be set to landscape orientation. I looked through all of the documentation for the PAGESETUPDLG structure and I couldn’t find the setting for it. Eventually I found that I needed to modify the DEVMODE structure and set dmOrientation to be DMORIENT_LANDSCAPE. The DEVMODE is referenced in the PAGESETUPDLG structure as an HGLOBAL. This is where I began to get confused. At first I thought that the HGLOBAL was simply supposed to be a direct pointer to a DEVMODE structure. However, this continuously crashed my program. After more research, I found what I was looking for. An HGLOBAL is a structure that contains information about an allocated block of memory. It contains information such as the size and a pointer to the block. However, all of the members of the structure are private and are not to be directly modified by a program. Win32 function calls must be utilized to use an HGLOBAL.

The GlobalAlloc() function will allocate an HGLOBAL of a specified size. The function returns the HGLOBAL, which is a handle, but is NOT a direct pointer to the allocated memory. But it is easy to get the pointer to the allocated memory. Win32 utilizes memory locking so that unlocked memory can be resized or moved, and locked memory must stay in one place so that a subroutine can modify it. The Win32 function GlobalLock() takes an HGLOBAL as a parameter and returns an LPVOID which is the pointer to the actual allocated memory. This function increments the lock count so that no resizing, moving, or freeing of the allocated memory can take place. It is also possible to resize the HGLOBAL with GlobalReAlloc() and it may be freed with GlobalFree(). There are many other functions to modify HGLOBALs, so see your Win32 reference or MSDN for more information.

So to finish the PAGESETUPDLG example, I have included the abbreviated code below.
DEVMODE * pDevMode;

hDevMode = GlobalAlloc(GHND, sizeof(DEVMODE)); // allocate a moveable block of memory and initialize it to zeroes.
if ( hDevMode ) {
pDevMode = (DEVMODE *) GlobalLock(hDevMode); // lock the memory and return a pointer to it
if ( pDevMode ) {
pDevMode->dmSize = sizeof(DEVMODE); // set the size of the DEVMODE structure
pDevMode->dmFields = DM_ORIENTATION; // tell Windows that I will be setting the dmOrientation field
pDevMode->dmOrientation = DMORIENT_LANDSCAPE; // set the orientation to landscape
GlobalUnlock(hDevMode); // unlock the memory for other functions to use this

// hDevMode is now ready to be used in a PAGESETUPDLG structure


Leave a Reply

Your email address will not be published. Required fields are marked *