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.