In an C++ MFC project I'm using CMFCMenuButton using MSVC 2013.
When I toggle the high contrast mode the button is not properly repainted (for comparison a normal button is displayed):
Calling Invalidate() or ShowWindow(SW_HIDE);ShowWindow(SW_SHOW); seem to have no effect - even minimizing the dialog does not cause a proper redraw. How can I force the button to repaint with the updated system color?
Update: Forcing the colors after toggling contrast mode just makes the button text visible, however the button itself, the border, is not visible.
m_ctrlOkButton.SetFaceColor(::GetSysColor(COLOR_BTNFACE));
m_ctrlOkButton.SetTextColor(::GetSysColor(COLOR_BTNTEXT));
Took me a while, but I was able to solve this. I'm inheriting from the CMFCMenuButton class so that I can handle some events:
Get the color on the button right:Handle the WM_SYSCOLORCHANGE event and call GetGlobalData()->UpdateSysColors(); (make sure it's propagated to our parent before, e.g., by __super::OnSysColorChange();)
Get the border and background right:Handle the WM_THEMECHANGED event and call CMFCVisualManager::GetInstance()->DestroyInstance(); in order to close all opened theme data handles.
Related
I am using the following library call to change the window to dark mode:
BOOL dark = TRUE;
DwmSetWindowAttribute(hwnd, DWMWA_USE_IMMERSIVE_DARK_MODE, &dark, sizeof(dark));
This works, with a small caveat. The title bar doesn't update until some additional event happens, like maximizing, losing focus, resizing, etc. (but not moving the window).
I have tried UpdateWindow and a huge number of combinations of flags on RedrawWindow with no luck. How can I force the title bar to redraw?
Edit I was able to force the reset by programmatically resizing the window, then resetting it to the previous size. But that seems like a terrible method. There must be a proper solution.
I made a small video app with fullscreen support. While the video is playing I can push a button in my video controller and the app changes to fullscreen.
The strength thing is, when I'm in fullscreen the button has still somehow the focus in this way that when I move over it , it thinks I pushed (also the hover of the button is active even when I'm not over it with the mouse)
This behaviour end then up in a endless with to and from fullscreen when I'm not moving the mouse after pushing the button
I had here a similar problem in Qt4, but here the mouse over was only active after pushing
so perhaps somebody has an idea what's happening here, could not find anything in the Qt buglists
Georg
I don't know if it is a bug or an intended behaviour, nevertheless you may try to solve this problem in several ways. In the slot called whenever you change the size of the window, call one or several of the following QPushButton methods:
clearFocus() - that should make the button stop receiving keyboard/mouse input;
releaseKeyboard() and releaseMouse() should effectively do the same;
If you don't need the button while in fullscreen, you can also simply make it stop receiving any user input at all:
disable it (setEnabled(false));
make it invisible (invisible widgets don't receive keyboard/mouse input) by calling setVisible(false);
disconnect() the button and thus make it stop receiving any signals, and connect() it again after turning the fullscreen mode off.
Recently, I've got stuck over strange UI issue, found a solution, but still unsure about problem cause.
Preconditions:
MFC MDI application has 2 modeless dialogs opened, both has a child third-party grid and CToolTipCtrl. Dialog windows crosses each other borders (i.e. active dialog is overlapping part of inactive one). CToolTipCtrl is similar to example, the only tool set for tooltip is grid. Parent of tooltip is There is the corresponding dialog's grid, TTS_ALWAYSTIP style is set to allow tooltips on inactive dialog.
Issue:
When mouse is hovering on inactive dialog's grid, tooltip is appearing and inactive dialog is drawn over active one. In other words, inactive window is brought to top without activating. It's drawn completely, including caption, buttons, grid, etc.
I've checked Z-order and found that inactive dialog is still inactive, even when shown on top. No Z-order changed. Then I gathered message log using Spy++ for whole inactive dialog while tooltip is appearing and found no WM_ACTIVATE, WM_FOCUS, WM_MDIACTIVATE, etc. Then I performed search about how to bring window up without activating and logged SetWindowPos calls - the only calls are performed for CToolTipCtrl's window. So, no SetWindowPos for dialogs called. No BringToTop() called as well.
Solution
I've changed tooltip's parent window from dialog's grid to dialog itself - and that fixed problem. However, I still have no idea what was happened and why changing parent attribute matters.
Question
Could anyone give me a hint about what I'm missing? Maybe, tooltip causes repaint of grid, and that repaint has a bug causing repaint over active window, but I haven't found any proofs yet.
Haven't found something specific about tooltip's parent property in MSDN as well. Maybe, I have to read somenting about Windows GDI?
I have a QMainWindow with three QPushButtons (arranged in a QVBoxLayout in a QWidget). All have the same properties, except objectName, icon and iconSize. All are enabled and have two icons, one for normal and one for disabled.
When I start my application, always the top most icon shows the disabled icon (but is working, so it is enabled) the other two are fine. As soon as a focusable control in that window gets the focus, the icon changes to the active one and everything is fine.
Calling update or repaint in the showEvent of the window doesn't help either.
I'm using gcc 4.8.1 and qt 5.1.0.
Any ideas how to handle this glitch?
Update: It gets more strange: Starting the program, the icon shows disabled, getting another application the focus, the icon shows enabled, bringing the window on top again without giving it the focus (e.g. by using the task bar) changes the icon back to diabled. Clicking a control in the window, which can have focus will fix it again.
Well, well I finally got it. I just set the focus manually in the code and realized, that the icons were set in a wrong way. If a button was currently focussed it displayed the disabled icon. I had messed up the different button states and too many states got the disabled icon.
I have a dialog box with a list box,slider and a button.
I tried to change the background color but I couldn't managed to change that, so i thought that if I add a "picture control" as a bitmap and put it in the background i will succed, but now the problem is that the "picture control" is on top of all the controls.
I tried to change the the tab control with Ctrl+d but it didn't change anything.
I also tried to use SetWindowPos to top or buttom but also it didn't change anything.
I noticed that if I click in the location of the button it's brought to the front as I want.
Is there any way to "click" all the controls at the begining? do i miss something in order to bring the control to the top?
If you need to change the background colour of the dialog box, you need to handle the WM_CTLCOLORDLG message and return the handle to a brush (if the brush is not a stock object, make sure you delete the brush after the dialog box is closed) -- or, you can process the WM_ERASEBKGND message and erase the background yourself.
I tried to change the the tab control with Ctrl+D but it didn't change anything. I also tried to use SetWindowPos to top or buttom but also it didn't change anything.
Ctrl+D does get you in reordering mode, however there is a more reliable way of checking. The dialog template is in text form in .RC file, where you can review the order of control with text editor and sort lines manually the way you wish. This will be the order of control creation and tab order as well. Sometimes it's even easier to reorder controls this way.
More to that, when your application is running, Spy++ SDK tool can enumerate windows and again it will give you window order for checking.
SetWindowPos with proper arguments changes Z-order of controls on runtime as well.