Replacing texts "OK", "Cancel", "Apply" and "Help" in Win32 property sheets - winapi

On a Win32 property sheet the texts "OK", "Cancel", "Apply" and "Help" are automatically displayed in the system's language. That can be a problem if the language of a Software is different of the system's language.
For instance if a customer installs the French version of our software on an English Windows, the property sheet's content will be in French but the standard buttons at the bottom of the property sheet will be in English not matter what.
Does anybody know how can I change these texts.

Actually changing these texts is quite simple. The only thing that must be done is to derive a class from CPropertySheet, override the OnInitDialog method and change the texts in the overridden OnInitDialog.
class CMyPropertySheet : public CPropertySheet
{
public :
CMyPropertySheet() ;
protected:
virtual BOOL OnInitDialog();
DECLARE_MESSAGE_MAP()
} ;
BOOL CMyPropertySheet::OnInitDialog()
{
...
SetDlgItemText(IDOK, whatever..) ;
SetDlgItemText(0x3021, whatever..) ; // 0x3021 == IDAPPLY
SetDlgItemText(IDCANCEL, whatever...) ;
SetDlgItemText(IDHELP, whatever...) ;
}

Related

How do I get notification from a `CEdit` box?

I have a CEdit box where a user can enter relevant information. As soon as he\she starts writing in the box, I need a notification so that I can call doSomething() to perform some other task. Does Windows provide a callback, and if so, how do I use it?
With MFC there's no callback as such, rather you do this by implementing a handler for the appropriate event. You need to handle one of two events: WM_CHAR or EN_CHANGE
Handle the dialog's EN_CHANGE for example duplicating in realtime the entered text elsewhere on the dialog. You need to firstly add an entry in the dialog's message map, and secondly override the appropriate handler:
BEGIN_MESSAGE_MAP(CstackmfcDlg, CDialog)
ON_EN_CHANGE(IDC_EDIT1, &CstackmfcDlg::OnEnChangeEdit1)
END_MESSAGE_MAP()
void CstackmfcDlg::OnEnChangeEdit1()
{
CString text;
m_edit.GetWindowText(text);
m_label.SetWindowText(text); // update a label control to match typed text
}
Or, handle the editbox class's WM_CHAR for example preventing input of certain characters, e.g. ignore anything other than a digit for numerical entry. Derive a class from CEdit, handle the WM_CHAR event of that class (not the dialog) and make your edit control an instance of that class.
BEGIN_MESSAGE_MAP(CCtrlEdit, CEdit)
ON_WM_CHAR()
END_MESSAGE_MAP()
void CCtrlEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// Do nothing if not numeric chars entered, otherwise pass to base CEdit class
if ((nChar >= '0' && nChar <= '9') || VK_BACK == nChar)
CEdit::OnChar(nChar, nRepCnt, nFlags);
}
Note that you can use the VS IDE to put in stubs for the handler overrides by using the Properties bar with the mouse selection in the message map block.
EDIT: Added example code, and corrected explanation of WM_CHAR which I had wrong.
If you double click on the edit box in the resource editor it automatically creates the OnEnChanged event for you.
The following assumes that you have an MFC dialog application.
The class wizard can be started with a right-click:
Double-click the Control ID (has an icon with a small green plus) of the new edit control to add the corresponding member variable to the class.
The class and event wizards will update the class definition and add a CEdit member:
afx_msg void OnEnChangeEdit1(); // Added by event wizard
CEdit m_edit1; // member added by class wizard
The class wizard will update the function:
void CMFCApplication5Dlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_EDIT1, m_edit1); // new variable added with class wizard
}
Double-clicking the control or right-clicking and selecting the add event wizard will update the message map and create the function declaration and definition:
BEGIN_MESSAGE_MAP(CMFCApplication5Dlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_EN_CHANGE(IDC_EDIT1, &CMFCApplication5Dlg::OnEnChangeEdit1) // new event handler added with wizard
END_MESSAGE_MAP()
Finally the code may be updated to interact with the edit control:
void CMFCApplication5Dlg::OnEnChangeEdit1()
{
// TODO: Add your control notification handler code here
CString text;
m_edit1.GetWindowText(text);
//m_edit1.SetWindowText(text);
}

Creating Dialogs with Silverlight Prism

I'm new to creating Silverlight applications. I have inherited a code-base that I've been told is using Prism. Based upon what I've seen in the code-base, this looks to be true. My problem is, I am just trying to open a dialog window and close a dialog window.
To open the dialog window, I'm using the following:
UserControl myDialog = new MyDialog();
IRegion region = myRegionManager.Regions["DIALOG_AREA"];
IRegionManager popupRegionManager = region.Add(myDialog, null, true);
region.Activate(myDialog);
The dialog I have designed appears. It has two buttons: "OK" and "Cancel". When a user clicks on of these dialogs, I want to close the dialog. My problem is, I have no idea how to do this. Because the dialog is not a ChildWindow, I cannot call this.Close(). But, when I change MyDialog to a ChildWindow, it is wrapped in some custom window chrome that i can't figure out how to get rid of.
How do I close a dialog in Prism? Thank you!
Instead of putting in a different region, you should make your ViewModel call a service where you call your dialog window.
public MainPageViewModel(IMainPage view,
ILoginBox loginBox )
: base(view)
{
this.view = view;
this.loginBox = loginBox;
}
public interface ILoginBox
{
void Show();
}
remember to use the IOC container and declare on your ModuleClass:
protected override void RegierTypes()
{
base.Container.RegisterType<ILoginBox , LoginBox>();
}
I hope it helps.
If you are still looking for an example, check:
another Stackoverflow sample

Let my MFC dialog receive keystroke events before its controls (MFC/Win32 equivalent of WinForms "KeyPreview")

I have an MFC dialog containing a dozen or so buttons, radio buttons and readonly edit controls.
I'd like to know when the user hits Ctrl+V in that dialog, regardless of which control has the focus.
If this were C#, I could set the KeyPreview proprety and my form would receive all the keystrokes before the individual controls - but how do I do that in my MFC dialog?
JTeagle is right. You should override PreTranslateMessage().
// Example
BOOL CDlgFoo::PreTranslateMessage( MSG* pMsg )
{
// Add your specialized code here and/or call the base class
if ( pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN )
{
int idCtrl= this->GetFocus()->GetDlgCtrlID();
if ( idCtrl == IDC_MY_EDIT ) {
// do something <--------------------
return TRUE; // eat the message
}
}
return CDialog::PreTranslateMessage( pMsg );
}
Add a handler to override PreTranslateMessage() in the dialog class, and check the details of the MSG struct received there. Be sure to call the base class to get the right return value, unless you want to eat the keystroke to prevent it going further.

Key Preview and Accept Button

Using winforms, I have set the KeyPreview property to true and have event handles for the proper key events within the base form as well.
Within the forms that inherit from it, I set the AcceptButton property based on the requirements of the application.
There are certain cases in which I want the enter key to have functionality different than that of the AcceptButton.
I was hoping to capture the enter key press within my base form and check for the special cases where I do not want the AcceptButton event to fire.
It appears though, that the AcceptButton click is fired before any of the key events within my basef form. I could write functionality into the click events of the possible acceptbuttons, but, in my opinion, that would be a hack.
Any suggestions?
Thanks.
Another way to handle this is to override the form's ProcessDialogKey() method where you can suppress the accept and/or cancel buttons. For example, I have an application with a filter editor that filters a grid based on user input. I want the user to be able to hit the return key when the filter editor control has the focus to apply the filter. The problem is the accept button code runs and closes the form. The code below resolves the issue.
protected override bool ProcessDialogKey(Keys keyData)
{
// Suppress the accept button when the filter editor has the focus.
// This doesn't work in the KeyDown or KeyPress events.
if (((keyData & Keys.Return) == Keys.Return) && (filterEditor.ContainsFocus))
return false;
return base.ProcessDialogKey(keyData);
}
You can take this even further by dropping the following code in a base dialog form. Then you can suppress the accept button for controls in subclasses as necessary.
private readonly List<Control> _disableAcceptButtonList = new List<Control>();
protected override bool ProcessDialogKey(Keys keyData)
{
if (((keyData & Keys.Return) == Keys.Return) && (_disableAcceptButtonList.Count > 0))
{
foreach (Control control in _disableAcceptButtonList)
if (control.ContainsFocus)
return false;
}
return base.ProcessDialogKey(keyData);
}
protected virtual void DisableAcceptButtonForControl(Control control)
{
if (!_disableAcceptButtonList.Contains(control))
_disableAcceptButtonList.Add(control);
}
As our workaround, we captured the enter and leave event for the control that we wanted to have override the acceptbutton functionality. Inside the enter event, we held the current accept button in a private variable and set the acceptbutton to null. On leave, we would reassign the acceptbutton back to the private variable we were holding.
The KeyPreview events could have done something similar to the above. If anyone has a more elegant solution, I would still love to know.
Thanks.

Show Control.Text in VisualStudio Designer

I'm using VisualStudio 2005 and I want to set the text of a control on a form. For various reasons this should not be done in the VisualStudio Designer. I could write the code as follows:
public Form1( )
{
InitializeComponent( );
button1.Text = "Test";
}
But now I don't see the text in the designer, the button is empty (or has the default text of "button1"). Is there a way to set the text of a control outside the designer and see the text in Visual Studio Designer? The text should not be editable, it must only be visible. This would be really nice, because it would be possible to use constants for frequently used phrases and still see them in the designer to adjust the ui.
It's a bit hacky, but you could subclass the control you want and override the Text property:
public class MyTest : Button
{
public override string Text
{
get
{
return #"test";
}
set
{
}
}
}
This shows up in the designer, but when you try and change it Visual Studio just ignores you. You probably want to do something other than just return a hardcoded string literal, but I'm sure you get the idea :-)

Resources