User-Interface: Best way to toggle MDI frame's on-top status? - mfc

I maintain an MFC (VC6) MDI application that uses Frame Windows as views for a document. There is only one document at a time but there are several MDI-Frames each with a different view of the document data.
Recently a request came up to be able to keep one of those frame windows on top of the others while being able to interact with the background windows.
One idea was to add a "pin-button" to the frame's title bar. During my research I found out that every implementation uses bitmaps instead of for example CButton objects. This starts to get ugly as soon as one uses window colors other than the default-grey let alone UI-Themes.
An option in the menu of the frame window (the thing that appears when left-clicking the window icon in the title bar) would be possible but I'm searching for something that is more obvious to the user.
What other possibilities to set this frame window's on-top state are there?
Update
I have decided to go for the solution suggested by Uli as that one works fine with the XP themes.
Unfortunately this directly lead me to my next question: How can I actually make the frame window stay on top?

Maybe this or this helps.
Uli

Related

Colorizing the titlebar in macOS with multiple colors

I have a Qt app that runs on macOS. I found a way to change the color of the titlebar here, however I want to take it a step further. I want to mimic the titlebar that the Slack and Discord apps use. For example:
As you can see, the color of the controls in the window extend to the very top of the app's window. I figure there are two ways to accomplish what I want:
I can build on the code pasted above. Looking through some of the Apple developer documentation, I think I can create a couple NsWindows on top of the titlebar with whatever width I want and attach the titlebar as a parent for those windows. Once I do that I should be able to make the same backgroundColor() color call for each one. Of course, this will require me to keep track of when the controls or window are resized and adjust the NsWindows of the titlebar, and I am not sure what (if any) issues that could cause.
Maybe there is a way to essentially set the height of the titlebar to 0? I wonder if that's what the Discord app is doing because:
if you look closely, the edit box that says "Find or start a conversation" is vertically lined with the close, minimize and maximize buttons, as is the "Activity" label. But if the controls do extend to the top of the app's window then how are the standard app buttons getting painted?
I'd be curious to know how Slack and Discord accomplish this even though I know they're not using Qt.
I realize there is not a Qt solution since Qt does not paint the titlebar. I know this will be OS-specific, but since I do not have any real experience with Objective-C++ or working with Cocoa (all of my programming experience on macOS has been standard C++ with non-UI or Qt-based code) I'd appreciate any suggestions or guidance!
Natively this is done with fullSizeContentView and titlebarAppearsTransparent properties of NSWindow. Once you set them to true, you can draw or place controls beneath the title bar.

Multiple Documents/Views in MFC Splitter Window

I currently have an MFC SDI program that displays data in Open GL. I am trying to modify the program to display multiple data files at once using splitter windows. In other words, if there are four splitter windows, each with display a different file.
So far all the examples I have found only display one document in multiple views, but I need to display multiple documents at once.
I am starting to conclude that the problem may be because this is an SDI interface. I guess I originally thought that since I was using splitter windows that it would support multiple documents at once.
So my first question is, is the SDI interface the problem? Am I limited to just one file at a time?
If the answer is that I need to use MDI, then can I display the multiple documents in one MDI view using splitters, or do I have to still open multiple MDI windows?
Thank you
I think creating multiple MDI-child windows should be very acceptable, as they are fully functional (they can be maximized, closed or tiled). You can also post a Window->Tile command, as soon as your app enters the idle state (yields); they will fully occupy the client area. You can even get deeper and provide some customizations to your CMDIChildWnd-derived class, like disabling closing, moving or resizing, or having a shorter or custom or no title bar (you may need to customize the non-client-area message processing). Also experiment with the WS_EX_TOOLWINDOW extended window style (not sure if this works well with MDI child windows though, and you will have to test it under at least Windows 8/10 and 7).
Another solution could be initially create an MDI app with tabbed views, and customize the window accommodating the tabs so that they are not... actually tabs, just simple non-overlapping child windows (you will have to arrange them on the client area yourself). This may be preferable if the view wnidows are of "fixed" size (either a set size or determined by the document data, eg image size) and should not be resizable (by the user). The MainFrame window should then be customized too, to display scroll-bars if the area required to display all views exceeds its client area. This is a lot of work though, as you will need to modify the window classes so as to provide a functionality MFC was not originally meant to support, and dig deeply into the MFC sources.
This is an old question but for those who might want to do the same thing, MFC does support the scenario mentioned. From the Microsoft documentation:
MFC supports three common user interfaces requiring multiple views on the same document. These models are:
View objects of the same class, each in a separate MDI document frame window.
You might want to support creating a second frame window on a document. The user could choose a New Window command to open a second frame with a view of the same document and then use the two frames to view different portions of the document simultaneously. The framework supports the New Window command on the Window menu for MDI applications by duplicating the initial frame window and view attached to the document.
View objects of the same class in the same document frame window.
Splitter windows split the view space of a single document window into multiple separate views of the document. The framework creates multiple view objects from the same view class. For more information, see Splitter Windows.
View objects of different classes in a single frame window.
In this model, a variation of the splitter window, multiple views share a single frame window. The views are constructed from different classes, each view providing a different way to view the same document. For example, one view might show a word-processing document in normal mode while the other view shows it in outline mode. A splitter control allows the user to adjust the relative sizes of the views.
Microsoft MFC references
https://learn.microsoft.com/en-us/cpp/mfc/multiple-document-types-views-and-frame-windows?view=msvc-170
https://learn.microsoft.com/en-us/cpp/mfc/multiple-document-types-views-and-frame-windows?view=msvc-170#_core_splitter_windows
MFC samples
https://learn.microsoft.com/en-us/cpp/overview/visual-cpp-samples?view=msvc-170#mfc-samples
MFC splitter sample
https://github.com/microsoft/VCSamples/tree/master/VC2010Samples/MFC/general/viewex

Change the icon on windows 7 taskbar for a pinned application

My software Pomodoro Timer is going to display a dynamic icon on Windows 7 taskbar. You may wonder why the application icon need to be dynamic. It's actually a counting down timer for me to help me focus on current task, so called the pomodoro technique:
My way to change the icon is to simply change the Window icon. It works fine when I start the application, but after I pinned it to taskbar, it will display the default icon for the application. The dynamic counter down number will disappear. More worse, after I unpinned it from taskbar, the default behavior will never be recovered, that is, the dynamic icon will not able to be updated correctly. When I start the application again, it will display the default icon, unless I pinned it and unpinned it again, the counting down icon displays again.
I've searched this forum, and Change pinned taskbar icon (windows 7), and tried to change the overlay icon. It works, but not fulfill my requirement, the overlay icon can only display 16x16, and no enough room to display 4 digits.
I also read the MSDN article Application User Model IDs, but i am still not clear whether it can make it or not.
Anyone can help on this? Thanks a lot!
Windows 7 supports having a green progress bar be shown over an icon, and pinning doesnt effect the progress bar. So, instead of changing the icon every second, why not change it every few seconds, but have the progress bar count down from 100% of the original set counter value?
The pinned items in the Taskbar are stored as a shortcut at:
%appdata%\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar
You can try changing the icon of the Shortcut of your program.
My final solution is:
on Windows: use icon overlay. You can get more screen shots here.
on Mac: use different icon. You can get more screen shots here.
I use different solution for Windows and Mac.
Generally an application would make use of the System Tray to show interactive state such as this to the user. There is a whole API set for interacting with it, setting icons, menus, providing text feedback (balloons), and so on.
The following is a good article on how such functionality can be achieved:
http://www.codeproject.com/Articles/74/Adding-Icons-to-the-System-Tray

How to create a GUI without a frame in X11?

I'm trying to figure out how to create a graphical interface, in X11, which exists outside of a window manager's/desktop environment's standard window frame. For example, when Thunderbird finds new mail, it shows a special alert in the lower right hand corner of the screen which is shown without any frame (no close/minimize buttons, etc.).
I'm specifically interested in doing this in QT with C++, but if someone knows a solution with a different graphical library, that would be helpful too.
For QT pass Qt::FramelessWindowHint as a window flag when you construct your top level widget.
See here for more info:
http://doc.qt.nokia.com/main-snapshot/qt.html#WindowType-enum
You can do this with X as well although I haven't done so in a long time.
http://www.xfree86.org/current/XCreateWindow.3.html
With GTK you would use gtk_window_set_decorated(), which would probably be Gtk::Widget->set_decorated() (I think, I don't use gtkmm).
http://developer.gnome.org/gtkmm/unstable/classGtk_1_1Window.html#a67adb1d8051a38e0e5272f141bb8778c

How to draw text on the desktop in Windows?

How Would I go about placing text on the windows desktop? I've been told that GetDesktopWindow() is what I need but I need an example.
I'm assuming your ultimate goal is displaying some sort of status information on the desktop.
You will have to do either:
Inject a DLL into Explorer's process and subclass the desktop window (the SysListView32 at the bottom of the Progman window's hierarchy) to paint your text directly onto it.
Create a nonactivatable window whose background is painted using PaintDesktop and paint your text on it.
First solution is the most intrusive, and quite hard to code, so I would not recommend it.
Second solution allows the most flexibility. No "undocumented" or reliance on a specific implementation of Explorer, or even of just having Explorer as a shell.
In order to prevent a window from being brought to the top when clicked, you can use the extended window style WS_EX_NOACTIVATE on Windows 2000 and up. On downlevel systems, you can handle the WM_MOUSEACTIVATE message and return MA_NOACTIVATE.
You can get away with the PaintDesktop call if you need true transparency by using layered windows, but the concept stays the same. I wrote another answer detailing how to properly do layered windows with alpha using GDI+.
Why not just draw the text in the desktop wallpaper image file?
This solution would be feasible if you don't have to update the information too often and if you have a wallpaper image.
One can easily use CImage class to load the wallpaper image, CImage::GetDC() to obtain a device context to draw into, then save the new image, and finally update the desktop wallpaper to the new image.
i haven't tried but i assume you could do the following:
use GetDesktopWindow to retrieve the handle of the desktop window
use SetWindowLong to point the windows message handler to your own procedure
in your proc, process the WM_PAINT message (or whatever) and draw what you need.
in your proc, call the original message handler (as returned by SetWindowLong).
not 100% sure it will work, but seems like it should as this is the normal way to subclass a window.
-don
If your intent is to produce something like the Sidebar, you probably just want to create one or more layered windows. That will also allow you to process mouse clicks and other normal sources of input, and if you supply the alpha channel information, Windows will make sure that your window is drawn properly at all times. If you don't want the window to be interactive, use appropriate styles (such as WS_EX_NOACTIVATE) like Koro suggests.