My program/environment...VS2010, C++, MFC100, CWinAppEx, CMDIFrameWndEx. MFC feature pack.
I am creating and handling a CPreviewView derivative. My method treats this preview view as a normal view that the user can keep up and active. Where as the default PreviewView paints over the current view and 'takes over' the child frame.
One thing I can't figure out is how to gain control over the ON_UPDATE_COMMAND_UI message maps that should be directed to all CDocuments. When a CPreviewView is created it somehow disables all the command handlers to CDocuments. The command handlers to CViews are still up and working.
All Documents open in my MDI app don't receive their ON_UPDATE_COMMAND_UI messages. I can move these message handlers out to the View, or Frame but there are too many to do this efficiently.
Does anyone know where in the CPreviewView class turns off document handlers?
First of all, MFC is not a "locked" framework. Its complete source resides on your own PC in the following folder: "your Visual Studio folder"\VC\atlmfc\src\mfc\ (on my PC it is: c:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\atlmfc\src\mfc) The source for CPreviewView is in viewprev.cpp file. I just opened the file and in the DoPrintPreview they are calling this:
pParent->OnSetPreviewMode(TRUE, pState); // Take over Frame Window
According to MSDN this method:
The default implementation disables all standard toolbars and hides the main menu and the main client window. This turns MDI frame windows into temporary SDI frame windows.
I have opened the file called winfrm.cpp and checked that this method is doing, and it does disable all the menu. Obviously, no Update messages will be sent to documents while preview mode is on.
The MSDN article at the hyperlink above says that you need to override the OnSetPreviewMode method for your frame to:
customize the hiding and showing of control bars and other frame window parts during print preview. Call the base class implementation from within the overridden version.
This should not be a problem.
Related
I just started the GUI development, i had started on C++Builder but i switched to Visual Studio for differents reasons. But in Visual Studio, i've got a big problem :
In the GUI development interface (rc file) i can create buttons and place it, but i can't change there names. The name for all of MFC components i placed is initialize to a default name which i can't call and i can't change the property by the properties interface, i can change the Text, for change the Label of the Button, but not the name...
It's very incomfortable because by that i can't call my buttons for do anything, i have the same problem for Listboxs, so i can't modify my list because i can't call there
I just want to modify access my component by my c++ code for modifying this component
enter image description here
Thank for your help !
The MFC way of doing event handling is a bit more elaborate.
After the control is created on the form in the designer, an ID is generated ("IDC_BUTTON1" in the attached screenshot).
This is the ID that will be used for accessing this UI control from the code.
All this can be done via the designer also as shown in this article.
Basically, in the background this generated ID is put in a 'message map'
(more about message maps here).
In short 'message map' is used to specify what action needs to be performed when a certain type of action is done on the UI control by the user.
For, example if the button click is to be handled then in code:
the message map would look like:
BEGIN_MESSAGE_MAP(CSurface3DView, CView)
ON_BN_CLICKED(IDC_BUTTON1, CallMyFunction)
END_MESSAGE_MAP()
'ON_BN_CLICKED' is a predefined event macro.
The 'CallMyFunction()' function has to be declared with 'afx_msg' in the class. Besides please, have a look at data exchange mechanism as well. This know-how about data exchange will come in handy going forward.
I have a multi-threaded application with several supporting DLLs and several popup dialogs. My Main App loads all DLLs on startup, which creates all popups, but they are kept hidden until needed.
When the user presses a button in the main app, a particular popup is shown (from the DLL) by calling ShowWindow( SW_SHOW ) (modeless)
Sometimes (1-in-10 times?) the popup simply fails to show and the Main App hangs. OnShowWindow of the Popup dialog is never called. I have tried calling ShowWindowASync instead, and it still fails to show the popup sometimes, but this call doesn't lock the Main App.
This problem only affects popups within a single DLL.
If the popup shows the first time ShowWindow is called, it can be closed and re-opened indefinitely throughout the lifetime of the Main App. If (using ShowWindowASync), the popup fails to show, it will never show during the lifetime of the Main App. I can re-run the application (without rebuilding anything) and there is a hit-or-miss chance that it will work or fail. I haven't been able to identify any predictive conditions or properties.
I have used tools to renumber all of my resource elements so that there are no conflicts throughout the solution.
UPDATE:
I used Winspector to get some information about the dialog when it does and does not work.
When the dialog works (shows properly), Winspector reports that my dialog has valid position (10,96, 1015, 514), style attributes that match the resource template, ID of 0 (not sure what ID means), and the "Owner EXE" is "MyApp.exe" - I can see many messages passing in and out of the dialog, including WM_SHOWWINDOW.
When the dialog fails (does not get a show window message), Winspector reports position (-1512, 190, -517, 634), style attributes that do not match the resource template, ID 509290824, and owner EXE is "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\devenv.exe" - I also do not see ANY messages in the message viewer within Winspector when the dialog fails to show.
Clearly, the dialog is not getting created correctly. CDialog::Create never fails for me. Additionally, I experience this problem in release (not using Visual Studio) so it's not a VS-specific problem.
The dialog was getting created from a thread that was not executing a message pump. This was the root problem. I had tried to initialize all dialogs (i.e. call "Create") from an "init" thread, and then use them later on in the winproc/GUI thread. Can't do this apparently.
A pointer to the dialog was then retrieved into the winproc/GUI (which has a message pump), but by that time, the dialog was already "corrupt" and no longer responding to winproc properly
I have the main window, and then the user can "pop up" one of the frames in the application so that it floats rather than being contained in the main window. There are multiple frames that can be popped up so that in a given time there might be three WS_POPUP windows.
The problem is when I want to show the modal dialog, I can only disable one of them using the parameter in the DoModal function. How can I disable all top-level windows using DoModal? I can't simply disable the windows before showing modal and then enable it back because There could multiple chained modal dialog (one modal dialog opens up another modal dialog).
Does the API provide a way to do something like this? I've googled this for two hours and can't find a good enough solution. I'm using a combination of MFC, WTL, and ATL.
Thanks in advance!
As I understand the problem, it is the same like the MFC frame windows work.
In fact only the CFrameWnd of an MFC application gets disabled. On arrival off the WM_ENABLE message (with FALSE) BeginModalState is called and this function just disables it floating "child windows" of the CFrameWnd.
Same again, when EnableWindow (WM_ENABLE arrives with TRUE) is called for CFrameWnd. EndModalState is called and all disabled "child and floating" windows are enabled again.
See the MFC implementation of CFrameWnd::OnEnable, BeginModalState, EndModalSTate in the source code.
So you main window knows it's own popups. Upon launching the true modal dialog, and disabling this parent, it will disable it's floating popups.
The trick is that CDialog::DoModal needs the real parent... if not given in the constructor it guesses the correct one in most cases. For your case it should be necessary that you provide your "main window" as the parent window... same for message boxes...
My question is :
what is the main difference between Common File Dialog and Common Item Dialog ?
The MSDN just said that :
Starting with Windows Vista, the Common Item Dialog supersedes the
older Common File Dialog when used to open or save a file.We recommend
that you use the Common Item Dialog API instead of the Common File
Dialog API.
but it has not explained that what is the change log or main difference between them ?
thank for any help.
Common File Dialog was just a custom DialogBog. On the other end, Common Item Dialog is a full COM server.
Microsoft's documentation says :
The Common Item Dialog implementation found in Windows Vista provides several advantages over the implementation provided in earlier versions:
Supports direct use of the Shell namespace through IShellItem instead of using file system paths.
Enables simple customization of the dialog, such as setting the label on the OK button, without requiring a hook procedure.
Supports more extensive customization of the dialog by the addition of a set of data-driven controls that operate without a Win32 dialog template. This customization scheme frees the calling process from UI layout. Since any changes to the dialog design continue to use this data model, the dialog implementation is not tied to the specific current version of the dialog.
Supports caller notification of events within the dialog, such as selection change or file type change. Also enables the calling process to hook certain events in the dialog, such as the parsing.
Introduces new dialog features such as adding caller-specified places to the Places bar.
In the Save dialog, developers can take advantage of new metadata features of the Windows Vista Shell.
Simply it is harder to use from a simple low-level Win32 program.
I am trying to upgrade my MFC MDI application to use the new MFC Feature Pack.
I converted the CToolbar to CMFCToolBar. Now I am trying to disable one item in the toolbar under certain conditions. I listened to the ON_UPDATE_COMMAND_UI message of the item's ID and disabled the item by writing the following:
pCmdUI->Enable(FALSE);
This works perfectly only if the ON_UPDATE_COMMAND_UI message was handled in the CView object but not if handled in the CMFCToolbar derived class.
If there a way to disable an item from the toolbar class itself?
The Toolbar is not part of the command routing in MFC. So it will never get the command and update command UI messages. You can see the command routing in detail here: MFC Command Routing
You could overwrite the OnCmdMsg() method in one of the objects which gets the command messages (as you can see in the link above) and pass the message on to the Toolbar.