Страница: 1 | 2 |
Вопрос: Субкласнутый TextBox - борьба за точку
Добавлено: 25.02.06 11:23
Автор вопроса: XPEHOMETP
Такое непонятное явление. Нужно мне сделать TextBox, чтобы юзер вводил нужное ему расширение файла. Ну, например, если не устраивает его ".txt", которое идет по умолчанию, чтобы написал свое, например, какое-нибудь ".gy2" или что-то вроде. И хочется мне, чтобы в этом расширении уже стояла точка в самом начале, чтобы потом ее не приставлять. И вот с этим проблемы.
Что я сделал. Прописал субкласснутый TextBox, в который можно вводить любые буквы, цифры, точку, знаки "-" и "_". Сделал так, чтобы точка по второму разу не вводилась. Это все по образцу Euro Calculator (Freeware by Egbert Zijlema), нашел ссылочку на официальном форуме. И все это работает.
Что нагло не работает: не удается сделать так, чтобы точка была на самом первом месте, и чтобы она там ставилась (на этом месте) автоматом, если юзер ее не ввел.
Как я это делал:
В функции FUNCTION SubClassProc, написанной примерно как у Zijlema, я прописал обработку сообщения %WM_CHAR:
CASE %WM_CHAR
SELECT CASE wParam
CASE 8, 48 TO 57, ASC("a") TO ASC("z"), ASC("A") TO ASC("Z"), _
ASC("а") TO ASC("я"), ASC("А") TO ASC("Я")
CONTROL GET TEXT GetParent(hWnd), CtrlID TO sTemp
IF INSTR(sTemp, ".") = 0 THEN
sTemp = "." & sTemp
CONTROL SET TEXT GetParent(hWnd), CtrlID, sTemp
END IF
CASE ASC(".") 'Обработка ввода точки
CONTROL GET TEXT GetParent(hWnd), CtrlID TO sTemp
IF INSTR(sTemp, ".") THEN EXIT FUNCTION
CASE ELSE
EXIT FUNCTION
END SELECT
sTemp - это Local String. По всем правилам программирования, выполнение sTemp = "." & sTemp должно приписать точку к началу строки. А в TextBox у меня эта строка выводится почему-то с точкой в конце. Пробовал собирать это дело во второй строковой переменной: Temp = "." & sTemp, эффект тот же. Что за грабли?
Решил сделать по-другому. Для того, чтобы во введенной строчке была точка, прописал эту точку в качестве начального текста в TextBox. Да, она выводится, только вот курсор (в виде вертикальной черты) стоит ПЕРЕД этой точкой, и если его не подвинуть, весь ввод будет ДО точки. А мне надо ПОСЛЕ.
В общем, как с этим бороться?
Ответы
Всего ответов: 17
Номер ответа: 1
Автор ответа:
HOOLIGAN
Вопросов: 0
Ответов: 1066
Профиль | | #1
Добавлено: 25.02.06 12:16
Поставь точку начальным текстом, курсор можно подвинуть на конец строки
SendMessage (hWnd, EM_SETSEL, 1, 1)
Номер ответа: 2
Автор ответа:
XPEHOMETP
Вопросов: 3
Ответов: 30
Профиль | | #2
Добавлено: 25.02.06 14:41
Извиняюсь, не очень понял: где это прописывать? Я прописал в Callback Function для диалога, в раздел CASE %WM_INITDIALOG. Не сработало. Правда, там надо %EM_SETSEL, а не EM_SETSEL, но это мелочи. В общем, где это надо прописать: где описывается сам диалог, в Callback или в функцию SubClassProc?
Номер ответа: 3
Автор ответа:
HOOLIGAN
Вопросов: 0
Ответов: 1066
Профиль | | #3
Добавлено: 25.02.06 15:16
В том месте, где пользователю предлагается ввести расширение файла в текстовое поле. Но не в callback'е. И убери из callback'а все манипуляции с точкой.
Например, если ты делаешь прогу, которая ищет файлы по расширению, то один раз при инициализации диалога делаешь так:
SetWindowText(hEdit, Byval "."
SendMessage (hEdit, EM_SETSEL, 1, 1)
End Function
Function PbMain()
'после создания текстбокса
'вызывай ф-цию SetPoint, передавая ей hwnd текстбокса
End Function
callback function DlgProc
'в главной callback-процедуре приложения
'после вызова ф-ции поиска файлов с текущим расширением
'устанавливай свою дефолтную точку
FindFiles() 'гипотетическая ф-ция поиска
SetPoint(Byval hWndEdit)
End function
Точнее место сможешь определить только ты сам, ибо текст программы только у тебя
Номер ответа: 4
Автор ответа:
XPEHOMETP
Вопросов: 3
Ответов: 30
Профиль | | #4
Добавлено: 26.02.06 09:25
НЕ ПОЛУЧИЛОСЬ! Читал в MSDN, нашел, что для Textbox показывать курсор слева от начального текста - нормальное явление. Побороть не удалось. Надоело возиться, запретил ввод точки вообще, приписываю ее после чтения содержимого Textbox. Работает. И на том спасибо.
Номер ответа: 5
Автор ответа:
HOOLIGAN
Вопросов: 0
Ответов: 1066
Профиль | | #5
Добавлено: 26.02.06 10:50
А если файл с двойным расширением? типа .exe.bak или .exe.manifest ? Что тогда?
Неужели так сложно сразу же после установления точки вызвать SendMeesage
Номер ответа: 6
Автор ответа:
XPEHOMETP
Вопросов: 3
Ответов: 30
Профиль | | #6
Добавлено: 26.02.06 13:05
Да вызывал я SendMeesage, сразу после описания Textbox и до показа всей формы. Не помогло! Надоело мне с этим возиться. Мне еще надо DLL на фортране написать (точнее, модифицировать имеющуюся прогу), пристегнуть ее, потом приделать компонент для рисования графика (хочу готовый ActiveX взять, чтобы самому не возиться), и добиться, чтобы это все работало. Когда заработает, тогда, может быть, займусь причесыванием того, что сразу не получилось.
Номер ответа: 7
Автор ответа:
HOOLIGAN
Вопросов: 0
Ответов: 1066
Профиль | | #7
Добавлено: 26.02.06 13:13
Можно в callback процедуре текстбокса по сообщению WM_SETFOCUS, вставить sendmessage.
Номер ответа: 8
Автор ответа:
XPEHOMETP
Вопросов: 3
Ответов: 30
Профиль | | #8
Добавлено: 26.02.06 16:48
CASE %WM_COMMAND
SELECT CASE CBCTL
CASE %IDC_TEXTBOX1
IF CBCTLMSG = %WM_SETFOCUS THEN
SendMessage (%IDC_TEXTBOX1, EM_SETSEL, 1, 1)
END IF
.........
Не сработало! Все! Хватит! Надоело!
Номер ответа: 9
Автор ответа:
HOOLIGAN
Вопросов: 0
Ответов: 1066
Профиль | | #9
Добавлено: 26.02.06 17:38
А зачем так кричать
WM_SETFOCUS не приходит в case WM_COMMAND. И не является подпараметром WM_COMMAND.
Вставил обработку WM_SETFOCUS куда попало, и ждешь, что сработает
Номер ответа: 10
Автор ответа:
XPEHOMETP
Вопросов: 3
Ответов: 30
Профиль | | #10
Добавлено: 26.02.06 22:13
А куда его тогда вставлять? Во внешний SELECT CASE, на одном уровне с WM_COMMAND?
Номер ответа: 11
Автор ответа:
HOOLIGAN
Вопросов: 0
Ответов: 1066
Профиль | | #11
Добавлено: 26.02.06 22:46
Ты ведь делал новый callback для textBox'а (сабклассинг) ?
Вот в этой процедуре сабклассинга во внешний select case, как раз в одном уровне с WM_COMMAND.
И не по CBCTLMSG его получать, а по CBMSG.
Блин, неохота распаковывать этот пб , напишу по памяти, если что подправишь:
SELECT CBMSG
CASE WM_COMMAND
'тут обработка WM_COMMAND
CASE WM_CHAR
'тут фильтрация вводимых символов
CASE WM_SETFOCUS
'вот тут нужно переместить курсор
SendMessage (CBHNDL, %EM_SETSEL, 1, 1)
FUNCTION = 0
EXIT FUNCTION
CASE ELSE
FUNCTION = CallWindowProc(oldEditProc, CBHNDL, CBMSG, CBWPARAM, CBLPARAM)
END SELECT
END FUNCTION
Номер ответа: 12
Автор ответа:
XPEHOMETP
Вопросов: 3
Ответов: 30
Профиль | | #12
Добавлено: 27.02.06 18:14
Спасибо за разъяснения! Сегодня ничего сделать не смог: комп не грузился, сообщения о том, что не найден файл реестра... Появились 21 бэд почти в начале диска, еще пара чуть подальше. Весь день угробил на реанимацию. Похоже, винту скоро крышка...
Номер ответа: 13
Автор ответа:
XPEHOMETP
Вопросов: 3
Ответов: 30
Профиль | | #13
Добавлено: 27.02.06 22:29
Дома попробовал. Не работает! Результат приема Текстбоксом сообщения: квадратик перед точкой и курсор перед ними. То есть и прежние варианты это давали, я просто думал, что не там прописал. Я тут в MSDN порылся, есть такая функция SendInput, с ее помощью можно сэмулировать ввод точки, и курсор должен остаться справа (так как точка якобы введена с клавы). Попробую прикрутить.
Номер ответа: 14
Автор ответа:
HOOLIGAN
Вопросов: 0
Ответов: 1066
Профиль | | #14
Добавлено: 27.02.06 23:01
Вот здесь лежит файл:
http://webfile.ru/833564
скачай и посмотри.
При установке фокуса на текстбокс (как мышью, так и по клавише Таб), в текстбоксе устанавливается точка и курсор перемещается на позицию 1 (сразу за точкой).
Номер ответа: 15
Автор ответа:
XPEHOMETP
Вопросов: 3
Ответов: 30
Профиль | | #15
Добавлено: 28.02.06 13:15
Скачал, посмотрел. Действительно, устанавливается! Может, у меня не работало, потому что я СРАЗУ фокус на текстбокс прописал? Надо попробовать!