I'm writing a notepad program in MS C++ 2010 Express with Win32. So far whenever the user opens or saves the document, it updates the status bar with the saved / opened filename. I also want to change the status bar to the current filename everytime a different MDI is activated. How would I do this?
Your MDI child windows will get WM_MDIACTIVATE messages whenever their activation state changes - you then just have to pass that notification back to your top-level window in some way (via a custom message probably - you could even send the filename at the same time) to get it to update the status bar.
By the way, the MDI concept is more or less deprecated and Microsoft advise against using it in new applications:
Many new and intermediate users find it difficult to learn to use MDI
applications. Therefore, you should consider other models for your
user interface. However, you can use MDI for applications which do not
easily fit into an existing model
For a notepad-type application the "modern" way to do this would be via a tabbed interface.
This is what you need.
Send WM_MDIGETACTIVE to the current client to ge the active client.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms644915%28v=vs.85%29.aspx
Related
Good day, fellow stackoverflow users. I have a problem using Vaadin TestBench in order to test a sub-window.
To be more specific, I've programmed a "popup" window that will be invoked by the main application when such application fails for whatever reason. As this sub-window doesn't have an URL, it will simply be invoked programmatically. I'm having problems coming up with a way of testing this single sub-window, as I have searched and read the Vaadin documentation, but all examples I see involve creating a driver for a certain browser, invoking a URL, accessing its elements and then doing the tests.
All I want is something like this:
Window popup = new Window() // Create sub-window (popup) programmatically
// instead of navigating to an URL with a web driver
// Here, I select the elements of the popup and do actions on it
// programmatically
...
// End the test and close the popup window
popup.close()
Is there a way of accomplishing this feat? I'm using the latest version of Vaadin on Springboot.
Vaadin Testbench and Selenium use the same base. You can reach the popup in the same way you do in Selenium:
driver.switchTo().activeElement();
or (if it is an alert)
driver.switchTo().alert().submit(); //submit = click OK, maybe it differs from your intention
If your "popup" is a separate browser window, you can switch by windowHandle.
driver.switchTo().window();
Hope this helps :)
A bit of background:
I need to embed a webview of some kind into a Qt application (that embeds python/PyQt) in order to display some html content. I am stuck with the MinGW build of Qt because that is what the Windows version of our software is built with and it is not feasible to migrate over to Visual C++. Unfortunately for me, QtWebKit has been removed from recent versions of Qt and its replacement, QtWebEngine, is not supported by the MinGW builds of Qt.
It appears my remaining options are one of
Maintain a custom build of Qt that reincludes the old QtWebKit code.
Embed some other rendering engine.
Launch a web browser in a separate process and embed its window in the main program.
I have looked into the first two options, and both sound like a bit of a PITA with a combination of outdated/abandoned code, and complicated build processes with patchy/outdated/conflicting documentation, and limited Windows support.
I've decided to explore the option of embedding a web browser process into my application. I've been successful at getting a firefox process embedded in PyQt using QWindow::fromWinId and QWidget::createWindowContainer
self.process = QtCore.QProcess()
self.process.setProgram('C:/Program Files (x86)/Mozilla Firefox/firefox.exe')
self.process.start()
time.sleep(1)
hwnd = get_window_handle(self.process.processId())
ext_win = QtGui.QWindow.fromWinId(hwnd)
widget = QtWidgets.QWidget.createWindowContainer(ext_win)
widget.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.ForeignWindow)
self.layout().addWidget(widget)
I can drag and drop html files into the embedded firefox window and they load just fine. I thought I might be able to exploit this feature by faking drag/drop events in order to programatically load files.
def fakeDragDropEvent(self, urls):
point = QtCore.QPoint(self.width()/2, self.height()/2)
self.mimedata = QtCore.QMimeData()
self.mimedata.setUrls(urls)
dragevent = QtGui.QDragEnterEvent(point, QtCore.Qt.CopyAction, self.mimedata, QtCore.Qt.LeftButton, QtCore.Qt.NoModifier)
app.postEvent(self, dragevent)
time.sleep(0.1)
dropevent = QtGui.QDragEnterEvent(point, QtCore.Qt.CopyAction, self.mimedata, QtCore.Qt.LeftButton, QtCore.Qt.NoModifier)
app.postEvent(self, dropevent)
These fake events can be picked up by the main window etc when I implement event handlers and set acceptDrops(True), however they seem to have no effect on the embedded process window.
Is there any way to make my embedded process window pick up these events? Or do I maybe need to program the drag/drop events using the native Windows API instead?
I'm also open to any other suggestions about how I can display html in my application.
I am having an app with a dialog. I would like to know when an extended monitor is unpluged so I can move the app window to the primary monitor, if the app was in the extended one.
I would also want to know when the user is making changes with the extended monitor position.
Is there a WM message that is posted to the window when this happens.
I'm building my app in Visual Studio C++, using the standard WINAPI.
According to this;
The WM_DISPLAYCHANGE message is sent to all windows when the display
resolution has changed.
I'm not familiar enough with this to tell you how to use it though.
I have created a Dialog using WTL, inheriting from CDialogImpl class, inside the main dialog I have created another dialog and inside this second child dialog a list control. I wanted to add drag& drop functionality to the list control, I have read on the web about the WM_DROPFILES method and about the Ole Drop Target, I have chosen the later one.
I have implemented the IDropTarget interface methods in accordance to this.
I have set the accept files option to TRUE in all my dialogues, I have instantiated the IDropTarget in the child dialogue class and called the following methods in its WM_INITDIALOGUE handler:
//drag& drop
lpDropTarget = (LPDROPTARGET)new TDropTarget(m_hWnd);
CoLockObjectExternal(lpDropTarget, true, true);
// register the HWND as a drop target
RegisterDragDrop(m_hWnd, lpDropTarget);
lpDropTarget is instantiated as follows:
LPDROPTARGET lpDropTarget;
And that's about it. Haven't really used Ole before so I have tried the following scenarios in search of luck:
I have registered with RegisterDragDrop for the List control HWND and set it's parent dialogue to receive the notification WM_OLEDROP WM_USER + 1 that I send. Ok the cursor for drag & drop showed but no calls to the implementation of the functions of IDataTarget.
RegisterDragDrop for child dialogue & notifications for it also.
RegisterDragDrop for the main Dialog & notifications for it also.
In the later cases ( 2 & 3) the cursor for drag& drop didn't even appeared, it showed me the no-drag & drop allowed one.
Now, all the dialogues and list control have been set to accept files from the visual studio designer.
I am limited to using only ATL /WTL/WINAPI, no MFC.
What am I doing wrong?
For you WM_DROPFILES is the only thing you need to handle. No need to fiddle with IDropTarget etc.
If your application does not need to run in Admin mode, do not run it in admin mode. Disable the linker setting for the same (UAC Execution Level = asInvoker). Also, run VS in non-Admin mode, so that your application also starts are non-Admin process. This way, Explorer.exe would be able to send WM_DROPFILES message to your application.
If your application need to run as Admin mode, you need to allow other applications to send set of few messages to your application (window). Do the following:
ChangeWindowMessageFilter(WM_DROPFILES, MSGFLT_ADD);
ChangeWindowMessageFilter(WM_COPYDATA, MSGFLT_ADD);
ChangeWindowMessageFilter(0x0049, MSGFLT_ADD);
You may also want to use newer function: ChangeWindowMessageFilterEx.
Note that, if your application must run as Admin, and you need to dynamically locate one of these function using GetProcAddress, so that your application can run on OS where this function is not available (eg. Windows XP).
I am new to MFC well not entirely new but wanted to ask experts on this forum as why one would choose one project over the other. I hope this is not a stupid question as I am relatively new to MFC.
Thanks so much
Chose based on what template your application fits best into:
Single Document Interface (SDI) - if your application needs to work with only 1 document or data object or data set at a time
Example: notepad.exe
Multiple Document Interface (MDI) - if your applicaiton needs to work with multiple documents or data objects or data set at a time
Example: Visual Studio
Dialog Based - for anything else.
Example: Calculator
No matter what you chose, you still have the same functionality available to you in the end and you can cusotmize it in any way. So you aren't limiting yourself to anything you start with.
All variants come with CWinApp which is the base class for which you derive your MFC applications.
With a dialog based application you start with a CDialog as well. With an SDI application you start with CMainFrame, CDocument, and CView as well.
If you select an SDI project you get a whole Model-View-Controller framework included.
You get a document class (inheriting from CDocument) which ideally should hold all of the data, and a view class (inheriting from CView) to do with the display.
You get given a hosting frame with a menu already attached, and there are functions you can override to save and load to file.
If you have a dialog based application, then you get one dialog. That's it. Of course, this dialog can spawn off others, but the application essentially consists of a dialog.
If you're developing a small application that just does one task, a dialog application is appropriate, because you don't need the overhead.
If you are developing an application where the user will be loading, editing and saving data, then the SDI path would be more appropriate.
Having answered your question, I'd politely ask if there was a compelling reason why you were choosing MFC over Windows Forms. I believe that MFC was an excellent technology for its day, but the Visual Studio suite offers more advanced tools (if you're prepared to go down the .NET path).
If a "document" is the right metaphor for your application, use SDI or MDI. (Single of only one document can be open at a time, Multiple if more than one.) When you think about it, the document metaphor really isn't appropriate for most applications.