MFC CEdit won't take keyboard input - c++

I have a legacy project where i need to add a multi-line text box to the view.
I first simply want to create a textbox in onDraw function in my view class to put a text box on screen. The rectangle of the textbox keeps blinking. I can't select it or do anything.
The view class is inherented from CView. The info. i got from research is that CEdit usually added to dialog class, but i can still add it to any view.
CRect rect(100, 100, 300, 200);
CEdit test;
test.Create(WS_CHILD | WS_VISIBLE | WS_BORDER | WS_HSCROLL | ES_MULTILINE | WS_VSCROLL, \
rect, this, 1);
I'm totally new to this, and before i get into all the handle and messaging, i just want to simply create a text box and type some text in it.
Thank you for the help in advance.

You probably don't want to create the edit control in your OnDraw. In fact, unless your view contains something else you need to draw, you may not need to handle OnDraw at all.
When you have a view hosting a control, you usually want to create that control in the view's OnCreate, so it's created after the view's own window is created (which will be the control's parent) but before the view's window is displayed (so the control can be displayed at the same time).
In this case, the view probably won't need to deal with drawing at all. It probably will need to deal with:
sizing: resize the control to fit the new size of the view's client area.
focus: when the view receives focus, immediately give focus to the control.
Commands: you pretty routinely want to deal with things like:
cut/copy/paste to/from the control
put data into the control (e.g., from a file)
get data out of the control (e.g., save to a file)
set the control's font

Related

C++ how to display text in child window at real time

This application creates a child window (which is the white box) when I right click anywhere, and destroys the child window after another right click. I have implemented the mechanics to expand and shrink the red rectangle through Direct 2D. I would like the child window to display the width and height of the rectangle at real time, as I make changes to it. I do not interact with the child window at all: it doesn't need an "x" button for closing and stuff; it just prints out a couple lines of data.
Here is what I have in my main window procedure:
case WM_RBUTTONUP:
{
DemoApp *pDemoApp = reinterpret_cast<DemoApp *>(static_cast<LONG_PTR>(
::GetWindowLongPtrW(hwnd, GWLP_USERDATA)));
pDemoApp->showTextBox = !pDemoApp->showTextBox; //showTextBox is a boolean
if (pDemoApp->showTextBox) {
POINTS cursor = MAKEPOINTS(lParam);
pDemoApp->child_hwnd = CreateWindowEx(
WS_EX_TOPMOST,
"LISTBOX",
"I dont need a title here",
WS_CHILDWINDOW,
cursor.x,
cursor.y,
100,
200,
pDemoApp->main_hwnd,
NULL,
HINST_THISCOMPONENT,
pDemoApp
);
ShowWindow(pDemoApp->child_hwnd, SW_SHOWNORMAL);
UpdateWindow(pDemoApp->child_hwnd);
}
else {
DestroyWindow(pDemoApp->child_hwnd);
}
}
break;
How may I go from here? I would like to know:
Is using Direct Write to draw text in the child window my only option? I see the dashed lines in the white box so I assume there must be a way to display plain text.
I used LISTBOX here, which is a predefined windows class name. How do I set a procedure for it? What else predefined class name can better suit my need? Or do I have to register a custom one;
I would like to drag the child window around, how can I set it up so that the system handles dragging for me.
Would popping a dialog box to display text be better than popping a child window?
Thanks.
Since you are using a Win32 LISTBOX control as the child window, then you have a couple of options for displaying the rectangle's dimensions in it:
give the ListBox the LBS_HASSTRINGS style, and add 1-2 items to it. Then, any time you change the rectangle, send LB_DELETESTRING and LB_ADDSTRING messages to the ListBox's HWND to display the updated dimensions as needed. A ListBox does not have a way to update an existing item, so to change an existing item's text, you have to remove the item and then re-add it with the new text.
give the ListBox an LBS_OWNERDRAW... style, and add 1-2 blank item(s) in it. Then have the ListBox's parent window handle WM_MEASUREITEM and WM_DRAWITEM notifications from the ListBox to display the rectangle's current dimensions in the item(s) as needed. Whenever the rectangle is changed, call InvalidateRect() on the ListBox's HWND to trigger a redraw.

How to set the height and width of the CDockable pane

I want to set the height and the width of the dockable panes. I tried passing the value in the CRect parameter to the OnCreate function but that didnt work. can anybody help in resolving this
You can probably get the effect you want by calling SetWindowPos(... SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE), this will work in the case the pane is undocked.
I don't know if the result will constructive at all when the pane is docked or hidden. You can also add handlers for WM_SIZING and WM_SIZE in your CDockablePane derived class to limit the size of the pane within a desired range.
MFC manages the pane sizes and uses values stored in the registry. That is a real pain, especially when a pane disappears in a new version of your software. I don't know of an easy way to turn this off. But it can be done.

How can I erase the window background in an owner drawn static control?

I am currently developing a kind of "WinMerge" clone, and currently I am trying to implement a custom scrollbar which should later represent both compared files as a rectangle in the background each.
This is what it looks like at the startup:
However, after scrolling around a little bit, this is what I end up with:
As you can clearly see, only those parts look correct which I explicitely paint over in my paint routine:
void LocationPane::OnPaint(CDCHandle dc)
{
DefWindowProc();
dc = GetDC();
DrawLocationPaneFigures(dc);
}
This is how my control is configured in my .rc file:
CONTROL "",IDC_LOCATIONPANE,"Static",SS_OWNERDRAW | SS_NOTIFY | WS_BORDER | WS_GROUP,7,21,91,541
As you can see, it is an owner drawn control.
How can I erase the background for this control while repainting it?
A static control with SS_OWNERDRAW style receives a WM_DRAWITEM message when it needs to be redrawn.
So first you need to replace your OnPaint() handler by a handler for WM_DRAWITEM. Instead of calling GetDC() use the device context supplied to you in the DRAWITEMSTRUCT.
To erase the background it's generally best to do it as part of the regular painting code to reduce flickering (by calling FillRect() for instance).
I suggest to always draw the whole client area of your control. Then you may handle WM_ERASEBKGND to return TRUE without calling DefWindowProc() to reduce flickering even more.

MFC CCheckListBox's vertical scrollbar is not updated

I had to replace an old MFCSharpGrid control with a CCheckListBox.
Now, after displaying the vertical scroll-bar for the list-box, it seems to send the correct events (the line up/down and page up/down) to the list's client area, and it allows mouse-wheel scrolling which isn't available with the scroll-bar hidden.
However, the scroll-bar is not updated itself: the thumb is not moving when scrolling the client area (not even in response to scrolls from the scroll-bar), and the thumb's size is not proportional to the page-size.
The list-box is created more or less like this:
m_grid.Create(LBS_HASSTRINGS | LBS_OWNERDRAWFIXED | LBS_NOTIFY, m_gridRect, this, IDC_GRID1);
Strings are added iteratively, and then we request displaying the scroll-bar like this:
m_grid.ShowScrollBar(SB_VERT, TRUE);
Trying to set the SCROLLINFO for min/max/page-size didn't solve the position update problem.
What am I missing here?
You don't want to manually use ShowScrollBar. Delete that, and rather create the listbox with WS_VSCROLL style.
m_grid.Create(WS_VSCROLL | LBS_HASSTRINGS | LBS_OWNERDRAWFIXED | LBS_NOTIFY, m_gridRect, this, IDC_GRID1);
That way you get a vertical scrollbar automatically when the contents exceed the length of of the control.

Child window (CEdit) losing focus

I am programming in C++ using MFC Document/View architecture. I have been trying to achieve something similar to MFC CEdit lose focus handler. I processed the message EN_KILLFOCUS as the answer suggests.
Basically, I'm doing this: I have text drawn in the view. When the users clicks the area of the text in the view, I position and show the CEdit window on top of it so users are able to edit the text. When the edit loses focus, I get the CEdit text and save it in the document. Then invalidate the view.
However, I seem to only receive the EN_KILLFOCUS message when the view loses focus. I have to click somewhere else, e.g. a docking window, or the toolbar, to make the CEdit lose focus. I want it to happen when I click anywhere else on the view, outside the CEdit box.
I am creating the CEdit with WS_CHILD style. I tried WS_POPUP but still the same problem.
Any help would be appreciated.
Create a CEdit derived class/control. And create an instance of this class in your View
Handle the EN_KILLFOCUS in the derived class. You will be able to handle this message once user clicks outside the edit control window.
Keep your editbox as WS_CHILD.
Set focus to view on view's mouse down, call SerFocus() on view's LButtonDown.