Create a CDialog in the corner of the screen - mfc

I have an MFC application that creates a CDialog. I'd like this CDialog to not show up in the middle of the screen, but rather off to the side of the screen so its barely visible or even minimized would be good.
How can I do this?

Use SetWindowPos in your OnInitDialog() function, like so:
BOOL CDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// (x,y) is the upper-left corner in screen coordinates
SetWindowPos( NULL, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER );
return TRUE;
}

You can use SW_SHOWMINIMIZED flag in ShowWindow(SW_SHOWMINIMIZED). (SW_SHOWMINIMIZED ==> Opens the window in its minimized state, representing it as a button on the taskbar)
pDlg->Create(IDD_DLG_ID1,this);
pDlg->ShowWindow(SW_SHOWMINIMIZED);

Related

So how can I manually draw a legend in the bottom right with OnPaint on a dynamic resize dialog?

I have a situation that I am not sure how to resolve.
I have a CDialog that supports dynamic resizing and I have a static control on there:
I have set the properties of this control to invisible and to move 100 in both directions:
I have set it as invisible because I want to use it as a placeholder. In OnPaint I then do the following:
void CAssignmentsDlg::OnPaint()
{
CResizingDialog::OnPaint();
CPaintDC dc(this); // device context for painting
COLORREF crTextHL, crBackHL;
COLORREF crTextOld, crBackOld;
CString strText;
EstablishLegendPosition();
crBackHL = ::GetSysColor(COLOR_HIGHLIGHT);
crTextHL = ::GetSysColor(COLOR_HIGHLIGHTTEXT);
dc.FillSolidRect(m_rcKey, crBackHL);
crBackOld = dc.SetBkColor(crBackHL);
crTextOld = dc.SetTextColor(crTextHL);
strText.LoadString( IDS_STR_SAMPLE_CONFLICT );
CFont l_font;
l_font.CreateFont(14, 0, 0, 0, FW_NORMAL,
FALSE, FALSE, FALSE, 0,
OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN, _T("Arial"));
CFont* l_old_font = dc.SelectObject(&l_font);
dc.DrawText( strText, m_rcKey, DT_SINGLELINE|DT_CENTER|DT_VCENTER );
dc.SetBkColor(crBackOld);
dc.SetTextColor(crTextOld);
// Delete the font object.
dc.SelectObject(l_old_font);
l_font.DeleteObject();
}
EstablishLegendPosition is defined like this:
void CAssignmentsDlg::EstablishLegendPosition()
{
// establish position of key
m_lblKey.GetClientRect(m_rcKey);
m_lblKey.ClientToScreen(m_rcKey);
ScreenToClient(m_rcKey);
}
It seems that unless the control is visible it will not move. But if it is visible it then seems to overwrite my rendering as I can't see my legend drawn on the dialog:
So how can I manually draw a legend in the bottom right with OnPaint on a dynamic resize dialog?

CreateWindowEx invalid X position once created

I've noticed that once a window is created using "CreateWindowEx" with x=0, y=0 position coordinates, window does not appear to be located in the the 0,0 corner of the screen. Instead it appears at the x=9, y=0.
I'm using a single monitor.
I'm not modyfing it's position anywhere else.
Window is created as an overlapped parent window.
When window is created, WM_MOVE get's called with x=8, y=31. (Those are "client-area" coordinates)
(It's a bit strange that WM_MOVE y coordinate is 31px but in the screenshot you can see that it should be ~38px...)
Window is created by:
mHandle = ::CreateWindowEx(WS_EX_APPWINDOW, CLASS_NAME, APP_NAME, WS_OVERLAPPEDWINDOW, 0, 0, mWidth, mHeight, HWND_DESKTOP, nullptr, mInstance, this);
Any ideas on what I might be doing wrong? What might be the reason?

MFC: how to keep child CWnd dialog from jumping upon resizing the parent window?

I'm writing an MFC dialog with multiple controls. I have currently have a CWnd that is placed on the right half of the dialog. Upon clicking an edit button, the child CWnd is resized to take up a larger portion of the dialog.
However, now when I try to resize the window, the child CWnd jumps back to where it was originally. I cannot seem to figure out how to keep it in it's new position when resizing.
Relevant code:
OnInit() {
//the grouper rectangle
CRect rectHTMLGrouper;
m_grpHTMLbox.GetWindowRect(&rectHTMLGrouper);
ScreenToClient(&rectHTMLGrouper);
//the new rectangle to use for positioning
CRect rectHtml;
rectHtml.left = rectHTMLGrouper.left + PREVIEW_EDITOR_LEFT;
rectHtml.right = rectHTMLGrouper.right - PREVIEW_EDITOR_RIGHT;
rectHtml.top = rectHTMLGrouper.top + PREVIEW_EDITOR_TOP;
rectHtml.bottom = rectHTMLGrouper.bottom - PREVIEW_EDITOR_BOTTOM;
//this inits my editor and sets the position
m_wHtmlEditor.CreateHtmlEditor(rectHTMLGrouper, this, WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN);
//CodeJock - XTREMEToolkit Call for SetResize Logic
SetResize(m_wHtmlEditor.GetDlgCtrlID(), LEFT_PANE_RESIZE, 0, 1, 1);
m_wHtmlEditor.SetWindowPos(&CWnd::wndTop, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOMOVE);
}
OnEditMode() {
//enlarge the editor to take up the full dialog
CRect parentClientRect;
m_wHtmlEditor.GetParent()->GetClientRect(&parentClientRect);
m_wHtmlEditor.SetWindowPos(&CWnd::wndTop, parentClientRect.left + edgePadding, parentClientRect.top + editorTopPadding, parentClientRect.right - (edgePadding * 2), parentClientRect.bottom - bottomPadding, SWP_NOOWNERZORDER);
return;
}
Upon clicking an edit button, the child CWnd is resized to take up a
larger portion of the dialog.
You have to handle that same resize in your OnSize() (ON_WM_SIZE()) message handler (using some kind of BOOL member to keep track of the child window's status).
OnSize() is called repeatedly while resizing the dialog.
Example:
// .h
BOOL m_bIsEditMode;
// .cpp
// keep track of m_bIsEditMode
void CMyDlg::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
if (m_bIsEditMode) {
//enlarge the editor to take up the full dialog
m_wHtmlEditor.MoveWindow (0, 0, cx, cy);
}
}

C++ mouse click on certain spot in window

I have my function here working, but I am certainly going about it the wrong way.
My program uses FindWindow to find the correct window. I need to double click on a specific location on this window.
I made it work by always putting the window in the same location on the screen, but if I moved the window the program would try click on the hard-coded location I have provided and it would not work.
Here is the function:
void lobbyWindow(HWND main_client)
{
//RECT arect;
// GetWindowRect(main_client, &arect);
SetCursorPos(748,294);
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
}
As you can see I just move the mouse to 748,294 and double click. What I want to do is set the mouse to 100,100 in the main_client window, so if I move the main_client window the mouse still clicks on the correct spot.
Use SendInput() instead, then you can use flags to move the cursor relative to the window -
Input.mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP;
How i can simulate a double mouse click on window ( i khow handle) on x, y coordinate, using SendInput?
http://www.cplusplus.com/forum/windows/97017/
If the window you're clicking in is in another thread/process this approach is fundamentally flawed, because the window can move while you're sending the clicks - meaning even if you have the right position to start with there's no guarantee all the clicks will end up in the same place.
Having said that, you can convert a client-relative coordinate to screen-coordinates using the ClientToScreen API function:
POINT pt = { 100, 100 };
ClientToScreen(main_client, &pt);
Depending on the target window you may find you can simply post it a WM_LBUTTONDBLCLK message to simulate the input at the appropriate position:
PostMessage(main_client, WM_LBUTTONDBLCLK, MK_LBUTTON, MAKELPARAM(100, 100));
SetCursor() requires screen coordinates, so you need to calculate where your double-click would be in screen coordinates relative to the window's current screen location. You can do that by either:
using GetWindowRect() to retrieve the window's current screen coordinates, then offset that by the intended relative coordinates.
use ClientToScreen() or MapWindowPoints() to convert relative coordinates to screen coordinates.
Once you have the intended screen coordinates, you can pass them to SetCursor().

Anchor buttons in a dialog when using SW_MAXIMIZE

This should be a simple one:
I have a CDialog with 2 buttons.
The dialog is always opened in full screen (No title bar \ Status, etc...) using m_pMainWnd->ShowWindow(SW_MAXIMIZE);
I want my buttons to snap to the edge of the screen.
There are no resizing or anything.
You know the width of the dialog (GetClientRect). You know the width of the buttons.
Assuming you are snapping to the right edge ...
Inside your CDialog::OnSize:
// Grab the CDialog's rect.
CRect winRect;
GetClientRect( &winRect );
// Grab the button's rect.
CRect buttonRect;
button.GetClientRect( &buttonRect );
// Now we need to set the top, left of the button to the right edge - the button width.
// The y position will remain the same.
button.SetWindowPos( NULL, winRect.right - buttonRect.Width(), buttonRect.top, 0, 0, SWP_NOZORDER | SWP_NOMOVE );