Setting password style to a wxTextCtrl at runtime (solution)

If you have a cool piece of software to share, but you are not hosting it officially yet, please dump it in here. If you have code snippets that are useful, please donate!
Post Reply
sampah03
In need of some credit
In need of some credit
Posts: 3
Joined: Wed Jun 13, 2007 7:05 pm

Setting password style to a wxTextCtrl at runtime (solution)

Post by sampah03 » Wed Jul 18, 2007 2:46 pm

I searched for the method of setting password style to a wxTextCtrl at runtime, and the answer is impossible, as the manual says:
wxTE_READONLY, wxTE_PASSWORD and wrapping styles can be dynamically changed under wxGTK but not wxMSW.
I know that it can be done at runtime (I did it when I was using VB and Euphoria), so I tried this code and it works. Unfortunately it is for Windows only.

Code: Select all

void setPassword(wxWindow* win, int active) {
	HWND hwnd = (HWND) win->GetHandle();
	SendMessage(hwnd, EM_SETPASSWORDCHAR, active? 0x25cf: 0, 0); // 0x25cf is ● character
	win->Refresh();
}

So I'm posting this code in case any of you need it. I am also hoping that this will be integrated at future versions.

priyank_bolia
wxWorld Domination!
wxWorld Domination!
Posts: 1339
Joined: Wed Aug 03, 2005 8:10 am
Location: BANGALORE, INDIA
Contact:

Post by priyank_bolia » Thu Jul 19, 2007 6:48 am

Cool I was also looking for this.

posta10100
Earned some good credits
Earned some good credits
Posts: 106
Joined: Tue Jan 09, 2007 2:27 pm
Location: Italy

Post by posta10100 » Thu Jul 19, 2007 10:22 am

You can do that:

Code: Select all

void setPassword(wxWindow* win, int active) {
#ifdef __WXMSW__
        HWND hwnd = (HWND) win->GetHandle();
        SendMessage(hwnd, EM_SETPASSWORDCHAR, active? 0x25cf: 0, 0); // 0x25cf is ● character
        win->Refresh();
#else
        win->SetWindowStyle(wxTE_PASSWORD);
#endif
} 
I don't try it but I think that it can works!

mc2r
wxWorld Domination!
wxWorld Domination!
Posts: 1195
Joined: Thu Feb 22, 2007 4:47 pm
Location: Denver, Co
Contact:

Post by mc2r » Thu Jul 19, 2007 2:58 pm

The win-Refresh() should be moved after the #endif as win will need to be refreshed regardless of the method used to change it's style.

and finaly this is maybe better done as a patch wxWindow::SetWindowStyle(), as you code shows that wxTE_PASSWORD is a style that can be changed after creation on __WXMSW__.

Code: Select all

void setPassword(wxWindow* win, int active) {
#ifdef __WXMSW__
        HWND hwnd = (HWND) win->GetHandle();
        SendMessage(hwnd, EM_SETPASSWORDCHAR, active? 0x25cf: 0, 0); // 0x25cf is ● character

#else
        win->SetWindowStyle(wxTE_PASSWORD);
#endif
        win->Refresh();
} 
-Max

Troels
Experienced Solver
Experienced Solver
Posts: 79
Joined: Fri Jan 07, 2005 12:02 pm
Location: Denmark

Post by Troels » Sun Feb 10, 2008 10:54 am

posta10100 wrote:

Code: Select all

win->SetWindowStyle(wxTE_PASSWORD);
You are not only setting the the password flag, you are clearing out all other flags in the process.
Try this

Code: Select all

inline void wxModifyStyle(wxWindow* wnd, long remove, long add)
{
   long dw = wnd->GetWindowStyleFlag();
   dw&=~remove;
   dw|=add;
   wnd->SetWindowStyleFlag(dw);
}
...
wxModifyStyle(win, 0, wxTE_PASSWORD);

Troels
Experienced Solver
Experienced Solver
Posts: 79
Joined: Fri Jan 07, 2005 12:02 pm
Location: Denmark

Post by Troels » Sun Feb 10, 2008 12:49 pm

It turns out that restoring the bullet after once removing it (with 0) is impossible, in Ansi mode builds on WinXP.
SendMessage(EM_SETPASSWORDCHAR) and even SendMessageW(EM_SETPASSWORDCHAR) cannot understand 0x25CF. You just have to settle for '*' in non-Unicode builds.
This is tested on WinXP(ansi+unicode),Win95(ansi),Vista(unicode) and GTK2:

Code: Select all

void wxTextCtrl_SetPasswordFlag(wxTextCtrl* win, bool active)
{
#ifdef __WXMSW__
   HWND hwnd = (HWND)win->GetHandle();
#if wxUSE_UNICODE
   static wchar_t password_char = 0x25CF;
   static bool initialized = false;
   if (win->HasFlag(wxTE_PASSWORD) && !initialized)
   {
      password_char = (wchar_t)SendMessage(hwnd, EM_GETPASSWORDCHAR, 0, 0);
      initialized = true;
   }
#else
   const char password_char = '*';
#endif
   SendMessage(hwnd, EM_SETPASSWORDCHAR, active ? password_char : 0, 0);
#endif
   wxModifyStyle(win, active ? 0 : wxTE_PASSWORD, active ? wxTE_PASSWORD : 0);
   win->Refresh();
}

Post Reply