wxDC printing a text on screen while typing - c++

I am trying to show a string on the screen while the user still types it. Normally wxDC's DrawText function is used for a string where the contents of the string is already known.
void DrawText(const wxString& text, wxCoord x, wxCoord y)
As we know, this function takes a wxString and prints on the screen. However, how can I let the user type something on the screen (on a wxWindow, wxFrame ). All and all, I am working nowadays on a drawing program where users can draw certain shapes. Certain shapes are easy to draw, move etc... But having a textbox and letting user type something in it is bugging my mind so far. Of course, this should be editable such as when the user clicks again on the same "text box" I should be able to edit it.
One last point, I am trying to avoid using controls such as wxTextCtrl and in a sense trying to make my own textctrl. What would be the best starting point?
Any ideas would be appreciated.

Writing your own wxTextCtrl is difficult, I'd strongly recommend against doing this. But if you really want to (why?), then it's, of course, possible, after all wxRichTextCtrl which has significantly more features than the plain wxTextCtrl is written using only wxWidgets API.
And there is no particular magic here, you just need to update the window (ideally, use wxWindow::RefreshRect() instead of refreshing the entire window) whenever the text displayed in it changes and your wxEVT_PAINT handler must be capable of drawing the text correctly.

I don't think you need to do anything special here. As long as the user is in some kind of "edit" mode - i.e. you're expecting them to type text - then all you need to do is to redraw everything whenever the user enters more text.
Something like this:
User clicks inside a rect to edit text.
Program starts edit mode (some internal state initialises an empty string).
While user didn't click outside the rect
add the entered character to the text string
clear the drawing area inside the rect to background
call DrawText or more likely DrawLabel to draw the string in the rect
Then the text is redrawn as it changes and you have a string with the content for persistence if necessary.
Alternatively, you can just pop up a wxDialog with a wxTextCtrl to ask the user for the whole text string and then draw after the dialog is closed.
Makes sense?

Related

How can I copy a text from a sfml window?

I've got this sfml window that displays a text and now I want to make it markable so that you can copy the text.
Any ideas how to do that?
If you just want to copy everything then just use
sf::Clipboard::setString(your_string_here);
If you want more features, here are some I implemented when I programmed a Code Editor in SFML.
I stored two indexes, the first is where the selection begins, and the second is where the section ends.
So in the string Hello World!, if you wanted to select World you would set the begin index to 6, and the end index to 10 or 11 (depending on whether you include the final character or not).
I render this using an sf::RectangleShape, since my editor supported multiple line selection boxes the code is more complicated, but for your example you would want to get the position of each character. I used my own text renderer, but SFML's sf::Text::findCharacterPos() should be able to help with that.
Next the copy part, this is just
sf::Clipboard::setString(getSelected());
where getSelected() is
return std::string::substr(selection_begin, selection_end - selection_begin);
If you want pasting as well then it is also simple:
eraseSelected();
insertStringAtCursor(sf::Clipboard::getString());
Which are both simple string operations as well (std::string::erase and reset the selection indexes, and std::string::insert).
Finally, to let the user change what is selected, either holding shift and pressing the arrow keys or clicking and dragging are both common ways, the former being easier than the latter.
For the former, check if shift is held and then if left or right is pressed update the indexes.
For the latter, you will need to handle mouse events and dragging. When dragging begins, set one of the indexes, whilst the mouse is moving and is dragging set the other index.

Scrolling but wrapped pad in NCurses

I'm trying to make a text reader/pseudo-command-line a la man, but I'm having difficulty making the text scroll the way I'd like it to. At first I was having trouble getting new text to appear while scrolling, but eventually I found that pads would fix that for me, and I'm currently integrating them.
My question is, how can I get text to wrap within the pad? My program currently automatically refreshes when it is resized, so defining the pad to have as many columns as the terminal wouldn't fix everything. Can I get the pad to automatically resize itself as needed when my terminal receives a KEY_RESIZE? Not just the displayed size, but the size of the pad as well, such that text is pushed down a row due to the end of the pad. Additionally, will resizing it still keep the text, moving it down rows if necessary, or will I need to refresh the content of the pad?
Unfortunately, I'm having trouble finding resources with these details, and the documentation in ncurses doesn't elaborate on the behavior of resizing a pad.
Thanks a lot!
Edit after answered: ncurses doesn't do this, so I'm going to try instead making some arrays of strings, one to store the text from the file (broken at \n), and another for the line wrapping (refreshed on KEY_RESIZE, with each string having a max length of the terminal rows), parts of which are printed to the body window based on scrolling position and such. I'm making this edit so anyone else seeing this problem in the future can see what my solution is. I haven't done this yet, so I'll edit this again if it fails. Thanks again to Stack Overflow for helping with this!
ncurses will not do what you intend in this case:
A pad is like a window, true, and addch will wrap -- but the viewport which you are using to display data in the pad is not a window, and wrapping at the right side of the pad is not necessarily related to that viewport.
Once the text has wrapped, ncurses will not remember what that was, and re-wrap text if you resize the window (or pad).
A pad is mainly useful when you want to display just part of a window, e.g., if the screen is not large enough for the text you want to display.
If you want to resize and re-wrap, your program should allow for rewriting all of the text in the window (to lay it out as you intend) and not rely on ncurses to decide how to re-wrap text.

How to center align text in CDateTimeCtrl?

I'm using CDateTimeCtrl in my dialog application. Now we have already agreed with the client about the size of the CDateTimeCtrl. The 1st problem is, it is by default left-aligned, and is really close to the left border. The 2nd problem is it leaves a really wide space on the right side of the control. Hence, the solution to solve both problems would be to center align text.
Unfortunately, in the Properties window, there is no alignment property (except for "Right align" in which there were no changes when I tried to toggle it).
Now, I've tried calling CWnd::ModifyStyle in the OnInitDialog() event. Also, no luck with this.
For the actual code,
auto timePicker = (CDateTimeCtrl*)GetDlgItem(IDC_TIME_PICKER);
timePicker->ModifyStyle(0, SS_CENTER);
return TRUE; // this function is the OnInitDialog()
What could I be missing that calling this function does not center the text of CDateTimeCtrl?
You can't use a style that is suited for a static control and use the style in a date time control.
All available styles are listed here.
The control itself also doesn't have child controls. It draw the values itself.
Maybe there is a chance to subclass the control and overwrite the WM_PAINT message and doing a kind of ownerdrawing by yourself.
I don't use the date time picker and I confess: I don't like it at all. I wrote a complete own control that is much more flexible.

How should one retrieve the word under cursor, of current active window?

How could I retrieve the word under the cursor, on the currently active window? My thought was to use GetCursorPos() and WindowFromPoint() to get the handle, and do something, but how?
Imagine a dictionary app, which reads the text under the cursor, and give an explanation of its meaning.
EDIT
I end up use the dll from stardict, with its API hooks on text drawing.
You have to know the API needed for this; it's not obvious. You're looking for MSAA, Microsoft Active Accessibility
In short, you'll write an MSAA client. By calling AccessibleObjectFromPoint you get an IAccessible pointer. This pointer gives access to the properties of the object at the specified point.
What you are asking for is not trivial to implement.
Once you have determined which window is under the cursor (don't forget that you also need to use ChildWindowFromPoint() to drill down through nested windows), you can use GetClassName() to figure out what type of window it is.
For a standard RICHEDIT window, you can translate the screen-absolute cursor coordinates into client-relative coordinates within the window using MapWindowPoints() and then use the EM_FINDWORDBREAK, EM_EXSETSEL, and EM_GETSELTEXT messages to locate, highlight, and copy the word at the cursor coordinates.
For a standard EDIT window, once you have translated the coordinates, you can use the EM_CHARFROMPOS message to locate the character offset nearest the cursor coordinates, then use the EM_GETTEXT message for a single-line window, or the EM_LINEFROMCHAR and EM_GETLINE messages for a multi-line window (use GetWindowLong(GWL_STYLE) to test for the ES_MULTILINE style), to retreive the window's text, and then you would have to manually parse the text surrounding the character offset.
For other types of windows, especially custom controls, you have to do a lot more work, if it is even possible to get access to the window's text at all. Some windows respond to WM_GETTEXT messages and/or GetWidnowText(), while others do not.

How do I handle WM_NCCALCSIZE and make chrome-like interface?

I'm currently using Google Chrome as my main browser. I wondered how the developers put the custom titlebar, because I wanted to incorporate into one of my own applications.
If you guys don't know what I'm talking about, here's a picture:
I found an article about the interface, which is here:http://social.msdn.microsoft.com/Forums/en/vcgeneral/thread/33870516-9868-48d3-ab53-6269d9979598
However, I don't know how to do this. I'm currently using VC++ Express. Can anyone give me step by step instructions and how to get an interface like that? Except I don't want tabs on top.
I'm writing this in Win32.
If memory serves, the main things you need to handle aren't WM_NCCALCSIZE, but WM_NCHITTEST and WM_NCPAINT.
WM_NCHITTEST is what tells the system when the cursor is over the title bar, so you need to take a cursor position and decide whether it's over the area you consider "title bar". In particular, if the user clicks and drags with the cursor in this area, the whole window gets dragged.
WM_NCPAINT is just like WM_PAINT except for the non-client area -- i.e., this is when you need to actually draw whatever you're going to for the title bar (and window borders, if memory serves).
I should add that I haven't played with this in quite a while. There's almost certainly more I'm not remembering right now.
OK, the answer is simple:
Chomre simply does not use the Windows built in functionality for drawing a frame border, titlebar, titlebar buttons, etc..
When you call GetWindowRect(hChromeWindow) and GetClientRect(hChromeWindow) you will notice that the rectangles are identical. This means that Chrome turns off all Windows functionality for drawing a border (simply return 0 in WM_NCCALSIZE without doing anything else) and then they draw EVERYTHING into the client area.
So in WM_PAINT they draw the titlebar and the upper part of the window (URL bar, tabs, etc..) together. In WM_NCPAINT they do nothing.
This is not the common way to do it, but the easiest, and it is bullet-proof.
By the way: Java applications do the same.