In C++11 can I preprocess a custom shaped region?

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • SwissProgrammer
    New Member
    • Jun 2020
    • 220

    In C++11 can I preprocess a custom shaped region?

    C++11. Not .net. Not VC++.

    I can create a region with the following and pick parts of it to use as a custom shaped region for a DIALOG.

    I am using a large graphic bmp that takes the following a long time to convert to a custom shaped region that I use for a custom shaped DIALOG.

    My question is for the following

    Code:
    void createSomeRegion(HWND hwndDlg) // This handle is of the DialogBox.
        {
    
            //Get the destination device context
            hdcDestDC = GetDC(hwndDlg);
    
            //Create a memory DC
            hdcMem_001 = CreateCompatibleDC(nullptr);
    
    
    //        //To Load from resource.rc as a DIB Device Independent Bitmap
    //            HANDLE hBitmap__001 = LoadImage (GetModuleHandle(nullptr), MAKEINTRESOURCE( IDB_TestMasked02), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
    //
    //            if(hBitmap__001 == NULL)
    //                {
    //                    MessageBox(hwndDlg, L"Could not load BITMAP from resource!", L"Error", MB_OK | MB_ICONEXCLAMATION);
    //                }
    
            //To Load from a file.
                // HANDLE hBitmap__001 = (HBITMAP)LoadImage(GetModuleHandle(nullptr), L"a.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
                //if(!hBitmap__001)
                //    {
                //        //handle error here
                //        return;
                //    }
    
            //Get information about the bitmap..
            GetObject(hBitmap__001, sizeof(bmpInfo_001), &bmpInfo_001);	// Get info about the bitmap
    
            //Select the bitmap into the dc
            SelectObject(hdcMem_001, hBitmap__001);
    
            //Create an empty region
            hRgn_001 = CreateRectRgn(0,0,0,0);
    
            //Create a region from a bitmap with transparency color of white
            //change the pixel values for a different transparency color
            //ex - RGB(0,0,0) will mean a transparency color of black.. so the areas
            //of the bitmap not used to create the window will be black
    
            COLORREF crTransparent = RGB(255, 255, 255);  // To be transparent.
    
            int iX = 0;
            int iY = 0;
            int iRet = 0;
    
            for ( iY = 0; iY < bmpInfo_001.bmHeight; iY++)
                {
                    do
                        {
                            //skip over transparent pixels at start of lines.
                            while (iX < bmpInfo_001.bmWidth && GetPixel(hdcMem_001, iX, iY) == crTransparent)
                                {
                                    iX++;
                                }
    
                            //remember this pixel
                            int iLeftX = iX;
    
                            //now find first non transparent pixel
                            while (iX < bmpInfo_001.bmWidth   && GetPixel(hdcMem_001, iX, iY) != crTransparent)
                                {
                                    ++iX;
                                }
    
                            //create a temp region on this info
                            HRGN hRgnTemp = CreateRectRgn(iLeftX, iY, iX, iY+1);
    
                            //combine into main region.
                            //    int CombineRgn
                            //        (
                            //            HRGN hrgnDst,     // A handle to a new region with dimensions defined by combining two other regions. (This region must exist before CombineRgn is called.)
                            //            HRGN hrgnSrc1,    // A handle to the first of two regions to be combined.
                            //            HRGN hrgnSrc2,    // A handle to the second of two regions to be combined.
                            //            int  iMode        // A mode indicating how the two regions will be combined.
                            //
                            iRet = CombineRgn(hRgn_001, hRgn_001, hRgnTemp, RGN_OR);
    
                            if(iRet == ERROR)
                                {
                                    return;
                                }
                            //delete the temp region for next pass
                            DeleteObject(hRgnTemp);
                        }
                    while(iX < bmpInfo_001.bmWidth);    // Completing a Do While loop.
                                                    // This is not a "while for the next line".
    
                    iX = 0;
                }
    //////
    //////        //Center it on current desktop
    //////        iRet = SetWindowRgn(hwndDlg, hRgn_001, TRUE);
    //////
    //////        if(!iRet)
    //////            {
    //////                // messagebox stating that this did not work...
    //////                return;
    //////            }
    
    
    //// Create a reusable rectangular region.
    //hReusableRectangularRegion = CreateRectRgn(0,0,100,100);
    //
    //// Create a temporary brush for a temporary rectangular region.
    //HBRUSH hBrushTmporary1 = CreateSolidBrush(RGB(255, 0, 0));
    
    //BOOL FillRgn(
    //  HDC    hdc,
    //  HRGN   hrgn,
    //  HBRUSH hbr
    //);
    
    //FillRgn(HDC_of_MainWindow, hReusableRectangularRegion, hBrushTmporary1);
    //
    //// The temporary brush is no longer needed. Delete it to free the allocated memory that it is using.
    //DeleteObject(hBrushTmporary1);
    
    
    ///
    
    
    int x = 0;
    int y = 4;
    //int i = OffsetRgn(hReusableRectangularRegion, (n*47)+(n),(n*47)+(n));
    int i = OffsetRgn(hReusableRectangularRegion, (x*47)-x,(y*47)-y);
    //int i = OffsetRgn(hReusableRectangularRegion, 0,0);
    
    
    iRet = CombineRgn(hRgn_001, hRgn_001, hReusableRectangularRegion, RGN_AND);
    
    
    
            //Center it on current desktop
            iRet = SetWindowRgn(hwndDlg, hRgn_001, TRUE);
    
            if(!iRet)
                {
                    // messagebox stating that this did not work...
                    return;
                }
    
    
    
    //        iX = ((GetSystemMetrics(SM_CXSCREEN)) / 2) - (bmpInfo_001.bmWidth / 2 + 50);
    //        iY = ((GetSystemMetrics(SM_CYSCREEN)) / 2) - (bmpInfo_001.bmHeight / 2 + 50);
    
    //        iRet = SetWindowPos(hwndDlg, HWND_TOPMOST, iX, iY, bmpInfo_001.bmWidth, bmpInfo_001.bmHeight, 0);
            iRet = SetWindowPos(hwndDlg, HWND_TOPMOST, 300, 300, bmpInfo_001.bmWidth, bmpInfo_001.bmHeight, 0);
    
            //Copy the memory dc into hdcDestDC
            paintRegion_001();
    
            //delete the bitmap
            DeleteObject(hBitmap__001);
        }
    What I have tried:

    C++11. Not .net. Not VC++.

    I tried searching for a faster custom region creation but did not find that.

    I tried testing the time that it takes for the large bitmap to be converted to a custom region and to be used for the modeless dialog, and it looks like about 10 to 15 seconds. That is too long.

    I tried to figure out how to pre-process the custom region, but I am not clear how to do this.

    I tried #void createSomeRegio n(HWND hwndDlg), but that did not work.

    I want to be able to process a large graphic (bmp) into a custom region, and have that already-processed region included in my final stand-alone executable, which I can use without having to go pixel by pixel when the exe runs.

    I wandered through various wastelands of .net and VC++ starving for real C++ code.

    Thanks for your help with C or up to C++11 answers.
  • Banfa
    Recognized Expert Expert
    • Feb 2006
    • 9067

    #2
    I haven't worked with regions like this myself but by the sounds of it you are trying to create a custom region that doesn't change, I suspect the time issue is because you are creating so many small regions and adding them into a larger region but this isn't really what you need.

    I would have thought you would be better off with a single call to CreatePolygonRg n. In order to make that call you will need a list of points that make up the polygon that you wish the region to have.

    Therefore I would create a separate utility program that analyses the bitmap and outputs the list of points, you can then include that into your main program so that you can create the region in a single step without having to process the bitmap at all.

    Not sure if this would work but it's what I would try.

    Comment

    • SwissProgrammer
      New Member
      • Jun 2020
      • 220

      #3
      Thank you Banfa.

      I would like that. I think that is what I am trying to do in my efforts to streamline the process. I do not know how.

      Example: A cloud map of one moment of clouds over the United States and outlying regions. If that cloud map is stationary and if it is used for some interactive purpose later where the user can click through the transparent areas to the US map behind the cloud map then creating the custom region for the cloud areas, as I am doing, can take a long time. I want to process the custom region one time, then include the processed custom region in the executable so that each time the exe starts up it does not have to re-process the custom region. This is a struggle for me as I write this.

      I am not so good at arrays. Could I do this custom region processing and save it to an exterior array file and then load that as a resource when compiling the executable, thus making the array an integral part of the final exe?

      I feel like a monkey contemplating calculus while not knowing to let go of the apple in the monkey-puzzle box.

      Help!



      Thanks.

      Comment

      Working...