Deselect edit control win32 c++ - c++

How would I go about deselecting the text in edit control?
After entering the input I want the user to be able to deselect the edit control.
Because even after you click out of it and press a key, it gets entered into the edit.
Here is the code for my edit control:
HFONT fontMain = CreateFont(
-16, // Height Of Font
0, // Width Of Font
0, // Angle Of Escapement
0, // Orientation Angle
0, // Font Weight
false, // Italic
false, // Underline
false, // Strikeout
ANSI_CHARSET, // Character Set Identifier
OUT_TT_PRECIS, // Output Precision
CLIP_DEFAULT_PRECIS, // Clipping Precision
ANTIALIASED_QUALITY, // Output Quality
FF_DONTCARE|DEFAULT_PITCH, // Family And Pitch
TEXT("Calibri"));
HWND editControl = CreateWindow(
TEXT("EDIT"),
TEXT("TEST TEXT"),
WS_CHILD | WS_VISIBLE | ES_LEFT | ES_MULTILINE,
x, y, width, height,
window,
(HMENU) 100,
instance,
NULL);
SendMessage(window /* parent window */, WM_SETFONT, (WPARAM)fontMain, NULL);
DeleteObject(fontMain);
I have checked MSDN docs and have not found any additional styles to add to achieve the task.
If you have any ideas on how to achieve this task could you help me out?
Thank you.

You could use the same trick that works to dismiss dropdown list (of combo box), popup menus, and the like.
You'll need to subclass the EDIT control so you receive messages first to your own window procedure.
In your textbox subclass WM_SETFOCUS handler, call SetCapture so the next click is delivered to the textbox even if it's outside.
In the textbox subclasses's handler for mouse click messages, test the location and if outside the textbox, call SetFocus(NULL) to give up the focus. (This is where a popup would dismiss itself). Also call ReleaseCapture().
Also call ReleaseCapture() in the subclass's WM_KILLFOCUS handler, since mouse clicks are not the only way to lose focus.
The above is the way to have any click outside the textbox remove its focus. If you only want clicks in the client area of your parent window to defocus the textbox, then you can certainly skip the subclassing and capture, and just handle the mouse click events in the parent window, calling SetFocus(NULL) or SetFocus(parentHWnd).

I handled the WM_LBUTTONDOWN message in the window proc.
Such that when I click the mouse button on the parent window, it will set the focus to the parent window.
static LRESULT WINAPI WndProc
(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message){
case WM_LBUTTONDOWN : {
// Passing the parent window as the parameter.
SetFocus(HWND parentWindow);
}
}
}
This method works as the WM_LBUTTONDOWN might not be triggered if you click on any other window except the parent window.
There might be some exceptions to the above statement, but overall it works with buttons and edits but not static text for some reason.
The answers were provided by:
#PaulSanders and #BenVoigt

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.

Is focus rect drawn automatically for listbox (WC_LISTVIEW)?

I have created a listbox similar to the code provided here. In my UI, will the tab focus rect be automatically drawn by DefWindowProc() or do I need to take care of that ? I don't see the focus rect being drawn on tab focus.
Thanks.
HWND CreateListView (HWND hwndParent)
{
INITCOMMONCONTROLSEX icex; // Structure for control initialization.
icex.dwICC = ICC_LISTVIEW_CLASSES;
InitCommonControlsEx(&icex);
RECT rcClient; // The parent window's client area.
GetClientRect (hwndParent, &rcClient);
// Create the list-view window in report view with label editing enabled.
HWND hWndListView = CreateWindow(WC_LISTVIEW,
L"",
WS_CHILD | WS_VISIBLE | LVS_LIST,
0, 0,
rcClient.right - rcClient.left,
rcClient.bottom - rcClient.top,
hwndParent,
(HMENU)IDM_CODE_SAMPLES,
g_hInst,
NULL);
return (hWndListView);
}
Normally,the default window procedure draws a focus rectangle for the list box item drawn by the owner in response to the WM_DRAWITEM message.
In MSDN
For an empty list box or combo box, itemID can be -1. This allows
the application to draw only the focus rectangle at the coordinates
specified by the rcItem member even though there are no items in the
control. This indicates to the user whether the list box or combo box
has the focus. How the bits are set in the itemAction member
determines whether the rectangle is to be drawn as though the list box
or combo box has the focus.
If you are not using owner/custom draw then all Windows common controls will draw the focus rectangle for you automatically.
Windows 2000 (and later) hide keyboard accelerators and focus rectangles by default unless you are interacting with the window by using your keyboard.
Windows enables applications to hide or show various features in its UI. These settings are known as the UI state. The UI state includes the following settings:
focus indicators (such as focus rectangles on buttons)
keyboard accelerators (indicated by underlines in control labels)

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.

Docking a child window to the parent window

I need my 6 controls (child windows of the main window) to get larger when the main window gets resized by the user (dragging the corners). I thought I could accomplish this by using the MoveWindow function to change the proportions of each child in the main window's WM_SIZE or WM_SIZING function. Doing this made the Debug build go strange (multiple windows, image of the window sticking after exiting, etc). The Release build ran fine but the child windows didn't change when I resized the main window.
I found http://msdn.microsoft.com/en-us/library/ms632598%28v=VS.85%29.aspx#creating_enumerating_etc used a different method of doing this: by enumerating all the child windows, and the enum callback function handling the window resizing through a unique ID assigned to every child. Upon trying this myself, it made no difference to the controls when the main window got resized.
Why isn't this working?
In the main windows switch statement:
case WM_SIZING:
GetClientRect(hwnd, &hwndRect);
EnumChildWindows(hwnd, EnumChildProc, (LPARAM)&hwndRect);
break;
The child enumerator callback function:
BOOL CALLBACK EnumChildProc(HWND hwndChild, LPARAM lParam)
{
LPRECT hwndRect = (LPRECT)lParam;
switch(GetWindowLong(hwndChild, GWL_ID))
{
case ID_CHILD_LLABEL:
MoveWindow(hwndChild, 0, 0, (hwndRect->right - hwndRect->left) - 30, 20, false);
break;
case ID_CHILD_LDIR:
MoveWindow(hwndChild, 12, 20, (hwndRect->right - hwndRect->left) - 40, 20, false);
break;
case ID_CHILD_LLIST:
MoveWindow(hwndChild, 12, 40, (hwndRect->right - hwndRect->left) - 40, (hwndRect->bottom - hwndRect->top) - 238, false);
break;
}
}
From MSDN's article on WM_SIZE: "If the SetScrollPos or MoveWindow function is called for a child window as a result of the WM_SIZE message, the bRedraw or bRepaint parameter should be nonzero to cause the window to be repainted."
I suspect the child controls are moving, they simply aren't being repainted.
It might also be worth verifying that your switch cases are actually being hit.
Edit:
I missed the obvious. You are responding to WM_SIZING, which indicates that the size of the window is about to (but has not yet) changed. WM_SIZE indicates that the size has changed. If you want to use WM_SIZING, you need to use the rect carried in the lParam, not the results of GetClientRect. Unfortunately the WM_SIZING rect is the rect of the window, not the client area, and is in screen coordinates. Unless you really need to display the resized controls while the user is still performing the resize, it would be much easier to just handle the WM_SIZE message.

Win32: Bring a window to top

I have a Windows program which has two 2 windows in it:
hwnd (main interface)
hwnd2 (toplevel window, no parent, created by hwnd)
When I double click on hwnd, I need hwnd2 to pop up and show some data, so I use this function to bring hwnd2 to top:
BringWindowToTop(hwnd2);
hwnd2 is brought to top, but there is one thing odd. When I click on hwnd2 again, hwnd (main interface) pops itself up again automatically.
I tried to use the following function to solve this problem, but non of them works.
SetWindowPos(hwnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
//doesn't work
BringWindowToTop(hwnd2); //This is the function brings hwnd2 to top
SetForegroundWindow(hwnd2); //doesn't work
SetWindowPos(hwnd2, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
//doesn't work
SetWindowPos(hwnd2, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
// hwnd2 "always" on top, not what I want
SetActiveWindow(hwnd2); // doesn't work too (for replying to Magnus Skog, thanks)
SwitchToThisWindow(hwnd2, TRUE);// got the same problem with BringWindowToTop function
SwitchToThisWindow(hwnd2, FALSE);
How could I solve this problem?
Thanks in advance.
(for replying to aJ, hwnd2 doesn't have parent because it needs to be a toplevel window so it can be in front/back of other windows)
(hwnd2 is a media player which is composed of several windows, one of the windows is for video dispaly, two other trackbar controls for progress bar and volume bar, one Toolbar control for control panel.)
(There is one this might help, no matter which window I click on hwnd2, hwnd pops up automatically as loong as "the mouse is on top of hwnd in Z-order", including menu bar and non-client area, etc.)
(This media player is writen in Direct Show. I use IVideoWindow::put_Owner to put video window as the video owner, Direct Show internally creates a sub-video window as a child of the video window. Except for this sub-video window which I can't see the source code, I don't see any thing suspicious in hwnd2.)
I found the reason, which is because of Direct Show. I use multithread to execute it, and then the problem's solved. But...why??
This problem can be resolved by using PostMessage (rather than SendMessage).
try this,it is said coming from M$
HWND hCurWnd = ::GetForegroundWindow();
DWORD dwMyID = ::GetCurrentThreadId();
DWORD dwCurID = ::GetWindowThreadProcessId(hCurWnd, NULL);
::AttachThreadInput(dwCurID, dwMyID, TRUE);
::SetWindowPos(m_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
::SetWindowPos(m_hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE);
::SetForegroundWindow(m_hWnd);
::SetFocus(m_hWnd);
::SetActiveWindow(m_hWnd);
::AttachThreadInput(dwCurID, dwMyID, FALSE);
In order to bring a window to top, you should get your window handle,thread handle, the windows thread handle who is in foreground
then we attach our thread to foreground window thread and get input by AttachThreadInput, then we set our window z order
to topmost and then restore its z order to normal, call SetForegroundWindow,SetFocus,SetActiveWindow to make sure our window is brought to top and is active and have focus
then deattach the input queue from the old foreground window thread, make our thread the only one who capture the input events
So why should We call AttachThreadInput, it is because
SetFocus sets the keyboard focus to the specified window. The window must be
attached to the calling thread's message queue.
What does AttachThreadInput do?
The AttachThreadInput function can be used to allow a set of threads
to share the same input state. By sharing input state, the threads
share their concept of the active window. By doing this, one thread
can always activate another thread's window. This function is also
useful for sharing focus state, mouse capture state, keyboard state,
and window Z-order state among windows created by different threads
whose input state is shared.
We use SetWindowPos to bring the windows to topmost and show the window if the window is hidding by using SWP_HIDEWINDOW
SetWindowPos function changes the size, position, and Z order of a
child, pop-up, or top-level window. These windows are ordered
according to their appearance on the screen. The topmost window
receives the highest rank and is the first window in the Z order
If your problem is your window is also minimized , you should add one line code to the end
ShowWindow(m_hWnd, SW_RESTORE);
Both work great:
::SetForegroundWindow(wnd)
or
::SetWindowPos(m_hWnd, // handle to window
HWND_TOPMOST, // placement-order handle
0, // horizontal position
0, // vertical position
0, // width
0, // height
SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE// window-positioning options
);
But remember that the last one sets the window always on top.
After many tries and errors.I found following solution to this problem:
SendMessage(hwnd, WM_SYSCOMMAND, SC_RESTORE, 0); // restore the minimize window
SetForegroundWindow(hwnd);
SetActiveWindow(hwnd);
SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
//redraw to prevent the window blank.
RedrawWindow(hwnd, NULL, 0, RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN );
The hwnd is your windows HWND . Please do not just copy and paste. You also need use GetLastError to check api error after every api call.
I have confirm following result on my win7:
Can restore minimize window and no error return.
If the window already top, the window title will blink and no error return.
If the window has closed, it will return the error "0x578 Invalid window handle."
It can bring the window to the top on all not top-most window and no error return.(For example it will behind the top-most taskmanager)
It do not make the window top-most. The user can make other window on top of it.
SwitchToThisWindow works best for me.
Have you tried SetActiveWindow()?
This will restore an app if minimized and bring it to the front:
ShowWindow(hWnd, SW_SHOW);
SetForegroundWindow(hWnd);
//work great!
Var
WndHandle:HWND;
begin
WndHandle :=FindWindowEx(0,0,nil,'Calculator');
PostMessage(WndHandle,WM_SHOWWINDOW,SW_RESTORE,0);
SetForegroundWindow(WndHandle);
end;