CDockablePane prevent from closing - c++

Can I hide close button from CDockablePane and prevent it from closing?
I cannot find CanBeClosed method in the headers that I've just googled.
I suppose I can use PreTranslateMessage to filter WM_CLOSE event. But I am not sure that this is correct solution.

I am not sure that the dockable pane is really closed, AFAIK it is only hidden when the close button is pressed.
Note: WM_CLOSE is not send via a a PostMessage, it is directly delivered to the window.
There are several ways.
Handle OnClose (WM_CLOSE) yourself in your derived CDockablePane
The virtual function OnPressCloseButton is called. You migh overwrite it.
In your parent frame class (usually your CMainFrame) handle AFX_WM_ON_PRESS_CLOSE_BUTTON, you receive this message with the lParam set with the pointer to the CDockablePane. Return non zero to prevent closing.
I think method 3. is the one you should use...

I'm not sure what version of Visual Studio you have, but, that method is defined and implemented in AfxBasePane.h. Since it's virtual, you need to override it to remove the button. Details are here on how to work with that method.

Related

MFC: How to catch set focus of each control of dialog in one function

I have "n" dialogs which have the same base dialog. Each dialog has its own controls
edit boxes
combo boxes
list controls
etc.
In base dialog, how do I set focus messages of each control and,for example, give a Message box with
text("Hello I got focus, my ID is %d")?
The easiest way is using the classical subclassing method. The problem is that WM_SETFOCUS is not pumped through the message Loop, so PreTranslateMessage will not help.
Thee are some nice classes that help to do additional subclassing without disturbing the MFC stuff.
Paul Di Lascia wrote CSubclassWnd. PJ Naughter wrote CHookWnd. And with the ATL has CWindowsImpl.
All this classes allow easy additional subclassing even if a window is already subclassed by the MFC.
You can use "standard subclassing" GetWindowLong/SetWindowLong too.
According to this SO article, you can hook the WM_SETFOCUS message.
You can get the Control ID by using GetDlgCtrlID with the hwnd returned by the hook.
But beware of popping up a MessageBox, that will change the focus and trigger your hook proc, making it go into a loop!
As Jerry already said make a hook, get parent window handler via GetParent() and SendMessage(hParentWND, WM_MESSAGE, lParam, wParam).
Of course, you should handle WM_MESSAGE in your parent window.
Btw, framework calls OnSetFocus function when window gained focus.

CHtmlEditCtrl::OnSetFocus not being called

I have derived the CHtmlEditCtrl, and want to be able to react when the control gets or looses its focus. However the standard MFC OnSetFocus and OnKillFocus handling routines are not being called.
I presume it has something to do with the control actualy being a wrapped ActiveX control.
I have tried giving it the WS_EX_CONTROLPARENT and WS_TABSTOP styles on creation as suggested here, but it did not help.
I found somewhere that I should make my control the event sink for HTMLDocumentEvents2, but I would rather avoid that if possible.
EDIT: Spy++ says I should be getting WM_PARENTNOTIFY and WM_MOUSEACTIVATE messages. However, my Derived Class receives absolutely no messages. I tried it with OnSize and OnCreate too. No message whatsoever is being sent. Any idea?

Preventing Mouse-wheel scrolling of controls

I am developing an application using the MFC library and I am currently trying to prevent the user accidentally changing one of the combo box controls when they are scrolling the mouse wheel.
I am looking for a solution without deriving a new class from the CComboBox class and preventing the mouse scrolling there.
My understanding of the system is that Windows passes the WM_MOUSEWHEEL message to the Combo box control which handles it (scrolling the combo box) and then this is propagated up the chain of parent controls (so them to my CFormView etc.), which means I cannot prevent the scrolling by capturing the event in my form view.
Does anyone have a solution to this problem? Thanks in advance!
You can always derive a control from CComboBox and trap the WM_MOUSEWHEEL message in the control itself. Then simply use your new derived combo box in your form view.
If you don't want to create a derived class (perhaps it's too big a change for your project), you can subclass the combo box and trap the WM_MOUSEWHEEL there.
Override the PreTranslateMessage handler in the main window class and look for WM_MOUSEWHEEL messages. Compare the pMsg->hwnd handle in PreTranslateMessage handler with the combobox handle, if found, filter the messages away.

MFC: Capturing Resizes

Just wondering where is best to put functionality in an MFC application that is triggered when the whole window is resized. I was thinking mainfrm but I couldn't seem to capture any OnSize messages...
Can someone tell me what I am doing wrong?
Can someone tell me what I am doing wrong?
You didn't include any interesting details, so here are a few guesses (because of course the mainframe normally gets sent WM_SIZE messages...):
You didn't set up your message handler properly. Perhaps you forgot the message map entry?
You have an existing handler in place for WM_WINDOWPOSCHANGED that fails to call the default window procedure, thereby preventing WM_SIZE messages from being sent.
I am guessing that you are using the Multiple Document Interface ( MDI ) application type. In this case, you should capture the WM_SIZE message in each of your views - the classes you have derived from CView.

Parent notification in MFC Dialog

I have a first dialog with a simple button on it and while clicking the button, a second dialog is created using CDialog::Create(IDD,this). I would like the parent to be notified when the second dialog is destroyed but without adding any code to the second dialog i.e., without adding a m_pParent->Notify() line in OnDestroy method.
I have tried OnParentNotify, PreTranslateMessage, SubclassWindow in the parent dialog with no success. I have not used the WS_CHILD style for the second dialog. Any idea?
To complete: in fact, I have a ComboBox derived class (but the issue is the same with buttons) and I'm displaying a modeless Dialog instead of displaying the listbox. But I would like the control to be as generic as possible so that any modeless dialog could be used. That's why I do not want to add a specific notification in the second dialog. If I'm obliged, I will use this trick but I asked for a more generic solution. PreTranslateMessage only catches WM_PAINT, WM_NCMOUSELEAVE and WM_NCMOUSEMOVE.
Use a base class and have your parent refer to the modeless child by base class only. In the base PostNcDestroy have it post to the parent.
It doesn't make sense to have the parent do a bunch of filtering / spying on all messages. It does make sense to implement behavior in a base class that you want to have common to all the different future flavors you might have of the modeless child.
OnParentNotify() is not called since dialog2 is not a child of dialog1.
PreTranslateMessage() should help here (although I don't like this bullet). The trick is that a modeless dialog doesn't destroy itself when it's closed. If you want the dialog to die, it must call DestroyWindow() when it closes, such in an OnCancel() override.
Of course, the first thing that comes to mind is t wonder why you don't want to add custom notification in your modeless dialog code.
EDIT: Another method would consist in installing a message hook (for the current thread, Not the whole system!). This would help you catch all messages for all windows associated to the same thread as dialog1. See SetWindowsHookEx()
How about posting a main parent form event to the message queue?