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)
Related
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.
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
I am trying to programmatically design a dialog menu that resizes based on the resolution of the screen, and I am able to get the size and positions of the dialog using the dialog's nameID following this question:
Get Dialog Size as defined in resource file
However, I'm having trouble trying to obtain the size and positions of the button controls within the dialog. Here's an example of what the dialog might look like in the resource file:
IDD_DLG DIALOG 0, 0, 300, 200
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP
BEGIN
DEFPUSHBUTTON "OK",IDOK,30,46,42,18
PUSHBUTTON "Cancel",IDCANCEL,145,46,42,18
END
I can obtain the dialog's size and positions using its nameID, i.e. IDD_DLG, but is it possible to obtain the same thing for the DEFPUSHBUTTON or PUSHBUTTON programmatically?
If so, how? Thanks!
MFC allows automatic repositioning/resizing of child buttons. In resource property page, click on dialog button, go to dynamic control section, enable dynamic resizing/move for each button.
To find the coordinates of the button, relative to top-left of dialog client window:
Use GetWindowRect to find the buttons rectangle in screen coordinates. Then convert the screen coordinates to client coordinates:
CMyDialog::OnInitDialog()
{
CDialog::OnInitDialog();
CRect rc;
CWnd *wnd = GetDlgItem(IDOK);
wnd->GetWindowRect(&rc);
ScreenToClient(rc);
...
//move/resize rc
wnd->SetWindowPos(NULL, rc.left, rc.top, rc.Width(), rc.Height(), SWP_SHOWWINDOW);
}
I'm working on an Windows Application which has to show an overlaying fixed positioned window ("PopUp") in the left corner of the MainFrame which will receive some Information if a user missed some input or if certain actions have been successfully.
The "PopUp" Titlebar shall have an Icon next to the Title (e.g. ->Icon<- "Error") and the standard X - Close-Button. The ClientArea will have an descriptive text of the occurred Message.
Additionally the standard Border of the PopUp shall be set to 1px(smaller than the default windows border)
The "PopUp" is derived from CWnd and created with WS_VISLBE | WS_CLIPSIBLINGS | WS_CHILD | WS_CAPTION in the OnCreate-Method of the Applications MainFrame Window
Now I need to set/shrink the default Border of my PopUp and add the Icon to the Titlebar of the PopUp.
Can someone give me some example code of how i can solve my issues?
I'm pretty new to c++ and MFC so far my research brought me to https://msdn.microsoft.com/en-us/library/windows/desktop/bb688195(v=vs.85).aspx
but i dont know where and how to use DwmExtendFrameIntoClientArea() but so far I've read I assume Dwm is the way to go to be able to solve both problems or is there another/totally different way? Am I on the right track?
Finally I was able to shrinkthe default Windows Border by overriding the handling of WM_NCCALCSIZE.
I will update this answer as soon as I solved how to put my Icon in the Titlebar.
As of now I'll explain how I shrink the windows border:
Add ON_WM_NCCALCSIZE() to your MessageMap of the desired Window and Implement OnNcCalcSize() (Class Wizard will help to set this up) as followed:
void YourCWndClass::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp)
{
if (bCalcValidRects){
CRect rcClient, rcWind;
GetClientRect(&rcClient);
GetWindowRect(&rcWind);
int border = (rcWind.right - rcWind.left - rcClient.right) / 2 - 1;
//-1: leaves 1px of the Windows Default Border Width erase to have no border
lpncsp->rgrc->left -= border;
lpncsp->rgrc->right += border;
lpncsp->rgrc->bottom += border;
}
CWnd::OnNcCalcSize(bCalcValidRects, lpncsp);
}
The WM_NCCALCSIZE Message is sent up on the Window Creation (when you call Create()/CreateEx() ) but at this point of time GetClientRect() and GetWindowRect() will not return the proper values therefore you need to check the Bool Parameter!!!
To trigger another WM_NCCALCSIZE to be able to work with the proper Window Rectangles call SetWindowPos() right after the window creation
if (!m_MessagePopOver->Create(NULL, NULL, WS_CHILD | WS_CLIPSIBLINGS | WS_CAPTION, rect, this, NULL, NULL)){
TRACE0("failed to create MessagePopOver");
}
m_MessagePopOver->SetWindowPos(&wndTop, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
This will result in a window like this:
I am quite desperate to resolve this very annoying issue :(
I am trying to display a child window on parent window. Some time the window need to be resized. But for some reason, when I using MoveWindow function it leaves blank space on the top of the parent window. I would like to present a picture here but I can not post a picture.
Here is the code example:
HWND hwnd // Comes from external function. Was defined as WS_CHILD previously
HWND hwndParent = ::GetParent(hwnd);
RECT parentRect = {0,0,0,0};
RECT childRect = {0,0,0,0};
::GetClientRect(hwndParent, &parentRect); // Suppose it returns {0,0,600,300}
BOOL ok = ::MoveWindow(hwnd, 0, 0, 600, 300, true);
::GetClientRect(hwnd, &childRect); // Will return {0,0,584,297}
WHY ?????
What am I doing wrong? Did I forgot some flags with window initialization?!
Rather than use GetClientRect, use GetWindowRect and MapWindowPoints(NULL,hwndParent,&parentRect,2) to adjust it to the parent window coordinates. GetWindowRect will include the non-client area that MoveWindow requires.
Edit: If you want a window that doesn't have a non-client area so the window rect and the client rect are the same size, you need to trim the window styles that you apply to the window. Avoid the WS_BORDER, WS_CAPTION, WS_DLGFRAME, WS_OVERLAPPED, WS_SIZEBOX, and WS_THICKFRAME styles.
MoveWindow updates window position, while GetClientRect gets a client-area part of the window, which does not have to be the same. If your window has non-client area, then everything is fine and works as expected.
If you are still under impression that child window does not fully cover parent's client area, then the spacing belongs to the child control/window, and you need to look for ways to remove it there (control flags, parameters etc).
MoveWindow operates on window coordinates -- including non-client area (borders, title bar, etc).
GetClientRect gets the area of the client portion of the window, ignoring borders, title bar, etc.
This is where the mismatch is. If you want to MoveWindow to a desired client size, you need to just AdjustWindowRect to try and predict what to pass into MoveWindow. Note that it's not always possible, and not always accurate. For example minimum / maximum sizes of windows, menus (which can wrap to multiple lines), etc.
The problem was WS_POPUP flag to the parent window.
Very strange. As far as I know it was not suppose to have such an effect.
Thanks for everyone!