I have an Edit Box and a Button on a dialog. How can I change the content in the edit box runtime as the button is clicked? I have to read a new record from a file and post it in the Edit Box as the Button is clicked and I am using mfc.
Once you have trapped the button press, in most cases the easiest way to change text in an Edit Control is:
SetDlgItemText(IDC_EDIT_ID, "Desired Text String")
Where IDC_EDIT_ID is the ID of the Edit Control (set in the properties window)
You can set the text of an Edit control (wrapped by the CEdit class in MFC) by calling the SetWindowText method, which it inherits from the CWnd base class.
So then all you need to do is respond to a click event on your button control. You do this by listening for the BN_CLICKED notification from the appropriate button control within your parent window's OnCommand method.
Something like:
BOOL CMyDialog::OnCommand(WPARAM wParam, LPARAM lParam)
{
if (HIWORD(wParam) == BN_CLICKED && LOWORD(lParam) == IDC_MYBUTTON)
{
m_Edit.SetWindowText(TEXT("My string"));
}
return CWnd::OnCommand(wParam, lParam);
}
Obtaining and reading a book on MFC would be very helpful. This is fairly basic stuff, but it's a lot to cover in a single answer if you don't already understand the fundamental concepts.
Using the Class Wizard would make this even easier... Invoke it with the Ctrl+W keys and follow the on-screen instructions. You'll end up with something like:
void CMyDialog::OnMyButton()
{
m_Edit.SetWindowText(TEXT("My string"));
}
Related
Can anybody please let me know, how to add a right click event handler for a static text on a Dialog box.
So I have a modal dialog box, on which I have a static text control. When I am trying to add event handler for it,
I have only options:
STN_CLICKED
STN_DBCLK
STN_ENABLE
STN_DISABLE
NM_THEMECHANGED.
there is no message for right click. And I need to handle right click event. Can you please help me to know, is there any way to add right click event handler?
What you can do is this ...
Make sure your static control has a unique ID, eg: IDC_STATIC1. It can't be IDC_STATIC.
Associate the control with a CStatic variable using the ClassWizard.
Override the OnContextMenu for your dialog using the editor.
Now you can do something like:
void CMFCApplication1Dlg::OnContextMenu(CWnd* pWnd, CPoint point)
{
CRect rect;
m_staticLabel.GetWindowRect(&rect);
if (rect.PtInRect(point))
{
// Show context menu
}
}
This issue is in the same application as my last question.
I'm experiencing some "odd" behavior, and I don't know if it's functioning as designed or if there's something wrong. In the 3rd party application that I'm "injecting" data into I experience different behavior when I manually edit a record vs. when my automated application edits a record.
If I run the 3rd party application and manually edit a record, the 'Save' and 'Undo' buttons in the toolbar become enabled once I begin typing in a field.
If I run the 3rd party application, then run my automated application to edit a record, my application sets focus to the first field on the form, then "injects" the data into the fields (it actually looks like someone is typing it in very fast) but the 'Save' and 'Undo' buttons stay disabled the whole time. I try to invoke the 'Save' button when I reach the bottom of the form, but I receive an error:
"An unhandled exception of type 'System.Windows.Automation.ElementNotEnabledException' occurred in UIAutomationClient.dll
Additional information: The operation is not allowed on a nonenabled element."
I used this code example on MSDN to insert text in the textboxes of the 3rd party application.
if (!element.TryGetCurrentPattern(
ValuePattern.Pattern, out valuePattern))
{
// Set focus for input functionality and begin.
element.SetFocus();
// Pause before sending keyboard input.
Thread.Sleep(100);
// Delete existing content in the control and insert new content.
SendKeys.SendWait("^{HOME}"); // Move to start of control
SendKeys.SendWait("^+{END}"); // Select everything
SendKeys.SendWait("{DEL}"); // Delete selection
SendKeys.SendWait(value);
}
// Control supports the ValuePattern pattern so we can
// use the SetValue method to insert content.
else
{
// Set focus for input functionality and begin.
element.SetFocus();
((ValuePattern)valuePattern).SetValue(value);
}
Perhaps I'm not searching the correct keywords, but Google has not been much help to me, and I only found one SO post that seemed related. If anyone can shed some light on this I'd really appreciate it.
TIA
UPDATES:
Re: why don't I check if button is enabled...
I don't know how to accomplish that, I was trying to do that earlier today. I have an AutomationElement that references the 'Save' button, but the AutomationElement doesn't have an Enabled property.
AutomationElement toolbar = _mainWindow.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.AutomationIdProperty, "59392"));
AutomationElement saveButton = toolbar.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.NameProperty, "Commit Changes (CTRL S)"));
I tried to cast the AutomationElement as Button to check the Enabled property but I receive a build error "Cannot convert type 'System.Windows.Automation.AutomationElement' to 'System.Windows.Forms.Button'"
if (!((Button)saveButton).Enabled)
((Button)saveButton).Enabled = true;
...ok, more searching lead to this: UIAutomation Button Style Enabled
so now I can check if it is enabled, but I haven't figured out how to enable it yet.
2014.10.02 - I think it's not possible to enable a disabled button via UIAutomation. So I will modify my question a bit. If I manually click on an input field and begin typing the 'Save' button becomes enabled. If I use UIAutomation to modify the record the 'Save' button does not become enabled. So, how can I use UIAutomation to get the window into the same state that it's in when I manually edit the record?
You could try using the win32 api to send messages to the button directly. You can get all the handles you need from uiautomation just use the post message function like this.
public TestSetup AutomationLibrary;
[DllImport("User32.dll")] //http://msdn.microsoft.com/en-us/library/windows/desktop/ms644944(v=vs.85).aspx
public static extern int PostMessage(IntPtr hWnd, int uMsg, IntPtr wParam, IntPtr lParam);
public int WM_ENABLE = 0x0A;
public int WM_COMMAND = 0x111;
public MainWindow()
{
InitializeComponent();
AutomationLibrary = new TestSetup();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
AutomationElement aeDesktop = AutomationLibrary.GetDesktop();
AutomationElement aeForm1 = AutomationLibrary.GetAutomationElement("Form1", aeDesktop);
AutomationElement aeDisabledButton = AutomationLibrary.GetAutomationElement("DISABLED", aeForm1);
IntPtr windowIntPtr = new IntPtr(aeForm1.Current.NativeWindowHandle);
IntPtr controlIntPtr = new IntPtr(aeDisabledButton.Current.NativeWindowHandle);
PostMessage(windowIntPtr, WM_COMMAND, (IntPtr)WM_ENABLE, controlIntPtr);
}
The TestSetup is my own home brewed automationlibrary but basically I am just getting automation elements then using the PostMessage function from User32.dll to enable the button. although it doesnt seem to actually enable the button, it does have the unintend consequence of clicking the button.
I used this article as reference for the postmessage function http://www.codeproject.com/Articles/487938/Re-Active-Disabled-Controls
Hope this helps
Using MS VC, I've created a "Dialog based" MFC Application. Let's call it MyApp1. I simply want to add some kind of "box" to my dialog to display text. I tried to add an "Edit Control" and then printing to it via
var_set.SetCueBanner(_T("Test"), TRUE);
var_set is the variable of the Edit Control CEdit. This code is added in a function that is called when pressing a button in the dialog. E.g.
void MyApp1Dlg::OnBnClickedButton1()
{
var_set.SetCueBanner(_T("Test"), TRUE);
}
However, I think this is at least not the way an "Edit Control" should be used... So I tried with a "Static Text". To control it, I read to use
HWND hwndText = GetDlgItem(dlg, IDC_STATIC);
SetWindowText(hwndText, L"Test");
But I would have to use the ID of the dialog dlg which is not defined in MyApp1Dlg.cpp file. I found it in the MyApp1.cpp. Should I export that instance to MyApp1Dlg.cpp or is there another way to display text in my dialog? In the final application, I'd like to use it similar to a
printf("output: %g\n", xx);
command. Thanks for hints.
The SetCueBanner function is for setting a prompt into the edit control. If you want to set the actual text, use SetWindowText - it's part of the parent class CWnd so you would not find it in the CEdit documentation. This works for both edit and static controls, although a static control might also need a RedrawWindow before it shows the new text.
var_set.SetWindowText(_T("Test"));
OK, I got an answer:
First, define an "Edit Control" box. Let's call the ID IDC_EDIT1. Next, in one of the MyApp1Dlg.cpp functions, insert
CString str;
str.Format(_T("%d x %d"), .5, .4);
SetDlgItemText(IDC_EDIT1, str);
and mark the property "Read only" to True.
A very straightforward question....
How do you enter a new line in a CEdit control box without it triggering OK and closing the dialog box altogether? What I mean is when you hit the enter key it automatically selects OK, even if your cursor is still in the CEdit control. Is what I am trying to do possible? Or do i have to use some other control
PS: It is a modal dialog box btw.
There are various solutions for this problem.
Basically what you need is the ES_WANTRETURN style on the edit control.
Another solution is to check the message and key in PreTranslateMessage (since it has been commented upon this is not the recommended way, I'm just mentioning it for possibilities):
BOOL CYouDialog::PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN &&
GetFocus() == youcontrol)
{
return TRUE;
}
return FALSE;
}
The other solution is to handle WM_GETDLGCODE. You should subclass the edit control and do this:
UINT CYourEdit::OnGetDlgCode()
{
return CEdit::OnGetDlgCode() | DLGC_WANTALLKEYS;
}
UPDATE: FYI, also have a look at Just because you're a control doesn't mean that you're necessarily inside a dialog box.
The default dialog processing, as you've discovered, is to close a dialog box when enter is pressed. MFC actually executes the OnOK processing, but you can override that. Here's and old explanation, but, it's still relevant.
Am doing a calculator programme in vc++/MFC dialog application. Thier, i want to change the foreground and background colour of a push button in dialog. I have no idea, how to change.
Please suggests me with relevent code or example if any body have idea.
basu_sagar
There's no easy way to do this in a classical VC/MFC application, button colours are always system-defined. You either have to use a custom control, or create an owner-draw button. Handling WM_CTLCOLOR and returning a different brush doesn't work for buttons.
Edit:
This is an example replacement button control someone has built to solve this problem by encapsulating the owner-draw code into a class.
You can use a CMFCButton. Although you can directly say in your resources file a button is of this type, I do not recommend it, because it adds an unmaintainable hexadecimal piece of text on the rc file. And if you use several rc files, one for each language, it's really devilish!
So lets go. In your form class, declare a member
CMFCButton m_button1;
The DoDataExchange should look like:
void MyDialog::DoDataExchange(CDataExchange* pDX)
{
__super::DoDataExchange(pDX);
DDX_Control(pDX, IDC_BUTTON1, m_button1);
// ...
}
Then the OnInitDialog should be something like:
BOOL CMyDialog::OnInitDialog()
{
if(!__super::OnInitDialog())
return FALSE;
m_button1.SetFaceColor(RGB(0,0,255));
m_button1.SetTextColor(RGB(0,255,0));
m_button1.SetHotTextColor(RGB(255,0,0));
return TRUE;
}
The code I posted will draw a blue button, with green text, and when cursor hovers the button, its text will turn red.