Constraining Edit Control content - c++

I've scanned through all pages in MSDN, but still not found asnwers of following.
Minimum Character Length of edit control.
Specifying range for input values in edit control.
Permitting only alphabets in edit control.
Setting tooltip for button control.
Please tell me how to do this in Win32.

This is hard to do properly. A naive approach would handle WM_KEYDOWN messages to intercept the backspace and delete keys (VK_BACK and VK_DELETE). However, you also need to handle a user selecting some of the existing text and then deleting it (via backspace or delete), cutting it, or replacing it (by typing a key or by pasting some other text). I don't think it's worthwhile, and even if you could do this well, it is likely to be confusing when you break all of those normal behaviors. (It also can be incredibly annoying. Imagine that you have some text "bar" in the control but you want to change it to "baz". If the control enforces a minimum length of 3, then attempting to backspace over the last character won't work. You would have to change it to "barz" first and before being able to delete the "r" character. Ugh.)
If your control needs a minimum length, you're better off enforcing it during a separate validation step (such as when the user clicks an OK button or moves focus to another control) and showing an appropriate error message.
I'm not sure whether you mean allowing only certain characters to be entered into an edit control or whether you want to restrict it to a range of numeric values. For the former, see 3.
If you want to restrict values to a certain numeric range, I again recommend doing it during a separate validation step instead. Otherwise you again might prevent the user from inserting and deleting characters in a normal way. If you can, avoid using using an Edit control and use a Trackbar (slider) control.
You would have to subclass the Edit control, handle WM_CHAR messages, and reject characters that you don't want. You additionally would need to handle WM_PASTE messages and perform similar validation.
This doesn't have anything to do with Edit controls and probably should be a separate question. What have you tried? Have you read http://msdn.microsoft.com/en-us/library/bb760250.aspx ?

Related

CListCtrl search by typing: how to show what's been typed?

I have a CListCtrl in Report view, and I noticed that I can search by typing the first few letters of an item (the control selects the first item that matches as I type), and that this search "resets" after a second or so (so if I've typed "abc", pause, then type "d", then it searches for "d" only). For usability, I want the user to realize that this search-by-typing feature exists.
So here are the options I can think of, in order of preference, and the question I have in each case:
Use whatever existing built-in support there is in MFC.
Is there such a thing?
Some other solution that's been implemented before.
Again, is there such a thing?
Add another textbox to the dialog box, and handle its ON_EN_CHANGE message to somehow trigger CListCtrl's search behavior. In other words, similar to the find dialog/toolbar in browsers.
How do I trigger the search behavior?
Did take a look into the List-View controls documentation on Microsoft Docs.
This behavior is described in the Default List-View Message Processing (WM_CHAR message). The search-string is indeed reset after one second.
However, I didn't find any notification message that seems to be relative, eg returning the current search-string, which you can display. There is the
LVN_INCREMENTALSEARCH, but the documentation is rather confusing (eg what is an "incremental search"? etc), and I don't know if you are going to receive this at all, as this seems to be about Virtual List-View controls. Anyway, you can give it a try.
But resetting the test entered by the user in just 1 sec may rather be unwelcome to users or reviewers (actually I have never seen an application doing so). So you can implement some "Search" operation in your dialog, as you said add an edit box and search for its content. You can use the LVM_FINDITEM message (or the ListView_FindItem() macro) requesting a partial-match search (LVFI_PARTIAL), or do the search yourself (find the matching item and move there).

Remove the limit on the number of characters that can be entered into a Win32 Edit control

I've searched everywhere and it seems I can't find a solution to this problem..
My problem isn't limiting the amount of characters that can be entered into an edit control, my problem is I am limited by the size of the edit control. I want to be able to type past the size of the edit control.
I've tried extending the character limit to a high number with SendMessage and sending EM_LIMITTEXT, but that only seems to work if I want to limit it even more.
Here's an image example of my problem:
I use CreateWindowEx to create the edit control, but there doesn't seem to be an extended window style OR an edit control style that achieves what I want.
The style you're looking for is ES_AUTOHSCROLL. Without this style, input cannot go past the length of the edit control. With this style, text is automatically scrolled to the right by 10 characters when the input reaches the end of the control.
You may also be interested in ES_MULTILINE, which does exactly what it says. The default (without this style) is a single-line edit control.
All of the available styles are documented here. These are just regular window styles, not extended ones.
Also, I am pretty sure that you cannot change these styles at runtime, after the control has been created. Therefore, make sure that they are specified when you call CreateWindowEx, or in your resource file if the control lives on a dialog.

How to paste information into filtered CHeaderCtrl

We have an MFC application that uses the CHeaderCtrl and have been using the HDS_FILTERBAR style to filter data. Works great. But our users want to be able to paste in text into the filter cell. I have not found a way to get a pointer to any CEdit-type of control here so that I can call >Paste. I have managed to detect a Control-V while in the filter in the application's ::PreTranslateMessage. There is a way to send text to the filter by way of a CHeaderCtrl->SetItem call, but this will immediately launch the filter. I just want to be able to paste text.
So...I tried (I was desperate) using keybd_event and SendInput to force keystrokes. This worked but had undesirable side effects, probably due to MFC's message handling, and in my case, the user already had the Control + V pressed down. But in just sending the letter 'A', and forcing the SHIFT key, I accidently discovered that the CHeaderCtrl's filter does support a paste if you:
CONTROL + SHIFT + V
The problem is its hard to do, and hard to tell my users to do this.
I can simulate this sequence using keybd_event, but again, its real quirky.
Can anyone find a way to either get access to the CEdit (if there even is one) to a filtered CHeaderCtrl or know of another workaround ? I tried using a spy utility, but was not sure what to look for. Sorry for the long post.
So remove Ctrl+V from the accelerator list and you can handle it inside the control...
(Answer added according to the comment).

Lookup Combo that supports remote data - load data only after user wants to

I'm building a VCL c++ builder application. I would like to see if anyone knows of a component that can load data in the lookup upon drop down only after a user has typed a few letters to limit the rows queried? Preferably after pressing Tab, or Enter.
What I would like best is to get a behaviour similar to what Linux command line has, but that might be wishful thinking. The way it would work is to drop down the combo list after user presses tab only if there is multiple options available, and to fill in additional text till the point where characters are not the same anymore, then if user presses tab again, drop down list.
The next best would be if the drop down would only allow drop down if user has typed a few letters, then pressing a specific button opens the dataset with the parameter of the typed text so far, then drops down the combo.
Does a component like this exist?
You can check out TMS Software. I'm not sure if it has something exactly for you, but their components are quite flexible. And you can send a feature request to them - to consider for next update. If you are lucky they might add it to next release.

Win32API: How to determine if EN_CHANGE was because of user action, not software action?

I find this situation comes up from time to time, and I never seem to have a really robust generic solution to it.
I have a control - in this example an EDIT control on a dialog. I want to take certain actions in response to the user - and only the user - modifying the contents of the edit control.
The edit control can be set programmatically - e.g. when the dialog is being setup, there may be an initial value placed into the edit field. Or when the user selects an item from a listview, that selection's text may well be what's placed into the edit field.
But when the user modifies the contents of the edit field, I need to know that, and respond (in this scenario, I want to clear the selection from the corresponding listview).
I am currently looking at what control has focus, and only considering EN_CHANGE's to be "from the user" if the edit control has focus.
This works beautifully under Windows 7. This fails under XP (I haven't tested Vista yet).
In XP, if the edit field has the focus, but the user clicks on the list view, and the list view tells the edit control to set its contents, then I get a notification from the edit control which claims to still have focus (::GetFocus() == HWND of edit control). But this incorrect state doesn't occur in Win7.
This is a layered interface, so I cannot modify the list-view notification handler. It gets a selection change, and updates the edit field without my involvement or ability to really intervene other than to get notifications from both of them.
Any thoughts on how to generically, permanently solve the "Is this control notification really from the user" conundrum?
You can always track LVM_ITEMCHANGING, LVM_ITEMCHANGED, and EN_MSGFILTER messages. If the edit box is modified between LVM_ITEMCHANGING and LVM_ITEMCHANGED without an EN_MSGFILTER in between then you can probably assume the user did not modify the item. Or just check to see if there are any items selected when EN_CHANGE fires and if not or the text doesn't match the selected item, assume it is a user edit.
Or use ES_MULTILINE (from EN_CHANGE documentation):
The EN_CHANGE notification is not sent
when the ES_MULTILINE style is used
and the text is sent through
WM_SETTEXT.
I'd suggest using the right message. EN_CHANGE is too generic, you want to know if the user typed or pasted text. So why not subclass the control and watch for WM_KEYPRESS messages?
Alternatively, you can set a flag in your other code that sets the edit control content. You might be able to assume that anything that makes your wndproc re-entrant represents a programmatic change.
You aren't looking for something actually secure, are you? If you just want to exclude set content calls that's fairly straightforward. If you want to differentiate between user action and programmatic simulation of user keypresses, that's a much harder problem.