How to Save and Load a Windows Region with the Win32 API

In my previous post I explained how to save a Windows region to a file and how to load it again using MFC. Some people have problems translating MFC code to standard Win32 API code, so I wrote a followup article for CodeGuru explaining exactly the same thing but with Win32 API code instead of MFC.

The article explains in details how to save a Windows region to a file using GetRegionData and how to load and re-create this saved region with ExtCreateRegion using MFC.

There are 2 functions in the article: SaveRegion and LoadRegion. For demonstration purposes, the SaveRegion function will first create an elliptic region and will then save this region to a file. The LoadRegion function will read the data back from the file and create a Windows region from this data. For making it visually clear that the LoadRegion function has loaded the correct region, the region is set as the window region.

The SaveRegion function looks like:

// lang cpp 
void SaveRegion() 
{ 
   // Create some elliptic region as demonstration 
   RECT rc; 
   GetClientRect(g_hWnd, &rc); 
   HRGN hRgn = ::CreateEllipticRgn(0, 0, rc.right, rc.bottom);   

   // Get the size in bytes of our created region 
   int iSize = ::GetRegionData(hRgn, sizeof(RGNDATA), NULL);   

   // Allocate memory to hold the region data 
   RGNDATA* pData = (RGNDATA*)calloc(iSize, 1); 
   pData->rdh.dwSize = iSize;   

   // Get the region data 
   int iSize2 = ::GetRegionData(hRgn, iSize, pData); 
   // Sanity check 
   if (iSize != iSize2) 
      ::MessageBox(g_hWnd, L"Something wrong with GetRegionData...", 
                   L"Error", MB_ICONERROR);   

   // Save region data to a file 
   FILE* f = fopen("test_region.rgn", "wb"); 
   fwrite((char*)pData, sizeof(char), iSize, f); 
   fclose(f);   

   // Free allocated memory 
   free(pData);   

   // Delete our region 
   ::DeleteObject(hRgn); 
}

The LoadRegion function looks like:

// lang cpp 
void LoadRegion() 
{ 
   // Open file to read region data from 
   FILE* f = fopen("test_region.rgn", "rb");   

   // Get size of the file 
   fseek(f, 0, SEEK_END); 
   int iSize = ftell(f); 
   fseek(f, 0, SEEK_SET);            

   // Allocate memory to hold the region data 
   RGNDATA* pData = (RGNDATA*)calloc(iSize, 1);            

   // Read region data from file 
   fread((char*)pData, sizeof(char), iSize, f); 
   fclose(f);            

   // Create region from loaded region data 
   HRGN hRgn = ::ExtCreateRegion(NULL, iSize, pData);            

   // As a demonstration, set the loaded region as window region 
   // so it is visually clear that it got loaded correctly. 
   ::SetWindowRgn(g_hWnd, hRgn, TRUE);            

   // Free allocated memory 
   free(pData); 
}

For a more detailed explanation of all the steps in the above 2 functions, check out my article at CodeGuru: How to Save and Load a Windows Region with the Win32 API.

Share

Leave a Comment

Name: (Required)

E-mail: (Required)

Website:

Comment: