Viewing Dialog Template Resources at Runtime

In many resource applications, it is necessary to display a preview of the application's dialog template resource(s). This article presents a class (CPreviewStatic) that can be used to preview dialog template resources at runtime with a single line of code!

Using the CPreviewStatic class

In order to use this class, simple place a static text control on the dialog where you want to display the dialog template resource at runtime. Then, subclass the control with a call to SubclassDlgItem.
    m_stcPreview.SubclassDlgItem(IDC_STATIC_PREVIEW, this);

Once you have subclassed the text control, modify the CPreviewStatic::PreSubclassWindow function to load the desired dialog template resource. To do this, simply modify the LoadResource function call by specifying the correct resource id.

That's it! With only two steps you can view any of your application's dialog templates at runtime. For the more curious among you, the actual code to implement this functionality is presented below. If you have any questions or need any help, please feel free to contact me: Mihai Filimon. Enjoy!

Implementation of the CPreviewStatic class

The (CPreviewStatic::Preview) member function takes, as its only argument, a handle to a memory block where a dialog template resource is stored. A dialog template resource can be loaded into memory using the LoadResource Win32 SDK function. You can see how this is done in the demo project (CPreviewStatic::PreSubclassWindow). CPreviewStatic::Preview then returns a pointer to a bitmap that is a preview of the desired dialog template resource.

    // Function name : CPreviewStatic::Preview // Description : Take a handle of memory dialog resource and return the bitmap with preview // Return type : CBitmap* // Argument : HGLOBAL hGlobal CBitmap* CPreviewStatic::Preview(HGLOBAL hGlobal) { CBitmap* pBitmap = NULL, bitmapNonClient; if (LPCDLGTEMPLATE pTemplate = (LPCDLGTEMPLATE)::LockResource(hGlobal)) { CWnd* pParent = AfxGetMainWnd(); if (HWND hwnd = CreateDialogIndirectParam(AfxGetInstanceHandle(), pTemplate, pParent->m_hWnd, NULL, NULL)) { CWnd* pWnd = CWnd::FromHandle(hwnd); CRect rectWindow; pWnd->GetWindowRect(rectWindow); CRect rectClient; pWnd->GetClientRect(rectClient); CPoint p(0,0); pWnd->ClientToScreen(&p); rectClient.OffsetRect(p.x - rectWindow.left, p.y - rectWindow.top); CDC* pDC = pWnd->GetDC(); CDC dcMemSourceNonClient, dcMemDestination; if (dcMemSourceNonClient.CreateCompatibleDC(pDC)) if (dcMemDestination.CreateCompatibleDC(pDC)) if (pBitmap = new CBitmap()) if (pBitmap->CreateCompatibleBitmap(pDC, rectWindow.Width(), rectWindow.Height())) if (bitmapNonClient.CreateCompatibleBitmap(pDC, rectWindow.Width(), rectWindow.Height())) { CBitmap* pOldNonClientBitmap = dcMemSourceNonClient.SelectObject(&bitmapNonClient); CBrush brush(RGB(192, 192, 192)); CBrush* pOldBrush = dcMemSourceNonClient.SelectObject(&brush); dcMemSourceNonClient.PatBlt(0,0,rectWindow.Width(), rectWindow.Height(), PATCOPY); dcMemSourceNonClient.SelectObject(pOldBrush); dcMemDestination.SelectObject(pBitmap); pWnd->Print(&dcMemSourceNonClient, PRF_NONCLIENT ); dcMemDestination.BitBlt(0,0,rectWindow.Width(), rectWindow.Height(), &dcMemSourceNonClient, 0,0, SRCCOPY); pWnd->Print(&dcMemDestination, PRF_CHILDREN | PRF_CLIENT); dcMemSourceNonClient.SelectObject(pOldNonClientBitmap); bitmapNonClient.DeleteObject(); } pWnd->DestroyWindow(); } } return pBitmap; }


Comments

  • Modified and much smaller version!

    Posted by Legacy on 03/28/2001 12:00am

    Originally posted by: Sushant Kumar

    Same functionality can be achieved with this modified and much smaller version also!
    
    

    CBitmap* Preview(HGLOBAL hGlobal)
    {
    CBitmap* pBitmap = NULL;

    if(LPCDLGTEMPLATE pTemplate = (LPCDLGTEMPLATE)::LockResource(hGlobal))
    {
    CWnd* pParent = AfxGetMainWnd();
    if(HWND hwnd = CreateDialogIndirectParam(AfxGetInstanceHandle(), pTemplate, pParent->m_hWnd, NULL, NULL))
    {
    CWnd* pWnd = CWnd::FromHandle(hwnd);
    CRect rectWindow;
    pWnd->GetWindowRect(rectWindow);

    CDC* pDC = pWnd->GetDC();
    CDC dcMemDestination;
    if(dcMemDestination.CreateCompatibleDC(pDC))
    if(pBitmap = new CBitmap())
    if(pBitmap->CreateCompatibleBitmap(pDC, rectWindow.Width(), rectWindow.Height()))
    {
    CBitmap* pOldBitmap = dcMemDestination.SelectObject(pBitmap);
    pWnd->Print(&dcMemDestination, PRF_ERASEBKGND | PRF_CHILDREN | PRF_CHILDREN | PRF_NONCLIENT);
    dcMemDestination.SelectObject(pOldBitmap);
    }
    }

    pWnd->DestroyWindow();
    }

    return pBitmap;
    }

    Regards
    Sushant

    Reply
  • Code?

    Posted by Legacy on 03/22/2000 12:00am

    Originally posted by: Tom Archer

    Hi Milhai,

    Do you think you could throw together a demo for this great article?

    Thanks in advance,
    Tom Archer
    Web Master - CodeGuru

    Reply
  • Where's the goods?

    Posted by Legacy on 07/27/1999 12:00am

    Originally posted by: Jason

    Where is this phantom class?

    Reply
  • Here's the code

    Posted by Legacy on 10/29/1998 12:00am

    Originally posted by: Mihai

    It's just a simple snippet. I am not responsabile if your explorer isn't in folder winnt 9 you can chage
    this) or if that explorer has a dialog with 9 as identifier. You can change this. I choise the screen to put
    the preview for make independentsnippet.
    
    

    void Test()
    {
    HMODULE h = NULL;
    if (CBitmap* p = Preview(LoadResource(h, FindResource(h = LoadLibrary(_T("c:\\winnt\\explorer.exe")), MAKEINTRESOURCE(9) ,RT_DIALOG))))
    {
    BITMAP b; p->GetBitmap(&b);
    CDC dcMem, *pDC = CDC::FromHandle(::GetDC(NULL));
    if (dcMem.CreateCompatibleDC(pDC))
    {
    CBitmap* pOld = dcMem.SelectObject(p);
    pDC->StretchBlt(0,0,100,100, &dcMem, 0, 0, b.bmWidth, b.bmHeight, SRCCOPY);
    dcMem.SelectObject(pOld);
    }
    delete p;
    }
    }
    Sincerely, Mihai

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: March 19, 2015 @ 1:00 p.m. ET / 10:00 a.m. PT The 2015 Enterprise Mobile Application Survey asked 250 mobility professionals what their biggest mobile challenges are, how many employees they are equipping with mobile apps, and their methods for driving value with mobility. Join Dan Woods, Editor and CTO of CITO Research, and Alan Murray, SVP of Products at Apperian, as they break down the results of this survey and discuss how enterprises are using mobile application management and private …

  • On-demand Event Event Date: February 12, 2015 The evolution of systems engineering with the SysML modeling language has resulted in improved requirements specification, better architectural definition, and better hand-off to downstream engineering. Agile methods have proven successful in the software domain, but how can these methods be applied to systems engineering? Check out this webcast and join Bruce Powel Douglass, author of Real-Time Agility, as he discusses how agile methods have had a tremendous …

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date