MFC frame application not repainting when covered or shaken - mfc

I am creating a MFC frame based application for instrument monitoring/plotting/interaction, with several child windows hosted in a main frame. These child windows are all created by the main frame using:
MakeCommandsWindow("Child Window",
WS_VISIBLE | WS_CHILD ,
CommandsRect, this, NULL);
which calls this construtor:
BOOL Commands::MakeCommandsWindow(LPCSTR WindowTitle, DWORD dwStyle,
RECT& rect, CWnd* pParent, UINT nID){
CString CommandsWindowClass = AfxRegisterWndClass(
CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW ,
AfxGetApp()->LoadStandardCursor(IDC_ARROW));
CWnd::Create(CommandsWindowClass, WindowTitle, dwStyle,
rect, pParent, nID);
The application works well except in its handling on repaint events. When the application is covered by another window, and uncovered, it does not redraw properly. In addition, it does not maximize or resize properly. My understanding is that MFC automatically sends redraw messages during these events, and that I should not have to intercept these messages. I have implemented some manual redraw() instructions after modal dialogs close to handle some of these issues so far, but I do not know what is the proper way to handle this deeper problem, or what aspect of my application is incorrect.
Thank you, any advice appreciated.
Edit: the Redraw() mentioned:
After a dialog (which covers the centerwindow) closes, I tell the center window to repaint:
PlotSettings Dlg;
Dlg.DoModal();
MonitorWindow->RedrawWindow();

Related

ATL project pushbutton color change

We have a requirement to change the color of pushbutton/control. I have controls defined in resource file.
We have tried multiple ways
1)Using CMFCButton Object I got defination ambiguity errors
2)
Using CBUtton CDC* pdcWindow1 = m_Button.GetWindowDC(); CRect rect1; GetClientRect(&rect1); pdcWindow1->FillSolidRect(&rect1, (RGB(0, 0, 255)));
No effect on Button color no error as well.
Inputs which i have got so far : we have used ATLcontrols and to color Button we need MFC Functions, here ATL and MFC libs can't coexist they are causing ambiguity errors as both have same functional definitions.
Is it even possible to color ATL controls without MFC functions.?
only solution is --https://jeffpar.github.io/kbarchive/kb/173/Q173974/??
Look of standard Windows GDI buttons is customized according to Button Color Messages:
The system sends a WM_CTLCOLORBTN message to a button's parent window before drawing a button. This message contains a handle to the button's device context and a handle to the child window. The parent window can use these handles to change the button's text and background colors. However, only owner-drawn buttons respond to the parent window processing the message.
In ATL project, you would either handle this notification message in parent window class or use more sophisticated message forwarding (reflection) to reflect this message to button class.
Either way you don't really paint (FillSolidRect), you can just update colors in the message handler. And also pay attention that only owner-drawn buttons expose this functionality.
See also: Owner-drawn button, WM_CTLCOLORBTN and WM_DRAWITEM (clearing an HDC)
This is how I was able to achieve :
HINSTANCE hInstance = GetModuleHandle(NULL);
HANDLE hBitmap = LoadImage(hInstance, MAKEINTRESOURCE(IDB_CURCANCEL_LOGO), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
HANDLE hBitmap1 = LoadImage(hInstance, MAKEINTRESOURCE(IDB_CURLOGIN_LOGO), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
const HWND hOriginalLoginButton = GetDlgItem(IDOK);
const HWND hOriginalCancelButton = GetDlgItem(IDCANCEL);
SendMessage(hOriginalLoginButton, BM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)hBitmap1);
SendMessage(hOriginalCancelButton, BM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)hBitmap);
Now i am trying to make corners rounded.

Maximized WS_POPUP window goes in front of the taskbar

I'm creating a window in C++ with that code:
HWnd = CreateWindow(wc.lpszClassName,
"myapp",
WS_POPUP |WS_VISIBLE,
10, 10, 1000, 800, 0, 0, hInst, NULL);
It appears as I want but when I maximize it with like this:
ShowWindow(hwnd, SW_SHOWMAXIMIZED);
then it's like a fullscreen window so that the taskbar is hidden.
I think it's because it is a POPUP window but this is like I want it to appear.
Do I need to create my own maximize function or is there a parameter to avoid that ?
Thanks
You can add WS_CAPTION | WS_SYSMENU | WS_MAXIMIZEBOX style.
If you want your window to be without caption then you will need to adjust window size manually to fit into desktop work area that you can query using SystemParametersInfo specifying SPI_GETWORKAREA flag.
This is a feature where the Taskbar will get out of your full-screen application:
If you want to create a fullscreen window that covers the taskbar, just create a fullscreen window and the taskbar will automatically get out of the way.
I’ve seen people hunt for the taskbar window and then do a ShowWindow(hwndTaskbar, SW_HIDE) on it. This is nuts for many reasons.
Don’t do any of this messing with the taskbar. Just create your fullscreen window and let the taskbar do its thing automatically.
Since this is Stackoverflow, a combination of Wikipedia and Reddit, i want this relevant information saved for the next guy asking this question.

MFC - Minimize main MDI window only

I have main MDI window and have custom CWnd derived window which I create dynamically run-time. I want to keep that window on the screen even when main MDI window is minimized but I dont want to have top-most window. I have tried use WS_EX_CONTROLPARENT | WS_EX_APPWINDOW styles, set parent to NULL and set owner to GetDesktopWindow() but nothing works.
Any ideas how I should do that?
When window is minimized, it takes down with it all of its child and owned windows.
This code creates a regular (not topmost) window which is not hidden when the main frame is minimized:
HWND hWnd = ::CreateWindow(L"button", L"test", WS_CAPTION|WS_VISIBLE,
100, 100, 200, 200, GetDesktopWindow(), 0, 0, 0);

Application in C++ with two windows. One window shown in taskbar. The other not shown

I am doing some analysis before coding and I was having some trouble finding information or implementations where there is an application where there are these characteristics:
Window #1 (shown on taskbar)
Window #2 (doesn't show on taskbar and you can put this one behind Window #1, so we are not talking about popups/dialogs rooted from Window #1)
Both Window #1 and Window #2 are in the same Project (or application, so to speak)
Again, this is just speaking conceptually, so if you can point me to some information proving that this is possible, it would be great. Note, this is in C++ not C#.
The closest I came up with is this:
Added a class derived from CWnd
Added the following function to the class
void Create2ndWindow(CWnd* pParent){
LPCTSTR pszClassName = AfxRegisterWndClass(CS_VREDRAW | CS_HREDRAW, ::LoadCursor(NULL, IDC_ARROW), (HBRUSH) ::GetStockObject(WHITE_BRUSH), ::LoadIcon(NULL, IDI_APPLICATION));
BOOL bCreated = CreateEx(WS_EX_CLIENTEDGE,
pszClassName,
_T("My Second Window"),
WS_BORDER|WS_CAPTION|WS_ACTIVECAPTION|WS_MAXIMIZEBOX|WS_MINIMIZEBOX|WS_POPUPWINDOW|WS_SIZEBOX,
CRect(20, 20, 100, 100),
pParent,
NULL);
if(bCreated)
ShowWindow(SW_SHOW);
}
In the InitInstance i added the following lines:
CSecondWindow* pWnd = new CSecondWindow();
pWnd->Create2ndWindow(pFrame);
Execute the application, 2 Windows appear on your desktop but you should see only one taskbar button for the pFrame window and no button for the CSecondWindow
if the pParent is NULL then you would see the taskbar button. There is another style you can add WS_EX_TOOLWINDOW but that reduces the height of caption bar.

Child window do not catch WM_MOUSEWHEEL event

I have main window which contains child. In child I need to handle mouse wheel scroll, however it doesn't matter where I scroll mouse wheel message goes to main window. I got those results with Spy++.
Don't know why it happens, but I think that something is wrong with child creation, my code:
m_window = CreateWindowEx(0, CustomTreeView::m_className.c_str(), NULL, WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL, x, y, width, height, parent, NULL, NULL, NULL);
The WM_MOUSEWHEEL message is sent to the window with focus (i.e. the last one to have SetFocus() called on it). It doesn't matter where the mouse cursor is located - the messages will always go to the focus window.
If the focus window doesn't handle the wheel message, it is propogated by DefWindowProc to the focus window's parent, and again to its parent, and so on. So wheel messages only move up the window hierarchy.
If you want a child window that doesn't have input focus to get wheel messages then you need to arrange to forward them to it yourself.
If you do this, you should do it via a different message, to avoid the possibility of infinite loops.