Infocatcher, значит ликбез

1. SetWindowStyle - такой функции в библиотеке user32.dll нету. Стиль это просто значение типа LONG_PTR хранящееся в ассоциированной с окном внутренней структуре ОС. Доступ к этому значению(а также ко многим другим) осуществляется с помощью системных вызовов:
Code: Select all
LONG GetWindowLong(HWND hwnd, int index)
LONG SetWindowLong(HWND hwnd, int index, LONG value)
//+ A/W суффикс
или точнее сказать:
Code: Select all
LONG_PTR GetWindowLongPtr(HWND hwnd, int index)
LONG_PTR SetWindowLongPtr(HWND hwnd, int index, LONG_PTR value)
// + A/W суффикс
- 32/64, битная версия(без Ptr - считается устаревшей и существует для поддержки 16-битных приложений. 64-ый Platform SDK компилятор материт старый вариант функции).
Нас интересует index = GWL_STYLE
2. ВАЖНО: Установка этого значения - это только установка этого значения. Никто не гарантирует что все окна будут принимать к сведению стиль(или значения других индексов) немедленно, и будут ли вообще туда смотреть. Т.е. эти значения в большинстве случаев(не во всех) индикаторы.
Потому действует негласное правило: если окну(контролу, диалогу, рамке, любому) нужно поменять стиль, это должен сделать тот, кто гарантирует что окно будет отображаться(и вообще реагировать на окружающую среду) в соответствии с этим стилем, т.е это должна сделать оконная процедура. А какой единственный способ заставить оконную процедуру сделать что-то? Правильно, отправить окну сообщение.
3. Читаем RTFM по контролу, в поисках сообщения хоть как-то связанного с нашей темой. Находим единственную пару EM_GET/SETPASSWORDCHAR. EM_SETPASSWORDCHAR принимает код символа, которые скрывает текст. Если код == 0, текст не скрывается, при этом стиль ES_PASSWORD снимается, иначе символы скрываются указанным символом, и выставляется стиль ES_PASSWORD. Какраз то что искали.
Итого получаем код:
Code: Select all
var showPass = AkelPad.SendMessage(hWndShowPass, 240 /*BM_GETCHECK*/, 0, 0);
AkelPad.SendMessage(hWndPass, 0x00CC/*EM_SETPASSWORDCHAR*/, (showPass)?0:0x002A/* asterisk in both ANSI and UCS2*/, 0);
oSys.Call("user32::InvalidateRect", hWndPass, 0, 1/*TRUE*/);