Перейти к содержанию
  • Регистрация

Вадим Смоленский

Пользователи
  • Публикаций

    194
  • Зарегистрирован

  • Посещение

  • Победитель дней

    5

Вадим Смоленский стал победителем дня 3 декабря 2018

Вадим Смоленский имел наиболее популярный контент!

Информация о Вадим Смоленский

  • Звание
    Продвинутый пользователь

Посетители профиля

Блок последних пользователей отключён и не показывается другим пользователям.

  1. Да, я это видел, конечно. Но очень плохо растолковано. Какое из этих значений соответствует монохромному изображению? L, может быть? И как именно этот формат выставлять? У TBitmap это свойство Read-only.
  2. Имею в своем проекте огромный невидимый TImage, из которого при необходимости вырезаются те или иные кусочки и показываются пользователям. Так оказалось сделать удобнее, чем хранить эти кусочки в БД. Изображение монохромное, из черных и белых пикселей, цвета не нужны. Я полагал, что достаточно загрузить в TImage.MultiResBitmap монохромный файл, чтобы битмэп и трактовался программой как монохромный. Но сейчас проверил это функцией PixelFormatToString - и увидел, что пиксельный формат имеет значение BGRA. Похоже, под цвета по-прежнему выделяются ресурсы, которые можно было бы сэкономить. Возникают следующие вопросы: 1. Действительно ли PixelFormat=BGRA означает, что мой TBitmap не является монохромным и занимает в памяти в разы больше места? 2. Если да, то есть ли способ сделать его монохромным?
  3. Узнал, что в UWP API включены средства для получения уникального идентификатора компьютера. Это юнит Windows.System.Profile, класс HardwareIdentification, метод getPackageSpecificToken. Существуют ли способы обратиться к этим средствам из Delphi? Вообще, я привык считать, что такая идентификация компьютера в принципе невозможна, в отличие от мобильных устройств. Но прогресс, как известно, не остановить.
  4. Немножко улучшил свой вариант. Теперь вообще как часы всё заработало. var TheFormIsMinimized: Boolean = False; TheFormWasMaximized: Boolean = False; function NewWndProc(Wnd: HWND; Msg: UINT; WParam: WPARAM; LParam: LPARAM): LRESULT; stdcall; begin if (Msg = WM_SHOWWINDOW) and (LParam = SW_PARENTCLOSING) and (not TheFormIsMinimized) then begin TheFormIsMinimized := True; TheFormWasMaximized := (MainForm.WindowState=TWindowState.wsMaximized); SendMessage(FormToHWND(MainForm), WM_SYSCOMMAND, SC_MINIMIZE, 0); MainFormp.WindowState := TWindowState.wsMinimized; end else if (Msg = WM_SHOWWINDOW) and (LParam = SW_PARENTOPENING) and (TheFormIsMinimized) then begin TheFormIsMinimized := False; SendMessage(FormToHWND(MainForm), WM_SYSCOMMAND, SC_RESTORE, 0); if TheFormWasMaximized then MainForm.WindowState := TWindowState.wsMaximized else MainForm.WindowState := TWindowState.wsNormal; end else Result:=CallWindowProc(OldWndProc, Wnd, Msg, WParam, LParam); end; Единственный недостаток: при восстановлении из wsMinimized в wsMaximized на долю секунды окно фиксируется как wsNormal. Но это, в общем-то, не страшно.
  5. Да, я сейчас тоже попробовал сделать через перехват, только попроще. Работает. Вот как выглядит функция: function NewWndProc(Wnd: HWND; Msg: UINT; WParam: WPARAM; LParam: LPARAM): LRESULT; stdcall; begin if (Msg = WM_SHOWWINDOW) and (LParam = SW_PARENTCLOSING) then begin SendMessage(FormToHWND(MainForm), WM_SYSCOMMAND, SC_MINIMIZE, 0); Application.ProcessMessages; MainForm.WindowState := TWindowState.wsMinimized; end else Result := CallWindowProc(OldWndProc, Wnd, Msg, WParam, LParam); end; ProcessMessages пришлось вставить из-за того, что без этого приложение перед сворачиванием на долю секунды становилось черным. Наверное, можно сделать изящнее - в вашем примере, как я понял, TThread помогает. Но все-таки оно работает, и это, безусловно, изящнее, чем курочить FMX.Platform.Win и таскать его туда-сюда.
  6. Воспроизвел изменения у себя - и увы! Не только сворачивание не стало работать правильно, но даже перетащить окно теперь не получается. Что-то с этим кодом всё равно не так... Кстати, попробовал перехватить событие WM_SYSCOMMAND и обнаружил, что оно происходит только при щелчке по кнопке Minimize в шапке окна, а при щелчке по иконке в трее уже не происходит. Не то мы ловим.
  7. Да! С таким булевым заграждением всё получилось! Видимо, у вас просто компьютер помощнее, процедура отрабатывает быстрее, чем вызывается по второму разу. Очень и очень признателен. Желаю всяческих благ - и отдельно успехов дочери на поприще японистики!
  8. И что - прямо заводите японский текст, и выскакивает candidate window, и располагается на точке (100,100)?
  9. Вынес всё, касающееся этой проблемы, в отдельный проект. У меня продолжает падать и в таком виде. Не поленитесь проверить, упадет ли у вас. Файл FMX.Platform.Win.pas я в свое время чуть изменил из-за каких-то проблем (сходу и не вспомню, каких), и с тех пор держу его в одной папке с проектом. Может, с ним что не так? ImeProject.zip
  10. LookUp - это название моей формы, которое я забыл поменять на MyForm. Но можно и без него, конечно. Однако же, у меня и в таком виде всё равно валится. Что еще тут стоит проверить?..
  11. Да, действительно. Теперь управление в нужные моменты передается WMIMENotify. Спасибо еще раз. Однако, к сожалению, это пока не помогло мне решить исходной проблемы. Не знаю, уместно ли будет изложить эту проблему здесь - все-таки она связана с процедурами IME для ввода японского текста; с этим мало кто сталкивается. И тем не менее: когда включена японская локаль и выбран ввод хираганой (слоговой азбукой), то при печатании в TEdit на экран автоматически выдается маленькое окошко (candidate window) со списком иероглифов или слов, которые могли бы соответствовать набранному чтению. Пользователь может выбрать одного из этих кандидатов. Проблема в том, что когда включено экранное масштабирование (скажем, 125%), candidate window выскакивает не строго под TEdit, как должно, а левее и выше. Похоже, это недоработка FireMonkey - при передаче координат курсора ввода масштабирование не учитывается. Я хотел наладить перехват выдачи candidate window с присвоением ему других координат. Сам перехват теперь получается (при вызове candidate window выдается сообщение WM_IME_NOTIFY с WParam=IMN_SETCANDIDATEPOS). А вот так выглядит у меня обработка этого перехвата в рекомендованной вами процедуре: uses imm; procedure TMyForm.WMIMENotify(var Msg: TMessage); var Imc: HIMC; ImeCandidateFormProperties: TCandidateForm; begin Imc:=ImmGetContext(FMXHandleToHWND(LookUp.Handle)); ImmGetCandidateWindow(Imc,0,@ImeCandidateFormProperties); ImeCandidateFormProperties.dwStyle:=CFS_CANDIDATEPOS; ImeCandidateFormProperties.ptCurrentPos.X:=100; ImeCandidateFormProperties.ptCurrentPos.Y:=100; ImmSetCandidateWindow(Imc,@ImeCandidateFormProperties); ImmReleaseContext(FMXHandleToHWND(LookUp.Handle),Imc); end; Сколь могу судить, ImmGetCandidateWindow успешно считывает данные о candidate window. Но заменить их на исправленные уже не выходит, при вызове ImmSetCandidateWindow происходит переполнение стека. Документация о ImmSetCandidateWindow лежит здесь. Опять же: трудно надеяться, что вы сможете помочь - но вдруг?
  12. Да вот, kami говорит, что в FireMonkey всё по-другому...
  13. Попробовал повторить у себя. Получилось странно. Во время запуска приложения управление множество раз переходит в NewWndProc, в том числе и дважды с сообщением WM_IME_NOTIFY. Но как только главное окно появилось на экране - больше ни разу, ни с какими сообщениями вообще. Что-то где-то недокручено, такое впечатление...
  14. Можно считать, что в рамках окна. Спасибо, Некрасов-сан. Выглядит интригующе. Но я не могу понять, как управление перейдет в процедуру WMIMENotify. Она ведь у вас вообще нигде не вызывается. P.S. А, понял. Она вызывается в FMX.Platform.Win: WM_IME_NOTIFY: begin Result := WMImeNotify(LForm, hwnd, uMsg, wParam, lParam); end;
  15. Для задач, связанных с вводом японского текста, мне нужно научиться перехватывать системное сообщение WM_IME_NOTIFY. Насколько могу судить, в FireMonkey эти вещи делаются (если вообще делаются) принципиально иначе, нежели в VCL. Конкретного ничего не нагуглил. Не поможет ли кто?
×
×
  • Создать...