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.
Related
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
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.
I got a multiple selection CListBox with horizontal scroll bar enabled and showed correctly. Problem is, that when I use function
lst.ResetContent() and fill it back, I can't find way to scroll text in the rows back to the same position. I tried to use
lst.SetScrollPos(SB_HORZ, horizScroll, TRUE); , where horizScroll = lst.GetScrollPos(SB_HORZ); This works correctly on scroll bar itself, but
text in the row stays not scrolled (manual scrolling functions OK).
Structure of my program is:
CListBox lst;
int horizScroll;
/*Periodically doing code bellow*/
//Get current scroll position
horizScroll = lst.GetScrollPos(SB_HORZ);
//Reset current content
lst.ResetContent();
//Add item into CListBox (UNICODE in my application)
lst.AddString(L"Some longer text then width of CListBox");
//Calculate horizontal extent and set it through
lst.SetHorizontalExtent(calculatedWidth);
//Try to scroll text (scrolls only scroll bar, not text itself)
lst.SetScrollPos(SB_HORZ, horizScroll, TRUE);
UpdateData(FALSE);
Thanks in advance!
EDIT:
As "rrirower" answered correctly,
lst.PostMessage(WM_HSCROLL, MAKEWPARAM(SB_THUMBPOSITION, 250), 0);
message does the job. Scroll position from horizScroll works perfectly. I suggest posting this message twice, because if you do it only once, text is re-scrolled visually from beginning to the wanted position. When you post it twice, text visually stays at the correct position and scroll bar just quickly comes to the right place.
If I understand you correctly, you're trying to scroll the text in the list box horizontally using the program code. If you use Spy++, you'll see that when you manually scroll, using the mouse, a series of WM_HSCROLL messages is posted to the list box control. You can accomplish the same thing by doing this...
lst.PostMessage(WM_HSCROLL, MAKEWPARAM(SB_THUMBPOSITION, 250), 0);
You need to calculate the position (I used 250 above), but, the above code should move the text and the scroll bar horizontally.
After some reading it seems that Invalidate should do the trick. Since as I understand you have one text line this should be fine, however if the painting itself is complex and requires resources you can use ScrollWindowEx and then InvalidateRect on the rectangle returned by the latter to repaint only the changed area.
I am using a combobox control to show names stored in a database ( I need to preserve space, that is why I use it instead of a listview, for example ).
My problem is that sometimes text is longer than the combobox so part of it can not be seen.
Is there a way to resize combobox' listbox so it can entirely show text, or at least to enable some kind of horizontal scrolling so the user can scroll to see the entire text?
Looking through combobox documentation, I haven't found any style that can solve my problem. Trying to add WS_HSCROLL as a style in my CreateWindowEx call didn't help either.
Thank you.
You are looking for the CB_SETHORIZONTALEXTENT message.
An application sends the CB_SETHORIZONTALEXTENT message to set the width, in pixels, by which a list box can be scrolled horizontally (the scrollable width). If the width of the list box is smaller than this value, the horizontal scroll bar horizontally scrolls items in the list box. If the width of the list box is equal to or greater than this value, the horizontal scroll bar is hidden or, if the combo box has the CBS_DISABLENOSCROLL style, disabled.
Parameters
wParam
Specifies the scrollable width of the list box, in pixels
lParam
This parameter is not used.
I created an application with the MFC wizard and added the splitter functionality.
The wizard will add a variable CSplitterWndEx m_wndSplitter to class CChildFrame.
After that, a split view will be created with a horizontal scrollbar and a vertical scrollbar.
But the rich edit view also has its own scroll bar.
How can I keep only one scrollbar and keep the split functionality?
Thanks in advance.
The scroll bar is created with respected to the style given on creation of splitter window. Please refer the following link
https://learn.microsoft.com/en-us/cpp/mfc/reference/csplitterwnd-class?view=msvc-170#create
if the style is modified as below, the scrollbars will not be created
DWORD dwStyle = WS_CHILD | WS_VISIBLE | SPLS_DYNAMIC_SPLIT.
To show the Splitter for dynamic split, we need the scrollbars which creates space to display the splitter.