Click here to Skip to main content
Click here to Skip to main content

CResizableDialog

By , 25 Jul 2012
 

CResizableDialog - What is it & Why?

I wrote my own class to implement resizable dialogs mostly as an exercise of MFC and Windows programming. Later, I discovered that other people had written similar classes, but I didn't find one I really like that was as simple as my little projects.

Before you go any further, I have to warn you that I'm not a "guru". Surely something could be done better, but I think this class is at least easy to use.

The user will have the ability to resize the dialog, with consequent rearrangement of child windows, and you can control the minimum and maximum size allowed, as well as the maximized size and position of the dialog. The size grip is displayed by default, but you may turn it off. Automatic Save/Restore the dialog's size and position is also supported.

Conversion of a previously existant dialog should be very simple, as well as creation of a new resizable dialog.

Now implemented with ResizableLib (see article).

The Sample Application

This is a view of the sample dialogs:

Default min size is the one in the dialog template (and grip is visible) Support for colored or bitmap background with a triangular size grip

This is a composite view, where you can see the maximized position is not the default:

A desktop snapshot with the dialog maximized and normal size overimpressed

You may see how to do this in the next section.  

Usage - Step by Step

Add the ResizableLib to your project's workspace, as explained in the relative article.

Create a dialog resource and associate it with a CDialog derived class, for example using Class Wizard, or take a dialog you have already made which you want to be resizable.

You no longer need to change the window style to have the dialog resizing.

Include 'ResizableDialog.h' in the associated header file.

Search and replace all CDialog occurrences with CResizableDialog in both your .cpp and .h files, just as if your dialog class was derived from CResizableDialog instead of CDialog. I think there's no way to let the Class Wizard do this for you. Let me know if I'm wrong, please.

Your header file should appear like this:

// MyDialog.h : header file
//
// ( Class Wizard stuff )
/////////////////////////////////////////////////////////////////////////////
// CMyDialog dialog

#include "ResizableDialog.h"
class CMyDialog : public CResizableDialog
{
// Construction
public:
    CMyDialog(CWnd* pParent = NULL);    // standard constructor

// ( other stuff )
// ...
}

In your OnInitDialog override, add an anchor for each control you want the size and/or position to be changed when the user resizes the dialog.

BOOL CMyDialog::OnInitDialog()
{
    CResizableDialog::OnInitDialog();

    // Set the icon for this dialog. The framework does this
    // automatically when the application's main window is not a dialog
    SetIcon(m_hIcon, TRUE);     // Set big icon
    SetIcon(m_hIcon, FALSE);    // Set small icon

    // preset layout
    AddAnchor(IDOK, BOTTOM_RIGHT);
    AddAnchor(IDCANCEL, BOTTOM_RIGHT);
    
    AddAnchor(IDC_SPIN1, TOP_RIGHT);

    AddAnchor(IDC_LABEL1, TOP_LEFT);
    AddAnchor(IDC_EDIT1, TOP_LEFT, BOTTOM_RIGHT);

    AddAnchor(IDC_RADIO1, BOTTOM_LEFT);
    AddAnchor(IDC_RADIO2, BOTTOM_LEFT);
    AddAnchor(IDC_GROUP1, BOTTOM_LEFT, BOTTOM_RIGHT);
    
    // other initializations
    // ...

Here you may also set a maximum size for your dialog (default is the workspace area), a minimum size (default is the one you set in the resource editor) and also a rectangle that the dialog occupies when maximized.

// get desktop size
CRect rc;
GetDesktopWindow()->GetClientRect(&rc);

// set max tracking size to half a screen
SetMaxTrackSize(CSize(rc.Width(), rc.Height()/2));

// maximized position and size on top of the screen
rc.bottom = 100;
SetMaximizedRect(rc);

After all this settings, you may wish the dialog's size and position to be automatically saved and restored, as well as its maximized or minimized state. Just provide a Section and an Entry name in your application's profile, in which to save dialog's status.

// save/restore
// (for dialog based app, default is a .INI file with
// the application's name in the Windows directory)
EnableSaveRestore(_T("DemoDlg"));

You are ready to rebuild your project and you will have a resizable dialog just as you wanted.

For further details, see the next section.

Class Reference

This class inherits from CResizableGrip, CResizableLayout, CResizableMinMax, CResizableState, and obviously from CDialog.

CResizableDialog::CResizableDialog

CResizableDialog()
CResizableDialog(UINT nIDTemplate, CWnd* pParentWnd = NULL)
CResizableDialog(LPCTSTR lpszTemplateName, CWnd* pParentWnd = NULL)

The first is the default constructor.

The second and the third forms are needed to reproduce the construction scheme of a CDialog derived class. Since the dialog resource template is needed by the CDialog constructor, you have to call one of these forms of the CResizableDialog constructor. This is the reason why replacing one class with the other will work.

CResizableDialog::EnableSaveRestore

void EnableSaveRestore(LPCTSTR pszSection, BOOL bRectOnly = FALSE)

Enables automatic save/restore on dialog's open/close operations. The arguments are the same as in CWinApp::WriteProfileString. If bRectOnly is TRUE, the minimized/maximized state is not saved/restored. Should be called after all the layout settings.

If you want details on how this information is stored by your application, look at CWinApp::SetRegistryKey, CWinApp::m_pszProfileName, CWinApp::m_pszRegistryKey on MFC documentation.

CResizable???::???

Implemented in the various base classes, see ResizableLib article.

Conclusion

I would like to make this class more "integrated" with Class Wizard, but I don't even know if it's possible. I hope this class can be useful to other programmers that just want to have resizable dialogs with the minimum effort.

I implemented a sort of percentage resizing. However, currently available anchor types do not permit a high level of complexity, but should be enough in many applications. If you want more flexibility or if your dialogs are very big and full of controls, you may search CodeProject for another solution in this same Section (see the top of the article).

The CVS tree is now on Source Forge.

Updates

25 May 2000

  • Initial public release.

31 May 2000

  • Some unneeded code has been removed.
  • Flickering has been reduced for Button, Static and ListBox controls.
  • Save/Restore support has been added.
  • Fixed a nasty bug that only came out with modeless dialogs.

9 Jun 2000

  • Now compiles cleanly at warning level 4.
  • Memory leak fixed. (I completely forgot to free memory)
  • New type of anchorage now allowing more complex layouts. (compatible with previous code)
  • Fixed a bug with the size grip when hidden and when the dialog is maximized.
  • Better handling of controls that need repainting.
  • Demo project updated to show new features.

11 Jul 2000

  • Fixed a minor bug in save/restore functions. (standard maximized dialog wasn't restored correctly)

27 Oct 2000

  • Changed layout implementation (from CPtrList to CArray)
  • Fixed a bug with controls that need refresh

23 Nov 2000

  • Fixed a bug with multiple calls to DoModal()
  • Removed doc from zip files (you simply save this page if you need it)

13 Mar 2001

  • Fixed a bug with radio buttons and group boxes (thanks to Matt Philmon)
  • Changed copyright note

11 Jun 2001

  • New implementation and integration with ResizableLib
  • Automatic resizing style (thanks to John Simmons)
  • Added anti-flickering support

15 Jul 2001

  • Updated to new ResizableLib release
  • Demo project shows new grip implementation

28 Oct 2001

  • Version 1.1 (CVS Tag: SF_1_1)
  • Added static build configurations to all projects

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Paolo Messina
Software Developer RoboTech srl
Italy Italy
Member
Paolo began programming at the age of 9 with a glorious 8086 and GW-BASIC, then he played a bit with C, ASM and Pascal. He tought himself MFC and Windows programming, to exploit his studies of C++. Always attracted by low-level programming and Assembly, he's beginning to appreciate the joys of templates and STL. At work he changed his mind about Java, discovered Eclipse IDE, and now think it's cool.
 
He lives in Follonica, Italy.
 
He has been abroad in the U.S. to work on his final thesis before graduating. For seven months he was playing with airplanes and automatic control at the Unversity of Illinois at Urbana-Champaign.
 
He graduated in Computer Science Engineering at the University of Pisa, Italy, in December 2003.
 
Currently working for an edutainment robotics company (www.robotechsrl.com).

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralResizable Textboxmemberumu29 Mar '11 - 16:06 
How to make a resizable textbox?
The text therein should grow/shrink accordingly.
Is this possible?
GeneralRe: Resizable TextboxmemberMizan Rahman4 Apr '11 - 23:24 
You could also see this: MFC/C++ Helper Class for Window Resizing[^]
QuestionAdding logo to top of Property Sheet breaks codemembermasteryoda2118 Oct '10 - 6:56 
Paolo,
 
This code is great, but when I add a logo to the top of a property sheet (as: http://www.codeguru.com/cpp/controls/propertysheet/article.php/c3973[^] see: Adding a Control to the Property Sheet) it breaks your code.
 
Do you have a fix?
AnswerRe: Adding logo to top of Property Sheet breaks codememberPaolo Messina18 Oct '10 - 21:43 
Copy OnInitDialog from CResizableSheet and make m_bLayoutDone as protected in the header file.
 
Then in your sheet call CPropertySheet::OnInitDialog directly at the beginning, skipping the CResizableSheet implementation (that you have copied at the end of your OnInitDialog).
 
That may or may not work. If the layout is much different, do not call PresetLayout and roll your own.
 
Paolo
------
Why spend 2 minutes doing it by hand when you can spend all night plus most of the following day writing a system to do it for you? - (Chris Maunder)

QuestionIs this suitable for dialog with child dialogs?memberRicky.Lee31 Mar '09 - 20:32 
when parant dialog size is changed, child dialog size can change accordingly.
is this class suitable for this case? if so, how to do? thanks
Ricky
QuestionI need to resize the controls in a dialog automatically?memberjohnthecoder25 Aug '08 - 0:16 
Hi,
 
Now now am using CResizableFormView in my application.I need to set the size of the dialog according to the size of the main window.Because its an sdi application different dailogs are displayed at different times in the same window.So the dialog controls sholud be resized automatically.Please help..
 
Regards,
thanks in advance,
 
John
AnswerRe: I need to resize the controls in a dialog automatically?memberPaolo Messina25 Aug '08 - 0:38 
Please see:
http://www.codeproject.com/KB/docview/resizableformview.aspx[^]
 
Paolo
 
------
Why spend 2 minutes doing it by hand when you can spend all night plus most of the following day writing a system to do it for you? - (Chris Maunder)

QuestionWhile compiling I am getting the follwing error - Cannot open include file: 'ResizableDialog.h': No such file or directory?memberjohnthecoder24 Aug '08 - 6:54 
Hi all,
I am using resizablelib in my project.But while compiling it displays the message "Cannot open include file: 'ResizableDialog.h': No such file or directory".Please tell me what may be the reason???
 
regards,
thanks in advance,
john...
AnswerRe: While compiling I am getting the follwing error - Cannot open include file: 'ResizableDialog.h': No such file or directory?memberPaolo Messina24 Aug '08 - 10:47 
Please have a look at:
http://www.codeproject.com/KB/dialog/ResizableLib.asp[^]
 
And check you did the same steps to use the library.
 
Paolo
 
------
Why spend 2 minutes doing it by hand when you can spend all night plus most of the following day writing a system to do it for you? - (Chris Maunder)

QuestionError C2440??memberHeiniBlad22 Jun '06 - 12:07 
when my app is set to use CDialog, all works fine.
when i change CDialog to CResizableDialog, as described i get this error:
 
error C2440: 'type cast' : cannot convert from 'int (__thiscall MyDlg::*)(void)' to 'void (__thiscall CCmdTarget::*)(void)
 
why does it work with CDialog?
Any ideas???
 
Thanks alot...
Heiner
AnswerRe: Error C2440??memberbrwx23 Jul '08 - 2:20 
The function, where the error is pointed at, needs to be return type 'void' not 'int'.
 
Looks like some AFX_MSG ....
 

Hope that helps you.
GeneralModeless DialogsmemberNeilDevlin3 Nov '05 - 6:06 
Hi,
Great class, very useful. I want to create a few modeless dialogs at one time, can anyone see a problem with this?
 
Neil
GeneralWindowsXP Stylememberintarapim19 Feb '05 - 2:22 
I try to use Windows XP Style , but the property pages have another size.
any fix for Windows XP Style ?
 
Robert
Generalwidth changes on minimize maximizesussSanat Tiwari10 Jan '05 - 19:29 
Hi,
Thanks for writing such a good library.
I am using it and it works fine except When we minimize the window and then again maximize it the widht of the window increases by some amount. I am not able to figure it out. Please help!!
 
Sanat Tiwari
GeneralRe: width changes on minimize maximizememberPaolo Messina10 Jan '05 - 21:13 
Hi Sanat,
 
A maximized window occupies all the screen. How can it grow in size?
Or you mean minimize and then restore?
 
In this case, I can't figure out what happens there... Is it the main window size or the size of some controls?
 
Please add some details...
 
Paolo
 
------
Why spend 2 minutes doing it by hand when you can spend all night plus most of the following day writing a system to do it for you? - (Chris Maunder)

GeneralRe: width changes on minimize maximizememberSanatforu13 Jan '05 - 1:05 
Yes u r correct.. minimize and then restore.. after restoring the widht of main window grows in size, also two group box controls grows in there width.
 
please help!!
 
Sanat
GeneralRe: width changes on minimize maximizememberPaolo Messina15 Jan '05 - 8:59 
This never happened to me. I really don't know...
 
Are you doing something unusual that could modify the window size?
 
Paolo
 
------
Why spend 2 minutes doing it by hand when you can spend all night plus most of the following day writing a system to do it for you? - (Chris Maunder)

Generalgrid class does not resizemembernnnnnnn3 May '04 - 4:30 
This dialog class does not appear to have effect on the chris maunder grid control ? Or do I need to do some extra work on the grid class ?
 
Confused | :confused:
GeneralDialog becomes "eternally" minimizedmemberIGx8915 Nov '03 - 7:45 
I've been using your CResizableDialog class for a couple months now, and I really appreciate how easy it makes it to make my program's main dialog dynamically resizable. Unfortunately, I've been getting reports from some people (both on ME and XP) that when starting up my program, it is only visible on the taskbar and they can't restore it. I'm using EnableSaveRestore with RectOnly=True, so I can't understand why that would be happening. As soon as the users deletes the registry key that saves the dialog's state, the program starts up fine. Please help; I'd rather not be forced to stop using this helpful class Frown | :(
GeneralRe: Dialog becomes "eternally" minimizedmemberPaolo Messina15 Nov '03 - 12:52 
Can you post the content of one of those registry keys and the ResizableLib version used? So I could try to reproduce it.
 
The suspect is that the saved position is invalid or off-screen, so maybe the problem is when the data is saved to the registry.
 
Paolo
 
------
Why spend 2 minutes doing it by hand when you can spend all night plus most of the following day writing a system to do it for you? - (Chris Maunder)

GeneralRe: Dialog becomes "eternally" minimizedmemberIGx8926 Jan '04 - 8:52 
Sorry about the delayed response; I had taken steps to avoid that problem (making window position remembering an option, defaulting to off), and didn't have a chance to find out a non-working registry key until now. Here's what the contents are of it:
 
-32000,-32000,-31287,-31475,1,0
 
I looked at all the source and header files of the ResizableLib code I'm using and couldn't find any version numbers; I was using the latest stable version (at least within a few weeks) at the time of my last post.
GeneralPatchmemberPaolo Messina27 Jan '04 - 8:04 
Could it be a problem with multi-monitor systems only? If you attach a secondary monitor, move the window on it, close the application, remove the monitor and then open the app again, it may happen that your window looks like minimized, but it's actually out of the visible part of the screen.
Someone reported this issue and that it doesn't happen with bRectOnly=FALSE.
If you could confirm this I could think about a fix for the next (upcoming) version.
 
Otherwise it may be another bug. The fifth field in the registry key you reported should be 2 for SW_SHOWMINIMIZED. It may be that I'm saving the wrong position with bRectOnly=TRUE.
 
Thanks,
Paolo
 
------ Temporary patch ------
BOOL CResizableState::SaveWindowRect(LPCTSTR pszSection, BOOL bRectOnly)
{
    CString data;
    WINDOWPLACEMENT wp;
 
    ZeroMemory(&wp, sizeof(WINDOWPLACEMENT));
    wp.length = sizeof(WINDOWPLACEMENT);
    if (!GetResizableWnd()->GetWindowPlacement(&wp))
        return FALSE;
    
    // use workspace coordinates
    RECT& rc = wp.rcNormalPosition;
 
    if (bRectOnly)  // save size/pos only (normal state)
    {
        data.Format(PLACEMENT_FMT, rc.left, rc.top,
            rc.right, rc.bottom, SW_SHOWNORMAL, 0);
    }
    else    // save also min/max state
    {
        data.Format(PLACEMENT_FMT, rc.left, rc.top,
            rc.right, rc.bottom, wp.showCmd, wp.flags);
    }
 
    return AfxGetApp()->WriteProfileString(pszSection, PLACEMENT_ENT, data);
}
 
BOOL CResizableState::LoadWindowRect(LPCTSTR pszSection, BOOL bRectOnly)
{
    CString data;
    WINDOWPLACEMENT wp;
 
    data = AfxGetApp()->GetProfileString(pszSection, PLACEMENT_ENT);
    
    if (data.IsEmpty()) // never saved before
        return FALSE;
    
    ZeroMemory(&wp, sizeof(WINDOWPLACEMENT));
    wp.length = sizeof(WINDOWPLACEMENT);
    if (!GetResizableWnd()->GetWindowPlacement(&wp))
        return FALSE;
 
    // use workspace coordinates
    RECT& rc = wp.rcNormalPosition;
 
    if (_stscanf(data, PLACEMENT_FMT, &rc.left, &rc.top,
        &rc.right, &rc.bottom, &wp.showCmd, &wp.flags) == 6)
    {
        if (bRectOnly)  // restore size/pos only
        {
            wp.showCmd = SW_SHOWNORMAL;
            wp.flags = 0;
            return GetResizableWnd()->SetWindowPlacement(&wp);
        }
        else    // restore also min/max state
        {
            return GetResizableWnd()->SetWindowPlacement(&wp);
        }
    }
    return FALSE;
}
 
It was actually a bug in the Load/SaveWindowRect functions. This is the fix, that will be included in the next version.
 
Paolo
GeneralI wish this was available in Winforms!memberMatt Philmon11 Nov '03 - 3:49 
I was just thinking to myself yesterday while I kicked and screamed at trying to get my stinking controls to stretch and grow the way I need them to that I really miss this class! MFC was my bread and butter for years and there are times when I really miss it. This class, to this day, remains the most heavily used piece of shared code I've ever downloaded.
 
Nowadays I'm 99.9% .NET (a pretty even mix of VB.NET and C#) with a little bit of old ATL COM still thrown into the mix on occasion and I'd give ANYTHING to have this project converted into a proper layout manager for Winforms for use in VB.NET and C#. The new features in Winforms for Docking and Anchoring are really great and do the job more often than not with very little effort... but there are so many times when they fall way short and I never came across a scenario with CResizableDialog that would not allow me to lay out my controls in the manner I frequently need to (more than 1 or 2 controls on a "line").
 
At any rate, if you do ever make the switch, PLEASE consider writing this for .NET.
GeneralRe: I wish this was available in Winforms!memberPaolo Messina11 Nov '03 - 6:44 
Matt Philmon wrote:
This class, to this day, remains the most heavily used piece of shared code I've ever downloaded.
 
Well, that's great. And thank you very much for showing your appreciation. Big Grin | :-D
 
Matt Philmon wrote:
At any rate, if you do ever make the switch, PLEASE consider writing this for .NET.
 
Well, I must say that I still prefer the old VC++ 6.0 to the new .NET version and I'm not ready for the "switch" yet. What's more, the next version of this class library will be based on templates and I don't know to what extent I could use them on the .NET platform, if not at all. But, since MFC compatibility will be achieved with some adapter classes (and some specific for MFC) I suppose that there could be a way to build some .NET components with C++. Anyway, right now I wouldn't even know where to start. Sigh | :sigh:
 
Paolo
 
------
Why spend 2 minutes doing it by hand when you can spend all night plus most of the following day writing a system to do it for you? - (Chris Maunder)

GeneralFails with ActiveX ControlmemberAlex Mitchell4 Nov '03 - 9:24 
Paolo
 
Very useful implementation. However, I had the need to use an ActiveX Control (Component One's FlexGrid) in the dialog which caused an ASSERT failure when AddAnchor is called. Tested this with VideoSoft's Flexgrid with a similar result.
 
Is this known issue?
 
Thanks,
Alex
GeneralRe: Fails with ActiveX ControlmemberPaolo Messina5 Nov '03 - 6:51 
Please review the older posts about ActiveX controls, both in this and the ResizableLib article.
Basically, you need to pass a HWND to the ActiveX control in the AddAnchor call.
 
Paolo
 
------
Why spend 2 minutes doing it by hand when you can spend all night plus most of the following day writing a system to do it for you? - (Chris Maunder)

GeneralRe: Fails with ActiveX ControlmemberAlex Mitchell5 Nov '03 - 7:49 
Thanks Paolo,
 
Found the solution as you indicated.
 
Much appreciated,
Alex
GeneralReplacing CDialog instancesmemberWolfSupernova30 Sep '03 - 4:27 
I've been using this for a while but I've found another class that I'd like to use for skinning the dialogs which also requires a find and replace of all the CDialog instances.
 
Is there a way to get them both working at the same time or a different way of doing it that might work?
 
If not, does anyone know how to get rid of the border if you set the dialog border property to resizable? If I'm using a transparent, or non-rectangular image for the dialog, I'd like to add a grip somewhere on the skin and hide the border.
 
Thanks,
Don
GeneralRe: Replacing CDialog instancesmemberPaolo Messina30 Sep '03 - 4:57 
WolfSupernova wrote:
Is there a way to get them both working at the same time or a different way of doing it that might work?
 
Use CResizableDialog as a base class for the skin dialog class (replace it in the source files) and then use the latter for your dialog.
 
I'm aware of this kind of problems, and that's another reason for generalizing the library in the next version. (Not soon to come, unfortunately).
 
Paolo
 
------
Why spend 2 minutes doing it by hand when you can spend all night plus most of the following day writing a system to do it for you? - (Chris Maunder)

GeneralRe: Replacing CDialog instancesmemberWolfSupernova30 Sep '03 - 5:55 
Hmmm... I think I screwed up. D'Oh! | :doh:
 
Here's what I did. The skin class in question is here if that helps. http://www.codeproject.com/dialog/cdialogsk.asp?target=cdialogsk
 
I included the library and replaced all instances of "CDialogSK" (previously CDialog) in my .h and .cpp files, with "CResizableDialog".
 
Then, I went through the CDialogSK.h and .cpp files and replaced all instances of "CDialog" with "CResizableDialog".
 
Was that right? After doing so, I got a gazillion compile errors, the first one starting with:
 
CDialogSK: illegal member initialization: 'CResizableDialog' is not a base or member.
 
Sorry for the trouble.
Thanks again,
Don
GeneralRe: Replacing CDialog instancesmemberPaolo Messina30 Sep '03 - 6:08 
WolfSupernova wrote:
Then, I went through the CDialogSK.h and .cpp files and replaced all instances of "CDialog" with "CResizableDialog".
 
This is correct. Now CDialogSK inherits from CResizableDialog.
 
WolfSupernova wrote:
I included the library and replaced all instances of "CDialogSK" (previously CDialog) in my .h and .cpp files, with "CResizableDialog".
 
This is incorrect. CYourDialog should still inherit from CDialogSK, that now is also a "resizable" dialog.
 
Be sure to follow the steps in the article for CDialogSK, about how to make it a resizable dialog. Then you can use it as both a skin-able and resizable dialog.
 
If you still get compiler errors, quote the source code the error is referring to in your post.
 
HTH,
Paolo
 
------
Why spend 2 minutes doing it by hand when you can spend all night plus most of the following day writing a system to do it for you? - (Chris Maunder)

GeneralRe: Replacing CDialog instancesmemberWolfSupernova30 Sep '03 - 7:03 
Okay, cool. That worked. Now I just have one more little problem and I promise I'll leave you alone. Thanks for responding so quickly by the way.
 
Is there any way to get rid of the border? That's the same problem I had before just using the skin class by itself and changing the border to "resizing". By using your library, I was hoping there'd be no border and I'd see the size grip, but I got a border and no grip instead. And obviously I don't want a border around a transparent or non-rectangular skin.
 
Okay, two questions. Wink | ;) Is there a way to change the image for the grip?
 
Thanks again,
Don
GeneralRe: Replacing CDialog instancesmemberWolfSupernova30 Sep '03 - 7:14 
Oops. Maybe it's not working. I only have one button control on the dialog in the top right corner and it won't allow me to resize it any smaller, which indicated that it was working, but it's not moving on resize after I added the anchor.
 
AddAnchor(IDC_BUTTON_EXIT, TOP_RIGHT);
 

GeneralRe: Replacing CDialog instancesmemberPaolo Messina30 Sep '03 - 8:49 
Be sure you replaced every occurence of CDialog with CResizableDialog, especially in the OnSize handler and the message map implementation.
Then you may want to modify the OnEraseBkgnd handler to enable clipping (for anti-flickering). You can use the old CResizableLayout::ClipChildren(CDC* pDC) function before starting drawing on the DC. This won't work with XP themes enabled.
Or you can get the latest code from CVS at SourceForge (main branch):
http://cvs.sourceforge.net/viewcvs.py/resizablelib/ResizableLib/[^]
(Ignore the ResizableCombo stuff and files you don't need - but check dependencies)
 
And then use the new code as follows:
BOOL CDialogSK::OnEraseBkgnd(CDC* pDC) 
{
    //BOOL bRetValue = CResizableDialog::OnEraseBkgnd(pDC); // erase this
    ClipChildren(pDC, FALSE);
    // drawing code
    ClipChildren(pDC, TRUE);
    return TRUE;
}
It's important that you don't call the base class implementation in OnEraseBkgnd, or you'll have flickering.
 
And if you use a non-rectangular shape, don't forget to update the window region whenever the window is resized. This may be a cause of flickering, I'm not sure. You'll have to find a suitable message handler for that... maybe WM_NCCALCSIZE.
 
Paolo
 
------
Why spend 2 minutes doing it by hand when you can spend all night plus most of the following day writing a system to do it for you? - (Chris Maunder)

GeneralRe: Replacing CDialog instancesmemberWolfSupernova30 Sep '03 - 10:09 
Thanks Paolo,
 
I figured out what was wrong with the anchoring. I had an ON_SIZE message handler for a WebBrowser control and when I took that out, the anchoring worked (kind of, it's a little slow moving into place), but now my WebBrowser control won't resize properly of course. I've always had to handle that one independently in the past. I've tried other resizing classes, but they don't play well with it either.
 
Anyway, I downloaded the latest files from sourceforge and did as you suggested. It doesn't appear to be flickering too bad but I still can't get rid of the border. I tried removing ModifyStyle(WS_THICKFRAME) but then it won't resize, so I'm right back to square one.
 
I was hoping there was a way to set the border width/hight to "0" or something but there doesn't seem to be a way to do that. If you or anyone else has a suggestion, I'd love to hear it!
 
Thanks again for your help,
Don
GeneralRe: Replacing CDialog instancesmemberPaolo Messina30 Sep '03 - 13:05 
To eliminate the border the only option is removing the WS_THICKFRAME style, and maybe also WS_BORDER and WS_CAPTION.
And you're right, it won'r resize anymore after you do that, unless you implement the resizing feature yourself. Modify the CResizableGrip class and call ::PostMessage(hDlg, WM_SYSCOMMAND, SC_SIZE, 0) when the WM_LBUTTONDOWN is received. The place to do that is in the CSizingGrip::WindowProc() function. The hDlg argument is the dialog HWND, that you can get with GetParent()(obviously you can use the returned CWnd* directly).
That should enable the resizing, but I'm not sure.
 
If you want to change the grip icon you need to handle WM_PAINT as well, and draw whatever you like the most. Have a look at the transparent drawing routines, maybe you can just load your own bitmap instead of letting the control draw the grip, and nothing more. It should be easy.
 
Paolo
 
------
Why spend 2 minutes doing it by hand when you can spend all night plus most of the following day writing a system to do it for you? - (Chris Maunder)

GeneralRe: Replacing CDialog instancesmemberWolfSupernova1 Oct '03 - 8:17 
Okay, I see where you're going with this. Unfortunately, there's already a WM_LBUTTONDOWN handler being used in the skin class, to let the user drag the dialog around the desktop when they click on a non-transparent part of the bitmap.
 

void CDialogSK::OnLButtonDown(UINT nFlags, CPoint point)
{
if (m_bEasyMove)
PostMessage(WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point.x, point.y));
 
CResizableDialog::OnLButtonDown(nFlags, point);
}

 
I just posted a message in Abhinaba's article to see if he could join in on this conversation and provide a little insight. I think this dialog that we have going here(no pun intended) could be useful to others as well.
 
Don
GeneralRe: Replacing CDialog instancesmemberPaolo Messina1 Oct '03 - 9:02 
WolfSupernova wrote:
Unfortunately, there's already a WM_LBUTTONDOWN handler being used in the skin class
 
I was talking about the grip class, that is CResizableGrip::CSizeGrip. You may add the code I was suggesting as an additional option, that you may add to the CreateSizeGrip() function.
 
This would not interfere with the WM_LBUTTONDOWN handler in the dialog class.
 
WolfSupernova wrote:
I think this dialog that we have going here(no pun intended) could be useful to others as well.
 
Yeah, definitely. You may call that CResizableDialogSK, or CResizableSkinDialog, or whatever you like. Smile | :)
 
But the enhancement to the grip class, I think I can add it to the next version of ResizableLib, just in case one would want to have a resizable window without a resizable border, or no border at all.
 
I may also release a version 1.4 of the library, with the latest fixes and these additions, while waiting for the more complex templated version (in another CVS branch). I wanted to do this but, as always, time is against us. Wink | ;)
I may however make a quick release and warn about possible incompatibilities, bugs and unfinished features (even if I don't like to publish unfinished or intermediate work).
 
Paolo
 
------
Why spend 2 minutes doing it by hand when you can spend all night plus most of the following day writing a system to do it for you? - (Chris Maunder)

GeneralRe: Replacing CDialog instancesmemberWolfSupernova1 Oct '03 - 9:19 
Good point. This probably deserves it's own article! After we get this all hashed out, I'll put one together, time permitting, and giving you both full credit and links of course. Wink | ;) In this case, maybe we should take this offline so we don't keep filling up your message board!
 
In terms of the WM_LBUTTONDOWN, I tried that but nothing happened because the grip (in this case) resides in the transparent part of the bitmap, so the event is caught and discarded before CResizableGrip::CSizeGrip has a chance to process it.
 

GeneralRe: Replacing CDialog instancesmemberWolfSupernova1 Oct '03 - 10:04 
Hmmm. What I just said wasn't true. I took out his event handler and the CSizeGrip WM_LBUTTONDOWN is still not picking it up.
 
I added a message box just to see if it was doing anything and never saw it with the left-click. Then, I tried WM_RBUTTONDOWN, and still no luck. Here's where I put it.
 
case WM_DESTROY:
// perform clean up
if (m_bTransparent)
SetTransparency(FALSE);
break;
 
case WM_LBUTTONDOWN:
// Left Mouse Button
MessageBox("clicked",NULL,MB_OK);
::PostMessage(m_hWnd, WM_SYSCOMMAND, SC_SIZE, 0);
break;
 
case WM_PAINT:
 

 

GeneralRe: Replacing CDialog instancesmemberPaolo Messina1 Oct '03 - 10:28 
WolfSupernova wrote:
Hmmm. What I just said wasn't true. I took out his event handler and the CSizeGrip WM_LBUTTONDOWN is still not picking it up.
 
Your code is correct, but I know why it doesn't work. My fix for the "focus problem" on the grip control includes returning DLGC_STATIC for WM_GETDLGCODE messages. Try removing that... I'll think about another fix if that works, or try experimenting with other return values.
It may also be the WM_SETFOCUS message, but the mouse messages should be posted to the control anyway, even if it refuses the focus.
 
Paolo
 
------
Why spend 2 minutes doing it by hand when you can spend all night plus most of the following day writing a system to do it for you? - (Chris Maunder)

GeneralRe: Replacing CDialog instancesmemberWolfSupernova4 Oct '03 - 14:15 
Hi Paolo,
 
I've tried this and a few other things and no luck, but I think I may be onto something. I've added a couple of buttons to my dialog with these functions.
 
void CSkinDialog_DemoDlg::OnBnClickedShowBorder()
{
CRect rect;
GetClientRect(&rect);
CResizableDialog::ModifyStyle(0,WS_THICKFRAME);
InvalidateRect(rect,TRUE);
SetWindowPos(this,-1,-1,rect.right+1,rect.bottom+1, SWP_NOMOVE|SWP_NOZORDER);
}
 
void CSkinDialog_DemoDlg::OnBnClickedHideBorder()
{
CRect rect;
GetClientRect(&rect);
CResizableDialog::ModifyStyle(WS_THICKFRAME,0);
InvalidateRect(rect,TRUE);
SetWindowPos(this,1,1,rect.right-1,rect.bottom-1, SWP_NOMOVE|SWP_NOZORDER);
}
 
This allows me to set it to resizable and show the border, and then set it back to not resizable and hide the border.
 
What I'm trying to do is make it a mouse-over event on the grip, so it's visible when the mouse is over the grip and dissapears when it's off, which should suffice although I haven't seen it in action yet. I think rather than the WM_LBUTTONDOWN, this could possibly be called from WM_NCHITTEST where you're setting the cursor type, but I'm having a little trouble with it. I don't get the same results calling it from CResizableGrip. Any ideas? Am I going down the wrong path?
 
Thanks again for all of your help. Smile | :)
 
Cheers,
Don
 

GeneralRe: Replacing CDialog instancesmemberPaolo Messina4 Oct '03 - 16:35 
Ok, I got some time on the weekend to try this out.
First, if you want no border at all you have to give up the caption either:
  ModifyStyle(DS_MODALFRAME|WS_BORDER|WS_CAPTION, 0);
  ModifyStyleEx(WS_EX_DLGMODALFRAME, 0);
Then, I tried to enable resizing using the grip (the only one left):
  case WM_LBUTTONDOWN:
    GetParent()->PostMessage(WM_SYSCOMMAND, SC_SIZE);
    break;
 
  case WM_SETCURSOR:
    SetCursor(AfxGetApp()->LoadStandardCursor(
      IsRTL() ? IDC_SIZENESW : IDC_SIZENWSE));
    return TRUE;
/* Remove this!
  case WM_NCHITTEST:
    // choose proper cursor shape
    if (IsRTL())
      return HTBOTTOMLEFT;
    else
      return HTBOTTOMRIGHT;
    break;
*/
As you can see the problem was in the WM_NCHITTEST handler that, returning a non-client code, somehow prevented the window to get the mouse click message. Good to know... Wink | ;)
 
Paolo
 
------
Why spend 2 minutes doing it by hand when you can spend all night plus most of the following day writing a system to do it for you? - (Chris Maunder)

GeneralRe: Replacing CDialog instancesmemberWolfSupernova5 Oct '03 - 9:32 
Perfect! I'm going to name my first three kids after you. Big Grin | :-D
 
I KNEW it was GetParent(). I was just using it wrong. D'Oh! | :doh:
 
Thanks a lot Paolo, sincerely. There's still a lot of work to do with this, as all of the skinning classes out there (the free ones) are pretty simple and only account for a background image, and don't take into account the resizing. I'd also like to incorporate the "snapping" effect as well.
 
So, since I'm going to have to do all this for my application anyway, I've decided not only to write an article on CP, but to start a skinning library project on sourceforge. If you can think of any ways of tailoring this for these purposes, other than what we've already tackled here, maybe some functionality that the skinning library won't need, or whatever, please let me know. I'd like to include your library in there with it. My email address is don.earnest@supernovasoft.com.
 
Thanks again!
Don
GeneralRe: Replacing CDialog instancesmemberPaolo Messina5 Oct '03 - 12:05 
WolfSupernova wrote:
Perfect! I'm going to name my first three kids after you.
 
Ok, but vary the name a bit or you're not gonna be able to call them. Wink | ;)
 
WolfSupernova wrote:
There's still a lot of work to do with this, as all of the skinning classes out there (the free ones) are pretty simple and only account for a background image, and don't take into account the resizing. I'd also like to incorporate the "snapping" effect as well.
 
You're right. They seem to think you would never want to resize a skin'ed window. The hard part would probably be the non-rectangular shape, but you may want to have a look at these GDI functions: BeginPath, EndPath, CloseFigure, PathToRegion, and of course SetWindowRgn.
Using those function you can create non-rectangular shapes, even with holes, just by using GDI drawing functions. It may also be possible, but I'm not sure, to use a metafile to create the path, and so the window region. Or you may create a 'script' file to issue drawing/path commands to render the region (something like SVG PATH elements). But maybe this is going too far... Wink | ;)
 
WolfSupernova wrote:
I've decided not only to write an article on CP, but to start a skinning library project on sourceforge.
 
That's great. And of course I'd be happy to modify the classes in ResizableLib to accomodate any need by your skinning library. As I said in previous posts, I'm rewriting the library to use templates, and that would definitely help you in the process, but although I have the CResizableDialog class transformed and working, the rest of the classes are not ready yet, and I won't have much time for that now, 'cause I'm also writing my thesis.
So I don't know what would be the best strategy now. It also depends on your timing: if you need this in short time, you can just use the old style library, that I'm wishing to maintain anyway (mostly bug-fixes, no new features), and have your project done.
Then, when I'll have more time, I could finish the template version and you could just port your code to the new version of the library. It shouldn't be much work initially, 'cause I'm keeping backward compatibility using some adapter classes.
 
If you want to switch the conversation to email, my address is in the source code. I just though it would be interesting for other people to know, but now it looks like we've come to the end.
No, wait... to a new beginnning! Big Grin | :-D
 
Cheers,
Paolo
 
------
Why spend 2 minutes doing it by hand when you can spend all night plus most of the following day writing a system to do it for you? - (Chris Maunder)

GeneralRe: Replacing CDialog instancesmemberCalder17 Jan '04 - 3:58 
Please let us all know where on SourceForge we can find the new project... Thinking about adding resizing to my App, based on a skinnable dialog...Smile | :)
GeneralNewsmemberPaolo Messina17 Jan '04 - 7:14 
As far as I know the skin-able version has not been published yet, but you should ask its author, not me.
As for my templated version, it's on SourceForge in the same repository of all my "Resizable" articles (see ResizableLib). The CVS branch is TEMPLATIZE, but it's not complete yet.
 
Paolo
 
------
Why spend 2 minutes doing it by hand when you can spend all night plus most of the following day writing a system to do it for you? - (Chris Maunder)

GeneralRe: Replacing CDialog instancesmemberEjaz11 Sep '07 - 3:29 
I know I'm too late, and Don, you'll not be interested in this, but I had similar needs recently. Here is how I did that (it may help someone else).
 
1. Remove WS_THICKFRAME style from CResizableDialog::OnCreate (line 82 in ResizableDaialog.cpp)
2. Set ShowSizeGrip( FALSE );, you may prefer to do that in the end of CResizableDialog::OnCreate
3. Handle NCHITTEST as following.
 
LRESULT CResizableDialog::OnNcHitTest(CPoint point)
{
UINT ret = CDialog::OnNcHitTest(point);
CRect rect;
GetClientRect(rect);
ClientToScreen(rect);
 
if ( rect.right - 10 < point.x && rect.bottom - 10 < point.y )
{
return HTBOTTOMRIGHT;
}
else if ( rect.right - 10 < point.x )
{
return HTRIGHT;
}
else if ( rect.left + 10 > point.x )
{
return HTLEFT;
}
else if ( rect.top + 10 > point.y )
{
return HTTOP;
}
else if ( rect.bottom - 10 < point.y )
{
return HTBOTTOM;
}
else if ( ret == HTCLIENT )
{
return HTCAPTION;
}
 
return ret;
}
 
Thats it, now inherit your class with CResizableDialog, and you don't need the boarders or thick frames to resize.
 
HTH,
 
Regards,
 
Ejaz.
 
Smile | :)

Generalcompiler errorsussGleason26 Sep '03 - 8:43 

I installed the latest sdk from ms. It was necessary to
add the lib and include directories to the project setup as extra directories in the project setup to get Visual Studio to know they are there. I was able to get past the undeclared identifier error by including this
 
#if !defined (WC_STATIC)
#define WC_STATIC TEXT("Static")
#endif
#if !defined (WC_LISTBOX)
#define WC_LISTBOX TEXT("ListBox")
#endif
#if !defined (WC_BUTTON)
#define WC_BUTTON TEXT("Button")
#endif
 
If I did not include the #defines, I still got the undeclared identifier error. If I include them without the #if, then I got a duplicate definition error.
 
Now I am getting
 
msvcrtd.lib(MSVCRTD.dll) : error LNK2005: __setmbcp already defined in libcmtd.lib(mbctype.obj)
LINK : warning LNK4098: defaultlib "mfc42d.lib" conflicts with use of other libs; use /NODEFAULTLIB:library
LINK : warning LNK4098: defaultlib "mfcs42d.lib" conflicts with use of other libs; use /NODEFAULTLIB:library
LINK : warning LNK4098: defaultlib "msvcrtd.lib" conflicts with use of other libs; use /NODEFAULTLIB:library
Debug/WSP.exe : fatal error LNK1169: one or more multiply defined symbols found
 
I have been through all the other messages and do not see where anybody else is having this problem.
 
Suggestions?
 
Thanks for your continued interest in this work.

 
Gleason
GeneralRe: compiler errormemberPaolo Messina26 Sep '03 - 9:10 
Gleason wrote:
If I did not include the #defines, I still got the undeclared identifier error. If I include them without the #if, then I got a duplicate definition error.
 
Well, that's weird. Maybe you just needed a Rebuild All, to recompile the precompiled header (included everywhere). If you have the latest SDK you shouldn't need the #defines. Try to look for them in the SDK headers (winuser.h)
Anyway I was thinking about adding something like that in stdafx.h, so people that don't have the latest headers can still compile the lib.
 
Gleason wrote:
LINK : warning LNK4098: defaultlib "mfc42d.lib" conflicts with use of other libs; use /NODEFAULTLIB:library
LINK : warning LNK4098: defaultlib "mfcs42d.lib" conflicts with use of other libs; use /NODEFAULTLIB:library
LINK : warning LNK4098: defaultlib "msvcrtd.lib" conflicts with use of other libs; use /NODEFAULTLIB:library

 
This probably means that you're using the wrong combination of runtime libs in your project and the library. I set up 4 build configurations (Debug, Debug Static, Release, Release Static) in ResizableLib. I know that if you have the same configurations in your project it should link without propblems. Or if you have VC++ 7 you can associate the configurations that you want built together.
Jsut check your project settings in the General tab (which MFC lib to use) and the C/C++ tab (code generation, runtime lib). They should match the settings in the associated configuration in ResizableLib. In VC++ 6 that means the configurations having the same name, as far as I know.
 
Gleason wrote:
Thanks for your continued interest in this work.
 
Yes, I'm still interested in this project. Especially if I can successfully make a port for WTL/MFC/SDK. There is still something to learn from this. And I hate bugs, so whenever people find one I have to fix it. I just hope I had more time for this. Smile | :)
 
Cheers,
Paolo
 
------
Why spend 2 minutes doing it by hand when you can spend all night plus most of the following day writing a system to do it for you? - (Chris Maunder)

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130516.1 | Last Updated 25 Jul 2012
Article Copyright 2000 by Paolo Messina
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid