Completely disabling the grip in a CStatusBar - mfc

I have a CListCtrl that creates a child CStatusBar (for displaying statistics etc).
All works fine (except for when using CMFCTabCtrl, but that's another story).
When I use this CListCtrl in a resizable dialog, it appears the framework signals the CStatusBar to automatically add a SBARS_SIZEGRIP, which I do not want.
Any ideas on how to disable this behavior for my CStatusBar?

If you use a CStatusBar SBARS_SIZEGRIP style is added when the parent frame has the style WS_THICKFRAME (see source code VC\atlmfc\src\mfc\barstat.cpp CStatusBar::CreateEx).
It should be easy to prevent this when you overwrite PreCreateWindow and remove this style.
Note that the behaviour of CMFCStatusBar is different.

Related

Create a property sheet using a dialog template

I need to extend an existing MFC app with a UI that will end up very cluttered unless I use a tab control. However, the nature of the UI is that there are some controls that are global, and only some that can be localised to a particular tab.
The standard use of tab controls (CPropertySheet + CPropertyPage) more or less expects there only to be CPropertyPage instances (tabs) visible on the CPropertySheet object, and nothing else. There is a Microsoft Example Project that shows a single additional window painted outside the area occupied by the tab control... but it's not immediately clear how it is created/drawn/handled, and it is only one single additional window that generates few events (I guess it is painted, so there must be a WM_PAINT event handler lurking somewhere).
Is it possible to lay out a bunch of controls with the MS Dialog Editor, including a tab control, and create the CPropertySheet using that template, hook up event handlers in a nice way, etc... or some equivalent way of getting the MFC framework to do as much of the creating, drawing and event handling as possible when it comes to a situation like this?
Yes it is possible to create dialog templates and use them in a CPropertyPage.
Each CPropertyPage behaves nearly like a dialog and handles all events for the controls on it.
Also there are features like OnApply that help you to manage the data exchange between the controls and your internal storage.
The central CPropertySheet only creates the dialog that get active. So OnInintDialog for a page is called the first time when the page gets active.
In the MFC since 2010 are more possibilities than a CPropertySheet. You can create tabbed views, that again may be CFormViews. I don't like CDialog based applications so I would prefer a tabbed view in a standard frame with toolbar and menus if appropriate for the application. So another method to unclutter your UI is to choose the MDI interface with tabbed documents... but multiple documents maybe isn't what you want.
Here is a sample of an SDI application with multiple tabbed views.
Also Coeproject shows some more samples here and with splitters and tabs here.
There are at least three solutions paths:
Try to squeeze the situation into the CPropertySheet + CPropertyPage framework which does not naturally allow for additional dialog controls on the CPropertySheet object, and so you will get no framework support this
Place a tab control on an ordinary dialog, and then use the TCN_SELCHANGE messages to fire code that manually hides & shows individual dialog controls subject to the tab control (again no framework support, but this time "within" the tab control instead of outside it)
Follow Mark Ransom's observation that if you can embed one kind of CWnd-based control on a CPropertySheet then you can probably embed any such object, including a CDialog-based object that has been developed in the MFC Dialog Editor
All of these approaches are going to encounter challenges, and it will depend on the specifics of the situation as to which is better. But first you should really consider whether there is a cleaner UI design which would lend itself to a simpler solution.
In my specific case, I saw no cleaner design alternatives, and found it easiest to take the second approach. It left me with some reasonably simple calls to ShowWindow() to show/hide the controls inside the tab control.

Is it possible to change the location of the main top-level menu in an MFC MDI app?

I have an app with a customized frame (i.e., caption/titlebar, borders). I customized the frame by removing the WS_CAPTION style, and overriding OnNcCalcSize to reserve a custom-sized area for the caption, which the app paints in OnNcPaint.
A side effect is that the menu bar no longer displays, which is OK because I want to customize the appearance & location of the main menu. Unfortunately, I don't know how to do that. I would like the "File" menu to be further from the left edge than it is with the standard menu bar.
An acceptable alternative would be to remove the menu entirely, and use OnNcHitTest, OnNcPaint and OnNcMouseMove to manage a hand-coded replacement for the top-level menu.
I've never seen a way to modify the looks of the standard menu. You can remove it (remove the creation code from your InitInstance) and then code a replacement. I wouldn't do that in OnNcXXX though, rather make a new custom control that you position at the top. Or you could have a look at the MFC Next themed menus and write a custom UI renderer. It may be enough to override a few functions left and ride to set the alignment of the menu.
It's an MFC MDI app -- InitInstance is not where the menu is being created. I have tried to get rid of the menu (and succeeded, temporarily) but the MFC framework seems to be "putting it back" -- I think the MDI model has the child windows modify the menu, but the code that does that seems to be buried in the framework somewhere (or else I just haven't been able to find exactly where it happens in the application's code, but I suspect it's happening inside the MFC framework code). If I knew where, I might be able to override the methods(s) and take control... I think.
What would be the reason to write a custom control vs. handling OnNcMouseMove & OnNcLeftButtonDown, e.g.? I don't expect to need the functionality in any other app (a new app would be coded in C#, probably), so I'm looking for ease of implementation, not code reuse.

MFC: 'Gluing' two windows/dialogs together

I'm trying to set something up so my main dialog has one or more child dialogs, and these are glued/docked to the outside of the main dialog - when the main dialog is minimised, the children are too, when main dialog moves, children move with it.
I'd tried setting child dialogs as having main dialog CWnd as parent, with CHILD style. But then they get clipped by the parent's boundary. If I set them as POPUP, they can be outside but then don't move with the parent.
I'm looking at putting an OnMove handler on the parent dialog, but is there something built-in? And, should child dialogs still be children of the main dialog... I assume they should?
This is VS2005 (I think VS2008 has some related functionality so I mention this).
You need to implement the movement manually when they are popups, and yes they should be popups otherwise they will be clipped out.
I'm new to SO. Not sure if I can refer to an external article.
I guess this is what you are looking for.
I started to write this class because
I'm often in need to popup additional
dialogs around the main one. Often
these dialogs can give some trouble to
the user; for example, he must
move/close them one by one... A
solution that could give the
application a more solid aspect and
that could make the management of the
various windows easier could be, to
dock all dialogs side by side (like
Winamp does, for example).
As Roel says, your extra dialogs will need to be popups. I'm interested: what kind of UI is this? Is it WinAmp-style, where the windows snap to eachother?
Or are you doing some kind of expanding dialog? If it's an expanding dialog (with a More>> button on it, e.g.), then you can put all of the controls on the same dialog and play with the window rect when showing/hiding the extras.

How to get the minimize and maximize buttons to appear on a wxDialog object

I've run into an issue using a wxDialog object on Linux In the construtor for the object I pass the relevant style flags (wxCAPTION|wxMINIMIZE_BOX|wxMAXIMIZE_BOX|wxCLOSE_BOX|wx_RESIZE_BORDER) but the buttons don't show up. When I was designing the class in wxformbuilder they would appear on the displayed design but don't show up in my running application.
I'm using wxWidgets 2.8.7 at the moment and running on Scientific Linux 5 (RHEL 5). Any suggestions or ideas on how to work around this?
EDIT: BTW, This is related to this question
If you create a dialog on wxGTK then during construction
gtk_window_set_type_hint(GTK_WINDOW(m_widget), GDK_WINDOW_TYPE_HINT_DIALOG);
is called, which leaves it up to the window manager what decoration is shown for this window. So if you give it the style but no buttons are shown, then there's nothing you can do. In any case, I think showing a wxFrame while the parent frame is disabled should work just as well.
Can you use a wxWindow instead of a wxDialog? Maybe it doesn't make sense to minimize a dialog but those are usual operations for application windows.

Dynamically resizing CMFCPropertySheet with PropSheetLook_OneNoteTabs style

I'm trying to resize dynamically a CMFCPropertySheet to add a custom control at the bottom of each page.
As all Property Pages are not of the same height, I have a mechanism to increase the size if necessary.
For this, I have overridden the OnActivatePage method and by using SetWindowPos, I can resize the sheet, first, then the tab control, then the page and finally I can move the OK/Cancel/Help buttons.
It works fine with PropSheetLook_OutlookBar and PropSheetLook_Tabs styles but not with PropSheetLook_OneNoteTabs style. The page (or the tab) is not correctly resized (the lighter grey color of the page does not fill the sheet.
OneNote style OneNote http://www.freeimagehosting.net/uploads/th.ec91600664.jpg
Outlook style Outlook http://www.freeimagehosting.net/uploads/th.319b6938ab.jpg
Any idea? A MFC Feature Pack bug?
I found the problem. One needs to get a reference to the different tab control the OneNote version uses via GetTab() and resize it accordingly.
Just follow the instructions as seen in here.
Although the instructions are for CPropertySheet they work for the CMFCPropertySheet as well.
Some parts of the code is deprecated so you will need to make the following amendments.
Skip the XmnPropSheetCallback and DoModal implementations completely
In OnInitDialog just make a call to CPropertySheet::OnInitDialog(); and then call OnSize instead of doing everything presented in that code.